99 Symbol* name() const {
100 return field()->name(_constants());
101 }
102
103 Symbol* signature() const {
104 return field()->signature(_constants());
105 }
106
107 Symbol* generic_signature() const {
108 if (field()->field_flags().is_generic()) {
109 return _constants->symbol_at(field()->generic_signature_index());
110 } else {
111 return nullptr;
112 }
113 }
114
115 int offset() const {
116 return field()->offset();
117 }
118
119 bool is_contended() const {
120 return field()->is_contended();
121 }
122
123 int contended_group() const {
124 return field()->contended_group();
125 }
126
127 // Convenient methods
128
129 const FieldInfo& to_FieldInfo() const {
130 return _fi_buf;
131 }
132
133 int num_total_fields() const {
134 return FieldInfoStream::num_total_fields(_fieldinfo_stream);
135 }
136
137 // bridge to a heavier API:
138 fieldDescriptor& field_descriptor() const {
139 fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
140 field.reinitialize(field_holder(), to_FieldInfo());
141 return field;
142 }
143 };
144
145 // Iterate over only the Java fields
146 class JavaFieldStream : public FieldStreamBase {
174 }
175
176 // Performs either a linear search or binary search through the stream
177 // looking for a matching name/signature combo
178 bool lookup(const Symbol* name, const Symbol* signature);
179 };
180
181
182 // Iterate over only the internal fields
183 class InternalFieldStream : public FieldStreamBase {
184 public:
185 InternalFieldStream(InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants(), k->java_fields_count(), 0) {}
186 };
187
188
189 class AllFieldStream : public FieldStreamBase {
190 public:
191 AllFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants()) {}
192 };
193
194 // Iterate over fields including the ones declared in supertypes
195 template<typename FieldStreamType>
196 class HierarchicalFieldStream : public StackObj {
197 private:
198 const Array<InstanceKlass*>* _interfaces;
199 InstanceKlass* _next_klass; // null indicates no more type to visit
200 FieldStreamType _current_stream;
201 int _interface_index;
202
203 void prepare() {
204 _next_klass = next_klass_with_fields();
205 // special case: the initial klass has no fields. If any supertype has any fields, use that directly.
206 // if no such supertype exists, done() will return false already.
207 next_stream_if_done();
208 }
209
210 InstanceKlass* next_klass_with_fields() {
211 assert(_next_klass != nullptr, "reached end of types already");
212 InstanceKlass* result = _next_klass;
213 do {
214 if (!result->is_interface() && result->super() != nullptr) {
215 result = result->super();
216 } else if (_interface_index > 0) {
217 result = _interfaces->at(--_interface_index);
218 } else {
219 return nullptr; // we did not find any more supertypes with fields
220 }
221 } while (FieldStreamType(result).done());
222 return result;
223 }
224
225 // sets _current_stream to the next if the current is done and any more is available
226 void next_stream_if_done() {
227 if (_next_klass != nullptr && _current_stream.done()) {
228 _current_stream = FieldStreamType(_next_klass);
229 assert(!_current_stream.done(), "created empty stream");
230 _next_klass = next_klass_with_fields();
231 }
232 }
233
234 public:
235 HierarchicalFieldStream(InstanceKlass* klass) :
236 _interfaces(klass->transitive_interfaces()),
237 _next_klass(klass),
238 _current_stream(FieldStreamType(klass)),
239 _interface_index(_interfaces->length()) {
240 prepare();
241 }
242
243 void next() {
244 _current_stream.next();
245 next_stream_if_done();
246 }
247
248 bool done() const { return _next_klass == nullptr && _current_stream.done(); }
249
250 // bridge functions from FieldStreamBase
251
252 AccessFlags access_flags() const {
253 return _current_stream.access_flags();
254 }
255
256 FieldInfo::FieldFlags field_flags() const {
257 return _current_stream.field_flags();
258 }
259
260 Symbol* name() const {
261 return _current_stream.name();
262 }
263
264 Symbol* signature() const {
265 return _current_stream.signature();
266 }
267
268 Symbol* generic_signature() const {
269 return _current_stream.generic_signature();
270 }
271
272 int offset() const {
273 return _current_stream.offset();
274 }
275
276 bool is_contended() const {
277 return _current_stream.is_contended();
278 }
279
280 int contended_group() const {
281 return _current_stream.contended_group();
282 }
283
284 FieldInfo to_FieldInfo() {
285 return _current_stream.to_FieldInfo();
286 }
287
288 fieldDescriptor& field_descriptor() const {
289 return _current_stream.field_descriptor();
290 }
291
292 };
293
294 #endif // SHARE_OOPS_FIELDSTREAMS_HPP
|
99 Symbol* name() const {
100 return field()->name(_constants());
101 }
102
103 Symbol* signature() const {
104 return field()->signature(_constants());
105 }
106
107 Symbol* generic_signature() const {
108 if (field()->field_flags().is_generic()) {
109 return _constants->symbol_at(field()->generic_signature_index());
110 } else {
111 return nullptr;
112 }
113 }
114
115 int offset() const {
116 return field()->offset();
117 }
118
119 bool is_null_free_inline_type() {
120 return field()->field_flags().is_null_free_inline_type();
121 }
122
123 bool is_flat() const {
124 return field()->field_flags().is_flat();
125 }
126
127 bool is_contended() const {
128 return field()->is_contended();
129 }
130
131 int contended_group() const {
132 return field()->contended_group();
133 }
134
135 int null_marker_offset() const {
136 return field()->null_marker_offset();
137 }
138
139 // Convenient methods
140
141 const FieldInfo& to_FieldInfo() const {
142 return _fi_buf;
143 }
144
145 int num_total_fields() const {
146 return FieldInfoStream::num_total_fields(_fieldinfo_stream);
147 }
148
149 // bridge to a heavier API:
150 fieldDescriptor& field_descriptor() const {
151 fieldDescriptor& field = const_cast<fieldDescriptor&>(_fd_buf);
152 field.reinitialize(field_holder(), to_FieldInfo());
153 return field;
154 }
155 };
156
157 // Iterate over only the Java fields
158 class JavaFieldStream : public FieldStreamBase {
186 }
187
188 // Performs either a linear search or binary search through the stream
189 // looking for a matching name/signature combo
190 bool lookup(const Symbol* name, const Symbol* signature);
191 };
192
193
194 // Iterate over only the internal fields
195 class InternalFieldStream : public FieldStreamBase {
196 public:
197 InternalFieldStream(InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants(), k->java_fields_count(), 0) {}
198 };
199
200
201 class AllFieldStream : public FieldStreamBase {
202 public:
203 AllFieldStream(const InstanceKlass* k): FieldStreamBase(k->fieldinfo_stream(), k->constants()) {}
204 };
205
206 /* Very generally, a base class for a stream adapter, a derived class just implements
207 * current_stream that returns a FieldStreamType, and this adapter takes care of providing
208 * the methods of FieldStreamBase.
209 *
210 * In practice, this is used to provide a stream over the fields of a class and its superclasses
211 * and interfaces. The derived class of HierarchicalFieldStreamBase decides in which order we iterate
212 * on the superclasses (and interfaces), and the template parameter FieldStreamType is the underlying
213 * stream we use to iterate over the fields each class. Methods such as done and next are still up to
214 * the derived classes, allowing them to iterate over the class hierarchy, but also skip elements that
215 * the underlying FieldStreamType would otherwise include.
216 */
217 template<typename FieldStreamType>
218 class HierarchicalFieldStreamBase : public StackObj {
219 virtual FieldStreamType& current_stream() = 0;
220 virtual const FieldStreamType& current_stream() const = 0;
221
222 public:
223 // bridge functions from FieldStreamBase
224 int index() const {
225 return current_stream().index();
226 }
227
228 AccessFlags access_flags() const {
229 return current_stream().access_flags();
230 }
231
232 FieldInfo::FieldFlags field_flags() const {
233 return current_stream().field_flags();
234 }
235
236 Symbol* name() const {
237 return current_stream().name();
238 }
239
240 Symbol* signature() const {
241 return current_stream().signature();
242 }
243
244 Symbol* generic_signature() const {
245 return current_stream().generic_signature();
246 }
247
248 int offset() const {
249 return current_stream().offset();
250 }
251
252 bool is_contended() const {
253 return current_stream().is_contended();
254 }
255
256 int contended_group() const {
257 return current_stream().contended_group();
258 }
259
260 FieldInfo to_FieldInfo() {
261 return current_stream().to_FieldInfo();
262 }
263
264 fieldDescriptor& field_descriptor() const {
265 return current_stream().field_descriptor();
266 }
267
268 bool is_flat() const {
269 return current_stream().is_flat();
270 }
271
272 bool is_null_free_inline_type() {
273 return current_stream().is_null_free_inline_type();
274 }
275
276 int null_marker_offset() {
277 return current_stream().null_marker_offset();
278 }
279 };
280
281 /* Iterate over fields including the ones declared in supertypes.
282 * Derived classes are traversed before base classes, and interfaces
283 * at the end.
284 */
285 template<typename FieldStreamType>
286 class HierarchicalFieldStream final : public HierarchicalFieldStreamBase<FieldStreamType> {
287 private:
288 const Array<InstanceKlass*>* _interfaces;
289 InstanceKlass* _next_klass; // null indicates no more type to visit
290 FieldStreamType _current_stream;
291 int _interface_index;
292
293 void prepare() {
294 _next_klass = next_klass_with_fields();
295 // special case: the initial klass has no fields. If any supertype has any fields, use that directly.
296 // if no such supertype exists, done() will return false already.
297 next_stream_if_done();
298 }
299
300 InstanceKlass* next_klass_with_fields() {
301 assert(_next_klass != nullptr, "reached end of types already");
302 InstanceKlass* result = _next_klass;
303 do {
304 if (!result->is_interface() && result->super() != nullptr) {
305 result = result->super();
306 } else if (_interface_index > 0) {
307 result = _interfaces->at(--_interface_index);
308 } else {
309 return nullptr; // we did not find any more supertypes with fields
310 }
311 } while (FieldStreamType(result).done());
312 return result;
313 }
314
315 // sets _current_stream to the next if the current is done and any more is available
316 void next_stream_if_done() {
317 if (_next_klass != nullptr && _current_stream.done()) {
318 _current_stream = FieldStreamType(_next_klass);
319 assert(!_current_stream.done(), "created empty stream");
320 _next_klass = next_klass_with_fields();
321 }
322 }
323
324 FieldStreamType& current_stream() override { return _current_stream; }
325 const FieldStreamType& current_stream() const override { return _current_stream; }
326
327 public:
328 explicit HierarchicalFieldStream(InstanceKlass* klass) :
329 _interfaces(klass->transitive_interfaces()),
330 _next_klass(klass),
331 _current_stream(FieldStreamType(klass)),
332 _interface_index(_interfaces->length()) {
333 prepare();
334 }
335
336 void next() {
337 _current_stream.next();
338 next_stream_if_done();
339 }
340
341 bool done() const { return _next_klass == nullptr && _current_stream.done(); }
342 };
343
344 /* Iterates on the fields of a class and its super-class top-down (java.lang.Object first)
345 * Doesn't traverse interfaces for now, because it's not clear which order would make sense
346 * Let's decide when or if the need arises. Since we are not traversing interfaces, we
347 * wouldn't get all the static fields, and since the current use-case of this stream does not
348 * care about static fields, we restrict it to regular non-static fields.
349 */
350 class TopDownHierarchicalNonStaticFieldStreamBase final : public HierarchicalFieldStreamBase<JavaFieldStream> {
351 GrowableArray<InstanceKlass*>* _super_types; // Self and super type, bottom up
352 int _current_stream_index;
353 JavaFieldStream _current_stream;
354
355 void next_stream_if_needed() {
356 precond(_current_stream_index >= 0);
357 while (_current_stream.done()) {
358 _current_stream_index--;
359 if (_current_stream_index < 0) {
360 return;
361 }
362 _current_stream = JavaFieldStream(_super_types->at(_current_stream_index));
363 }
364 }
365
366 GrowableArray<InstanceKlass*>* get_super_types(InstanceKlass* klass) {
367 auto super_types = new GrowableArray<InstanceKlass*>();
368 do {
369 super_types->push(klass);
370 } while ((klass = klass->java_super()) != nullptr);
371 return super_types;
372 }
373
374 void raw_next() {
375 _current_stream.next();
376 next_stream_if_needed();
377 }
378
379 void closest_nonstatic() {
380 while (!done() && access_flags().is_static()) {
381 raw_next();
382 }
383 }
384
385 JavaFieldStream& current_stream() override { return _current_stream; }
386 const JavaFieldStream& current_stream() const override { return _current_stream; }
387
388 public:
389 explicit TopDownHierarchicalNonStaticFieldStreamBase(InstanceKlass* klass) :
390 _super_types(get_super_types(klass)),
391 _current_stream_index(_super_types->length() - 1),
392 _current_stream(JavaFieldStream(_super_types->at(_current_stream_index))) {
393 next_stream_if_needed();
394 closest_nonstatic();
395 }
396
397 void next() {
398 raw_next();
399 closest_nonstatic();
400 }
401
402 bool done() const { return _current_stream_index < 0; }
403 };
404
405 #endif // SHARE_OOPS_FIELDSTREAMS_HPP
|