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