fieldStreams.hpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_VM_OOPS_FIELDSTREAMS_HPP
26#define SHARE_VM_OOPS_FIELDSTREAMS_HPP
27
28#include "oops/instanceKlass.hpp"
29#include "oops/fieldInfo.hpp"
30
31// The is the base class for iteration over the fields array
32// describing the declared fields in the class.  Several subclasses
33// are provided depending on the kind of iteration required.  The
34// JavaFieldStream is for iterating over regular Java fields and it
35// generally the preferred iterator.  InternalFieldStream only
36// iterates over fields that have been injected by the JVM.
37// AllFieldStream exposes all fields and should only be used in rare
38// cases.
39class FieldStreamBase : public StackObj {
40 protected:
41  Array<u2>*          _fields;
42  constantPoolHandle  _constants;
43  int                 _index;
44  int                 _limit;
45  int                 _generic_signature_slot;
46
47  FieldInfo* field() const { return FieldInfo::from_field_array(_fields, _index); }
48
49  int init_generic_signature_start_slot() {
50    int length = _fields->length();
51    int num_fields = 0;
52    int skipped_generic_signature_slots = 0;
53    FieldInfo* fi;
54    AccessFlags flags;
55    /* Scan from 0 to the current _index. Count the number of generic
56       signature slots for field[0] to field[_index - 1]. */
57    for (int i = 0; i < _index; i++) {
58      fi = FieldInfo::from_field_array(_fields, i);
59      flags.set_flags(fi->access_flags());
60      if (flags.field_has_generic_signature()) {
61        length --;
62        skipped_generic_signature_slots ++;
63      }
64    }
65    /* Scan from the current _index. */
66    for (int i = _index; i*FieldInfo::field_slots < length; i++) {
67      fi = FieldInfo::from_field_array(_fields, i);
68      flags.set_flags(fi->access_flags());
69      if (flags.field_has_generic_signature()) {
70        length --;
71      }
72      num_fields ++;
73    }
74    _generic_signature_slot = length + skipped_generic_signature_slots;
75    assert(_generic_signature_slot <= _fields->length(), "");
76    return num_fields;
77  }
78
79  FieldStreamBase(Array<u2>* fields, constantPoolHandle constants, int start, int limit) {
80    _fields = fields;
81    _constants = constants;
82    _index = start;
83    int num_fields = init_generic_signature_start_slot();
84    if (limit < start) {
85      _limit = num_fields;
86    } else {
87      _limit = limit;
88    }
89  }
90
91  FieldStreamBase(Array<u2>* fields, constantPoolHandle constants) {
92    _fields = fields;
93    _constants = constants;
94    _index = 0;
95    _limit = init_generic_signature_start_slot();
96  }
97
98 public:
99  FieldStreamBase(InstanceKlass* klass) {
100    _fields = klass->fields();
101    _constants = klass->constants();
102    _index = 0;
103    _limit = klass->java_fields_count();
104    init_generic_signature_start_slot();
105  }
106  FieldStreamBase(instanceKlassHandle klass) {
107    _fields = klass->fields();
108    _constants = klass->constants();
109    _index = 0;
110    _limit = klass->java_fields_count();
111    init_generic_signature_start_slot();
112  }
113
114  // accessors
115  int index() const                 { return _index; }
116
117  void next() {
118    if (access_flags().field_has_generic_signature()) {
119      _generic_signature_slot ++;
120      assert(_generic_signature_slot <= _fields->length(), "");
121    }
122    _index += 1;
123  }
124  bool done() const { return _index >= _limit; }
125
126  // Accessors for current field
127  AccessFlags access_flags() const {
128    AccessFlags flags;
129    flags.set_flags(field()->access_flags());
130    return flags;
131  }
132
133  void set_access_flags(u2 flags) const {
134    field()->set_access_flags(flags);
135  }
136
137  void set_access_flags(AccessFlags flags) const {
138    set_access_flags(flags.as_short());
139  }
140
141  Symbol* name() const {
142    return field()->name(_constants);
143  }
144
145  Symbol* signature() const {
146    return field()->signature(_constants);
147  }
148
149  Symbol* generic_signature() const {
150    if (access_flags().field_has_generic_signature()) {
151      assert(_generic_signature_slot < _fields->length(), "out of bounds");
152      int index = _fields->at(_generic_signature_slot);
153      return _constants->symbol_at(index);
154    } else {
155      return NULL;
156    }
157  }
158
159  int offset() const {
160    return field()->offset();
161  }
162
163  void set_offset(int offset) {
164    field()->set_offset(offset);
165  }
166};
167
168// Iterate over only the internal fields
169class JavaFieldStream : public FieldStreamBase {
170 public:
171  JavaFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), 0, k->java_fields_count()) {}
172
173  int name_index() const {
174    assert(!field()->is_internal(), "regular only");
175    return field()->name_index();
176  }
177  void set_name_index(int index) {
178    assert(!field()->is_internal(), "regular only");
179    field()->set_name_index(index);
180  }
181  int signature_index() const {
182    assert(!field()->is_internal(), "regular only");
183    return field()->signature_index();
184  }
185  void set_signature_index(int index) {
186    assert(!field()->is_internal(), "regular only");
187    field()->set_signature_index(index);
188  }
189  int generic_signature_index() const {
190    assert(!field()->is_internal(), "regular only");
191    if (access_flags().field_has_generic_signature()) {
192      assert(_generic_signature_slot < _fields->length(), "out of bounds");
193      return _fields->at(_generic_signature_slot);
194    } else {
195      return 0;
196    }
197  }
198  void set_generic_signature_index(int index) {
199    assert(!field()->is_internal(), "regular only");
200    if (access_flags().field_has_generic_signature()) {
201      assert(_generic_signature_slot < _fields->length(), "out of bounds");
202      _fields->at_put(_generic_signature_slot, index);
203    }
204  }
205  int initval_index() const {
206    assert(!field()->is_internal(), "regular only");
207    return field()->initval_index();
208  }
209  void set_initval_index(int index) {
210    assert(!field()->is_internal(), "regular only");
211    return field()->set_initval_index(index);
212  }
213};
214
215
216// Iterate over only the internal fields
217class InternalFieldStream : public FieldStreamBase {
218 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
224class AllFieldStream : public FieldStreamBase {
225 public:
226  AllFieldStream(Array<u2>* fields, constantPoolHandle constants): FieldStreamBase(fields, constants) {}
227  AllFieldStream(InstanceKlass* k):      FieldStreamBase(k->fields(), k->constants()) {}
228  AllFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants()) {}
229};
230
231#endif // SHARE_VM_OOPS_FIELDSTREAMS_HPP
232