< prev index next >

src/hotspot/share/oops/fieldStreams.hpp

Print this page

 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
< prev index next >