< prev index next >

src/hotspot/share/oops/fieldStreams.hpp

Print this page
*** 37,10 ***
--- 37,11 ---
  // iterates over fields that have been injected by the JVM.
  // AllFieldStream exposes all fields and should only be used in rare
  // cases.
  // HierarchicalFieldStream allows to also iterate over fields of supertypes.
  class FieldStreamBase : public StackObj {
+ 
   protected:
    const Array<u1>*    _fieldinfo_stream;
    FieldInfoReader     _reader;
    constantPoolHandle  _constants;
    int                 _index;

*** 108,18 ***
--- 109,30 ---
  
    int offset() const {
      return field()->offset();
    }
  
+   bool is_null_free_inline_type() {
+     return field()->field_flags().is_null_free_inline_type();
+   }
+ 
+   bool is_flat() const {
+     return field()->field_flags().is_flat();
+   }
+ 
    bool is_contended() const {
      return field()->is_contended();
    }
  
    int contended_group() const {
      return field()->contended_group();
    }
  
+   int null_marker_offset() const {
+     return field()->null_marker_offset();
+   }
+ 
    // Convenient methods
  
    const FieldInfo& to_FieldInfo() const {
      return _fi_buf;
    }

*** 178,13 ***
   public:
    AllFieldStream(Array<u1>* fieldinfo, ConstantPool* constants): FieldStreamBase(fieldinfo, constants) {}
    AllFieldStream(const InstanceKlass* k):      FieldStreamBase(k->fieldinfo_stream(), k->constants()) {}
  };
  
! // Iterate over fields including the ones declared in supertypes
  template<typename FieldStreamType>
! class HierarchicalFieldStream : public StackObj  {
   private:
    const Array<InstanceKlass*>* _interfaces;
    InstanceKlass* _next_klass; // null indicates no more type to visit
    FieldStreamType _current_stream;
    int _interface_index;
--- 191,91 ---
   public:
    AllFieldStream(Array<u1>* fieldinfo, ConstantPool* constants): FieldStreamBase(fieldinfo, constants) {}
    AllFieldStream(const InstanceKlass* k):      FieldStreamBase(k->fieldinfo_stream(), k->constants()) {}
  };
  
! /* Very generally, a base class for a stream adapter, a derived class just implements
+  * current_stream that returns a FieldStreamType, and this adapter takes care of providing
+  * the methods of FieldStreamBase.
+  *
+  * In practice, this is used to provide a stream over the fields of a class and its superclasses
+  * and interfaces. The derived class of HierarchicalFieldStreamBase decides in which order we iterate
+  * on the superclasses (and interfaces), and the template parameter FieldStreamType is the underlying
+  * stream we use to iterate over the fields each class. Methods such as done and next are still up to
+  * the derived classes, allowing them to iterate over the class hierarchy, but also skip elements that
+  * the underlying FieldStreamType would otherwise include.
+  */
+ template<typename FieldStreamType>
+ class HierarchicalFieldStreamBase : public StackObj {
+   virtual FieldStreamType& current_stream() = 0;
+   virtual const FieldStreamType& current_stream() const = 0;
+ 
+ public:
+   // bridge functions from FieldStreamBase
+   int index() const {
+     return current_stream().index();
+   }
+ 
+   AccessFlags access_flags() const {
+     return current_stream().access_flags();
+   }
+ 
+   FieldInfo::FieldFlags field_flags() const {
+     return current_stream().field_flags();
+   }
+ 
+   Symbol* name() const {
+     return current_stream().name();
+   }
+ 
+   Symbol* signature() const {
+     return current_stream().signature();
+   }
+ 
+   Symbol* generic_signature() const {
+     return current_stream().generic_signature();
+   }
+ 
+   int offset() const {
+     return current_stream().offset();
+   }
+ 
+   bool is_contended() const {
+     return current_stream().is_contended();
+   }
+ 
+   int contended_group() const {
+     return current_stream().contended_group();
+   }
+ 
+   FieldInfo to_FieldInfo() {
+     return current_stream().to_FieldInfo();
+   }
+ 
+   fieldDescriptor& field_descriptor() const {
+     return current_stream().field_descriptor();
+   }
+ 
+   bool is_flat() const {
+     return current_stream().is_flat();
+   }
+ 
+   bool is_null_free_inline_type() {
+     return current_stream().is_null_free_inline_type();
+   }
+ 
+   int null_marker_offset() {
+     return current_stream().null_marker_offset();
+   }
+ };
+ 
+ /* Iterate over fields including the ones declared in supertypes.
+  * Derived classes are traversed before base classes, and interfaces
+  * at the end.
+  */
  template<typename FieldStreamType>
! class HierarchicalFieldStream final : public HierarchicalFieldStreamBase<FieldStreamType>  {
   private:
    const Array<InstanceKlass*>* _interfaces;
    InstanceKlass* _next_klass; // null indicates no more type to visit
    FieldStreamType _current_stream;
    int _interface_index;

*** 218,12 ***
        assert(!_current_stream.done(), "created empty stream");
        _next_klass = next_klass_with_fields();
      }
    }
  
   public:
!   HierarchicalFieldStream(InstanceKlass* klass) :
      _interfaces(klass->transitive_interfaces()),
      _next_klass(klass),
      _current_stream(FieldStreamType(klass)),
      _interface_index(_interfaces->length()) {
        prepare();
--- 309,15 ---
        assert(!_current_stream.done(), "created empty stream");
        _next_klass = next_klass_with_fields();
      }
    }
  
+   FieldStreamType& current_stream() override { return _current_stream; }
+   const FieldStreamType& current_stream() const override { return _current_stream; }
+ 
   public:
!   explicit HierarchicalFieldStream(InstanceKlass* klass) :
      _interfaces(klass->transitive_interfaces()),
      _next_klass(klass),
      _current_stream(FieldStreamType(klass)),
      _interface_index(_interfaces->length()) {
        prepare();

*** 233,51 ***
      _current_stream.next();
      next_stream_if_done();
    }
  
    bool done() const { return _next_klass == nullptr && _current_stream.done(); }
  
!   // bridge functions from FieldStreamBase
! 
!   AccessFlags access_flags() const {
!     return _current_stream.access_flags();
!   }
! 
!   FieldInfo::FieldFlags field_flags() const {
!     return _current_stream.field_flags();
!   }
! 
!   Symbol* name() const {
!     return _current_stream.name();
!   }
! 
!   Symbol* signature() const {
!     return _current_stream.signature();
    }
  
!   Symbol* generic_signature() const {
!     return _current_stream.generic_signature();
    }
  
!   int offset() const {
!     return _current_stream.offset();
    }
  
!   bool is_contended() const {
!     return _current_stream.is_contended();
    }
  
!   int contended_group() const {
!     return _current_stream.contended_group();
-   }
  
!   FieldInfo to_FieldInfo() {
!     return _current_stream.to_FieldInfo();
    }
  
!   fieldDescriptor& field_descriptor() const {
!     return _current_stream.field_descriptor();
    }
  
  };
  
  #endif // SHARE_OOPS_FIELDSTREAMS_HPP
--- 327,69 ---
      _current_stream.next();
      next_stream_if_done();
    }
  
    bool done() const { return _next_klass == nullptr && _current_stream.done(); }
+ };
  
! /* Iterates on the fields of a class and its super-class top-down (java.lang.Object first)
!  * Doesn't traverse interfaces for now, because it's not clear which order would make sense
!  * Let's decide when or if the need arises. Since we are not traversing interfaces, we
!  * wouldn't get all the static fields, and since the current use-case of this stream does not
!  * care about static fields, we restrict it to regular non-static fields.
!  */
! class TopDownHierarchicalNonStaticFieldStreamBase final : public HierarchicalFieldStreamBase<JavaFieldStream> {
!   GrowableArray<InstanceKlass*>* _super_types;  // Self and super type, bottom up
!   int _current_stream_index;
!   JavaFieldStream _current_stream;
! 
!   void next_stream_if_needed() {
!     precond(_current_stream_index >= 0);
!     while (_current_stream.done()) {
!       _current_stream_index--;
!       if (_current_stream_index < 0) {
+         return;
+       }
+       _current_stream = JavaFieldStream(_super_types->at(_current_stream_index));
+     }
    }
  
!   GrowableArray<InstanceKlass*>* get_super_types(InstanceKlass* klass) {
!     auto super_types = new GrowableArray<InstanceKlass*>();
+     do {
+       super_types->push(klass);
+     } while ((klass = klass->java_super()) != nullptr);
+     return super_types;
    }
  
!   void raw_next() {
!     _current_stream.next();
+     next_stream_if_needed();
    }
  
!   void closest_non_static() {
!     while (!done() && access_flags().is_static()) {
+       raw_next();
+     }
    }
  
!   JavaFieldStream& current_stream() override { return _current_stream; }
!   const JavaFieldStream& current_stream() const override { return _current_stream; }
  
!  public:
!   explicit TopDownHierarchicalNonStaticFieldStreamBase(InstanceKlass* klass) :
+     _super_types(get_super_types(klass)),
+     _current_stream_index(_super_types->length() - 1),
+     _current_stream(JavaFieldStream(_super_types->at(_current_stream_index))) {
+     next_stream_if_needed();
+     closest_non_static();
    }
  
!   void next() {
!     raw_next();
+     closest_non_static();
    }
  
+   bool done() const { return _current_stream_index < 0; }
  };
  
  #endif // SHARE_OOPS_FIELDSTREAMS_HPP
< prev index next >