src/share/vm/runtime/reflectionUtils.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
equal deleted inserted replaced
-1:000000000000 0:f90c822e73f8
1 /*
2 * Copyright (c) 1999, 2013, 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_RUNTIME_REFLECTIONUTILS_HPP
26 #define SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP
27
28 #include "memory/allocation.hpp"
29 #include "oops/instanceKlass.hpp"
30 #include "oops/objArrayOop.hpp"
31 #include "oops/oopsHierarchy.hpp"
32 #include "runtime/handles.inline.hpp"
33 #include "runtime/reflection.hpp"
34 #include "utilities/accessFlags.hpp"
35 #include "utilities/globalDefinitions.hpp"
36
37 // A KlassStream is an abstract stream for streaming over self, superclasses
38 // and (super)interfaces. Streaming is done in reverse order (subclasses first,
39 // interfaces last).
40 //
41 // for (KlassStream st(k, false, false, false); !st.eos(); st.next()) {
42 // Klass* k = st.klass();
43 // ...
44 // }
45
46 class KlassStream VALUE_OBJ_CLASS_SPEC {
47 protected:
48 instanceKlassHandle _klass; // current klass/interface iterated over
49 instanceKlassHandle _base_klass; // initial klass/interface to iterate over
50 Array<Klass*>* _interfaces; // transitive interfaces for initial class
51 int _interface_index; // current interface being processed
52 bool _local_only; // process initial class/interface only
53 bool _classes_only; // process classes only (no interfaces)
54 bool _walk_defaults; // process default methods
55 bool _base_class_search_defaults; // time to process default methods
56 bool _defaults_checked; // already checked for default methods
57 int _index;
58
59 virtual int length() = 0;
60
61 public:
62 // constructor
63 KlassStream(instanceKlassHandle klass, bool local_only, bool classes_only, bool walk_defaults);
64
65 // testing
66 bool eos();
67
68 // iterating
69 virtual void next() = 0;
70
71 // accessors
72 instanceKlassHandle klass() const { return _klass; }
73 int index() const { return _index; }
74 bool base_class_search_defaults() const { return _base_class_search_defaults; }
75 void base_class_search_defaults(bool b) { _base_class_search_defaults = b; }
76 };
77
78
79 // A MethodStream streams over all methods in a class, superclasses and (super)interfaces.
80 // Streaming is done in reverse order (subclasses first, methods in reverse order)
81 // Usage:
82 //
83 // for (MethodStream st(k, false, false); !st.eos(); st.next()) {
84 // Method* m = st.method();
85 // ...
86 // }
87
88 class MethodStream : public KlassStream {
89 private:
90 int length() { return methods()->length(); }
91 Array<Method*>* methods() {
92 if (base_class_search_defaults()) {
93 base_class_search_defaults(false);
94 return _klass->default_methods();
95 } else {
96 return _klass->methods();
97 }
98 }
99 public:
100 MethodStream(instanceKlassHandle klass, bool local_only, bool classes_only)
101 : KlassStream(klass, local_only, classes_only, true) {
102 _index = length();
103 next();
104 }
105
106 void next() { _index--; }
107 Method* method() { return methods()->at(index()); }
108 };
109
110
111 // A FieldStream streams over all fields in a class, superclasses and (super)interfaces.
112 // Streaming is done in reverse order (subclasses first, fields in reverse order)
113 // Usage:
114 //
115 // for (FieldStream st(k, false, false); !st.eos(); st.next()) {
116 // Symbol* field_name = st.name();
117 // ...
118 // }
119
120
121 class FieldStream : public KlassStream {
122 private:
123 int length() { return _klass->java_fields_count(); }
124
125 fieldDescriptor _fd_buf;
126
127 public:
128 FieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
129 : KlassStream(klass, local_only, classes_only, false) {
130 _index = length();
131 next();
132 }
133
134 void next() { _index -= 1; }
135
136 // Accessors for current field
137 AccessFlags access_flags() const {
138 AccessFlags flags;
139 flags.set_flags(_klass->field_access_flags(_index));
140 return flags;
141 }
142 Symbol* name() const {
143 return _klass->field_name(_index);
144 }
145 Symbol* signature() const {
146 return _klass->field_signature(_index);
147 }
148 // missing: initval()
149 int offset() const {
150 return _klass->field_offset( index() );
151 }
152 // bridge to a heavier API:
153 fieldDescriptor& field_descriptor() const {
154 fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
155 field.reinitialize(_klass(), _index);
156 return field;
157 }
158 };
159
160 class FilteredField : public CHeapObj<mtInternal> {
161 private:
162 Klass* _klass;
163 int _field_offset;
164
165 public:
166 FilteredField(Klass* klass, int field_offset) {
167 _klass = klass;
168 _field_offset = field_offset;
169 }
170 Klass* klass() { return _klass; }
171 int field_offset() { return _field_offset; }
172 };
173
174 class FilteredFieldsMap : AllStatic {
175 private:
176 static GrowableArray<FilteredField *> *_filtered_fields;
177 public:
178 static void initialize();
179 static bool is_filtered_field(Klass* klass, int field_offset) {
180 for (int i=0; i < _filtered_fields->length(); i++) {
181 if (klass == _filtered_fields->at(i)->klass() &&
182 field_offset == _filtered_fields->at(i)->field_offset()) {
183 return true;
184 }
185 }
186 return false;
187 }
188 static int filtered_fields_count(Klass* klass, bool local_only) {
189 int nflds = 0;
190 for (int i=0; i < _filtered_fields->length(); i++) {
191 if (local_only && klass == _filtered_fields->at(i)->klass()) {
192 nflds++;
193 } else if (klass->is_subtype_of(_filtered_fields->at(i)->klass())) {
194 nflds++;
195 }
196 }
197 return nflds;
198 }
199 // Enhance Class Redefinition Support
200 static void classes_do(KlassClosure* f) {
201 for (int i = 0; i < _filtered_fields->length(); i++) {
202 f->do_klass(_filtered_fields->at(i)->klass());
203 }
204 }
205 };
206
207
208 // A FilteredFieldStream streams over all fields in a class, superclasses and
209 // (super)interfaces. Streaming is done in reverse order (subclasses first,
210 // fields in reverse order)
211 //
212 // Usage:
213 //
214 // for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) {
215 // Symbol* field_name = st.name();
216 // ...
217 // }
218
219 class FilteredFieldStream : public FieldStream {
220 private:
221 int _filtered_fields_count;
222 bool has_filtered_field() { return (_filtered_fields_count > 0); }
223
224 public:
225 FilteredFieldStream(instanceKlassHandle klass, bool local_only, bool classes_only)
226 : FieldStream(klass, local_only, classes_only) {
227 _filtered_fields_count = FilteredFieldsMap::filtered_fields_count((Klass*)klass(), local_only);
228 }
229 int field_count();
230 void next() {
231 _index -= 1;
232 if (has_filtered_field()) {
233 while (_index >=0 && FilteredFieldsMap::is_filtered_field((Klass*)_klass(), offset())) {
234 _index -= 1;
235 }
236 }
237 }
238 };
239
240 #endif // SHARE_VM_RUNTIME_REFLECTIONUTILS_HPP

mercurial