fieldStreams.hpp 7.4 KB
Newer Older
1
/*
2
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_OOPS_FIELDSTREAMS_HPP
#define SHARE_VM_OOPS_FIELDSTREAMS_HPP

#include "oops/instanceKlass.hpp"
#include "oops/fieldInfo.hpp"

// The is the base class for iteration over the fields array
// describing the declared fields in the class.  Several subclasses
// are provided depending on the kind of iteration required.  The
// JavaFieldStream is for iterating over regular Java fields and it
// generally the preferred iterator.  InternalFieldStream only
// iterates over fields that have been injected by the JVM.
// AllFieldStream exposes all fields and should only be used in rare
// cases.
class FieldStreamBase : public StackObj {
 protected:
41
  Array<u2>*          _fields;
42 43 44
  constantPoolHandle  _constants;
  int                 _index;
  int                 _limit;
45
  int                 _generic_signature_slot;
46

47
  FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); }
48

49 50 51 52 53 54 55 56 57
  int init_generic_signature_start_slot() {
    int length = _fields->length();
    int num_fields = 0;
    int skipped_generic_signature_slots = 0;
    FieldInfo* fi;
    AccessFlags flags;
    /* Scan from 0 to the current _index. Count the number of generic
       signature slots for field[0] to field[_index - 1]. */
    for (int i = 0; i < _index; i++) {
58
      fi = FieldInfo::from_field_array(_fields, i);
59 60 61 62 63 64 65 66
      flags.set_flags(fi->access_flags());
      if (flags.field_has_generic_signature()) {
        length --;
        skipped_generic_signature_slots ++;
      }
    }
    /* Scan from the current _index. */
    for (int i = _index; i*FieldInfo::field_slots < length; i++) {
67
      fi = FieldInfo::from_field_array(_fields, i);
68 69 70 71 72 73 74 75 76 77 78
      flags.set_flags(fi->access_flags());
      if (flags.field_has_generic_signature()) {
        length --;
      }
      num_fields ++;
    }
    _generic_signature_slot = length + skipped_generic_signature_slots;
    assert(_generic_signature_slot <= _fields->length(), "");
    return num_fields;
  }

79
  FieldStreamBase(Array<u2>* fields, constantPoolHandle constants, int start, int limit) {
80 81 82
    _fields = fields;
    _constants = constants;
    _index = start;
83 84 85 86 87 88
    int num_fields = init_generic_signature_start_slot();
    if (limit < start) {
      _limit = num_fields;
    } else {
      _limit = limit;
    }
89 90
  }

91
  FieldStreamBase(Array<u2>* fields, constantPoolHandle constants) {
92 93 94
    _fields = fields;
    _constants = constants;
    _index = 0;
95
    _limit = init_generic_signature_start_slot();
96 97 98
  }

 public:
99
  FieldStreamBase(InstanceKlass* klass) {
100 101 102 103
    _fields = klass->fields();
    _constants = klass->constants();
    _index = 0;
    _limit = klass->java_fields_count();
104
    init_generic_signature_start_slot();
105 106 107 108 109 110
  }
  FieldStreamBase(instanceKlassHandle klass) {
    _fields = klass->fields();
    _constants = klass->constants();
    _index = 0;
    _limit = klass->java_fields_count();
111
    init_generic_signature_start_slot();
112 113 114 115 116
  }

  // accessors
  int index() const                 { return _index; }

117 118 119 120 121 122 123
  void next() {
    if (access_flags().field_has_generic_signature()) {
      _generic_signature_slot ++;
      assert(_generic_signature_slot <= _fields->length(), "");
    }
    _index += 1;
  }
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
  bool done() const { return _index >= _limit; }

  // Accessors for current field
  AccessFlags access_flags() const {
    AccessFlags flags;
    flags.set_flags(field()->access_flags());
    return flags;
  }

  void set_access_flags(u2 flags) const {
    field()->set_access_flags(flags);
  }

  void set_access_flags(AccessFlags flags) const {
    set_access_flags(flags.as_short());
  }

  Symbol* name() const {
    return field()->name(_constants);
  }

  Symbol* signature() const {
    return field()->signature(_constants);
  }

  Symbol* generic_signature() const {
150 151
    if (access_flags().field_has_generic_signature()) {
      assert(_generic_signature_slot < _fields->length(), "out of bounds");
152
      int index = _fields->at(_generic_signature_slot);
153 154 155 156
      return _constants->symbol_at(index);
    } else {
      return NULL;
    }
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
  }

  int offset() const {
    return field()->offset();
  }

  void set_offset(int offset) {
    field()->set_offset(offset);
  }
};

// Iterate over only the internal fields
class JavaFieldStream : public FieldStreamBase {
 public:
  JavaFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), 0, k->java_fields_count()) {}

  int name_index() const {
    assert(!field()->is_internal(), "regular only");
    return field()->name_index();
  }
  void set_name_index(int index) {
    assert(!field()->is_internal(), "regular only");
    field()->set_name_index(index);
  }
  int signature_index() const {
    assert(!field()->is_internal(), "regular only");
    return field()->signature_index();
  }
  void set_signature_index(int index) {
    assert(!field()->is_internal(), "regular only");
    field()->set_signature_index(index);
  }
  int generic_signature_index() const {
    assert(!field()->is_internal(), "regular only");
191 192
    if (access_flags().field_has_generic_signature()) {
      assert(_generic_signature_slot < _fields->length(), "out of bounds");
193
      return _fields->at(_generic_signature_slot);
194 195 196
    } else {
      return 0;
    }
197 198 199
  }
  void set_generic_signature_index(int index) {
    assert(!field()->is_internal(), "regular only");
200 201
    if (access_flags().field_has_generic_signature()) {
      assert(_generic_signature_slot < _fields->length(), "out of bounds");
202
      _fields->at_put(_generic_signature_slot, index);
203
    }
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
  }
  int initval_index() const {
    assert(!field()->is_internal(), "regular only");
    return field()->initval_index();
  }
  void set_initval_index(int index) {
    assert(!field()->is_internal(), "regular only");
    return field()->set_initval_index(index);
  }
};


// Iterate over only the internal fields
class InternalFieldStream : public FieldStreamBase {
 public:
219
  InternalFieldStream(InstanceKlass* k):      FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
220
  InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
221 222 223 224 225
};


class AllFieldStream : public FieldStreamBase {
 public:
226 227
  AllFieldStream(Array<u2>* fields, constantPoolHandle constants): FieldStreamBase(fields, constants) {}
  AllFieldStream(InstanceKlass* k):      FieldStreamBase(k->fields(), k->constants()) {}
228 229 230 231
  AllFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants()) {}
};

#endif // SHARE_VM_OOPS_FIELDSTREAMS_HPP