< prev index next >

src/hotspot/share/memory/metaspaceClosure.hpp

Print this page


  58 // provides an API to walk all the reachable objects starting from a set of
  59 // root references (such as all Klass'es in the SystemDictionary).
  60 //
  61 // Currently it is used for compacting the CDS archive by eliminate temporary
  62 // objects allocated during archive creation time. See ArchiveCompactor in
  63 // metaspaceShared.cpp for an example.
  64 //
  65 // To support MetaspaceClosure, each subclass of MetaspaceObj must provide
  66 // a method of the type void metaspace_pointers_do(MetaspaceClosure*). This method
  67 // should call MetaspaceClosure::push() on every pointer fields of this
  68 // class that points to a MetaspaceObj. See Annotations::metaspace_pointers_do()
  69 // for an example.
  70 class MetaspaceClosure {
  71 public:
  72   enum Writability {
  73     _writable,
  74     _not_writable,
  75     _default
  76   };
  77 




  78   // class MetaspaceClosure::Ref --
  79   //
  80   // MetaspaceClosure can be viewed as a very simple type of copying garbage
  81   // collector. For it to function properly, it requires each subclass of
  82   // MetaspaceObj to provide two methods:
  83   //
  84   //  size_t size();                                 -- to determine how much data to copy
  85   //  void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers
  86   //
  87   // Calling these methods would be trivial if these two were virtual methods.
  88   // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced
  89   // only in the Metadata class.
  90   //
  91   // To work around the lack of a vtable, we use Ref class with templates
  92   // (see ObjectRef, PrimitiveArrayRef and PointerArrayRef)
  93   // so that we can statically discover the type of a object. The use of Ref
  94   // depends on the fact that:
  95   //
  96   // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses
  97   //     of Metadata. I.e., we don't do this:


 260   // When you do:
 261   //     void MyType::metaspace_pointers_do(MetaspaceClosure* it) {
 262   //       it->push(_my_field)
 263   //
 264   // C++ will try to match the "most specific" template function. This one will
 265   // will be matched if possible (if mpp is an Array<> of any pointer type).
 266   template <typename T> void push(Array<T*>** mpp, Writability w = _default) {
 267     push_impl(new PointerArrayRef<T>(mpp, w));
 268   }
 269 
 270   // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then
 271   // this is the second choice.
 272   template <typename T> void push(Array<T>** mpp, Writability w = _default) {
 273     push_impl(new PrimitiveArrayRef<T>(mpp, w));
 274   }
 275 
 276   // If the above function doesn't match (mpp is not an Array<> type), then
 277   // this will be matched by default.
 278   template <class T> void push(T** mpp, Writability w = _default) {
 279     push_impl(new ObjectRef<T>(mpp, w));










 280   }
 281 };
 282 
 283 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once.
 284 class UniqueMetaspaceClosure : public MetaspaceClosure {
 285   static const int INITIAL_TABLE_SIZE = 15889;
 286   static const int MAX_TABLE_SIZE     = 1000000;
 287 
 288   // Do not override. Returns true if we are discovering ref->obj() for the first time.
 289   virtual bool do_ref(Ref* ref, bool read_only);
 290 
 291 public:
 292   // Gets called the first time we discover an object.
 293   virtual bool do_unique_ref(Ref* ref, bool read_only) = 0;
 294   UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {}
 295 
 296 private:
 297   KVHashtable<address, bool, mtInternal> _has_been_visited;
 298 };
 299 


  58 // provides an API to walk all the reachable objects starting from a set of
  59 // root references (such as all Klass'es in the SystemDictionary).
  60 //
  61 // Currently it is used for compacting the CDS archive by eliminate temporary
  62 // objects allocated during archive creation time. See ArchiveCompactor in
  63 // metaspaceShared.cpp for an example.
  64 //
  65 // To support MetaspaceClosure, each subclass of MetaspaceObj must provide
  66 // a method of the type void metaspace_pointers_do(MetaspaceClosure*). This method
  67 // should call MetaspaceClosure::push() on every pointer fields of this
  68 // class that points to a MetaspaceObj. See Annotations::metaspace_pointers_do()
  69 // for an example.
  70 class MetaspaceClosure {
  71 public:
  72   enum Writability {
  73     _writable,
  74     _not_writable,
  75     _default
  76   };
  77 
  78   enum SpecialRef {
  79     _method_entry_ref
  80   };
  81 
  82   // class MetaspaceClosure::Ref --
  83   //
  84   // MetaspaceClosure can be viewed as a very simple type of copying garbage
  85   // collector. For it to function properly, it requires each subclass of
  86   // MetaspaceObj to provide two methods:
  87   //
  88   //  size_t size();                                 -- to determine how much data to copy
  89   //  void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers
  90   //
  91   // Calling these methods would be trivial if these two were virtual methods.
  92   // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced
  93   // only in the Metadata class.
  94   //
  95   // To work around the lack of a vtable, we use Ref class with templates
  96   // (see ObjectRef, PrimitiveArrayRef and PointerArrayRef)
  97   // so that we can statically discover the type of a object. The use of Ref
  98   // depends on the fact that:
  99   //
 100   // [1] We don't use polymorphic pointers for MetaspaceObj's that are not subclasses
 101   //     of Metadata. I.e., we don't do this:


 264   // When you do:
 265   //     void MyType::metaspace_pointers_do(MetaspaceClosure* it) {
 266   //       it->push(_my_field)
 267   //
 268   // C++ will try to match the "most specific" template function. This one will
 269   // will be matched if possible (if mpp is an Array<> of any pointer type).
 270   template <typename T> void push(Array<T*>** mpp, Writability w = _default) {
 271     push_impl(new PointerArrayRef<T>(mpp, w));
 272   }
 273 
 274   // If the above function doesn't match (mpp is an Array<>, but T is not a pointer type), then
 275   // this is the second choice.
 276   template <typename T> void push(Array<T>** mpp, Writability w = _default) {
 277     push_impl(new PrimitiveArrayRef<T>(mpp, w));
 278   }
 279 
 280   // If the above function doesn't match (mpp is not an Array<> type), then
 281   // this will be matched by default.
 282   template <class T> void push(T** mpp, Writability w = _default) {
 283     push_impl(new ObjectRef<T>(mpp, w));
 284   }
 285 
 286   template <class T> void push_method_entry(T** mpp, intptr_t* p) {
 287     push_special(_method_entry_ref, new ObjectRef<T>(mpp, _default), (intptr_t*)p);
 288   }
 289 
 290   // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently
 291   // used to mark the method entry points in Method/ConstMethod.
 292   virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) {
 293     assert(type == _method_entry_ref, "only special type allowed for now");
 294   }
 295 };
 296 
 297 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once.
 298 class UniqueMetaspaceClosure : public MetaspaceClosure {
 299   static const int INITIAL_TABLE_SIZE = 15889;
 300   static const int MAX_TABLE_SIZE     = 1000000;
 301 
 302   // Do not override. Returns true if we are discovering ref->obj() for the first time.
 303   virtual bool do_ref(Ref* ref, bool read_only);
 304 
 305 public:
 306   // Gets called the first time we discover an object.
 307   virtual bool do_unique_ref(Ref* ref, bool read_only) = 0;
 308   UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE) {}
 309 
 310 private:
 311   KVHashtable<address, bool, mtInternal> _has_been_visited;
 312 };
 313 
< prev index next >