< prev index next >

src/hotspot/share/memory/metaspaceClosure.hpp

Print this page

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




 83   };
 84 
 85   // class MetaspaceClosure::Ref --
 86   //
 87   // MetaspaceClosure can be viewed as a very simple type of copying garbage
 88   // collector. For it to function properly, it requires each subclass of
 89   // MetaspaceObj to provide two methods:
 90   //
 91   //  size_t size();                                 -- to determine how much data to copy
 92   //  void metaspace_pointers_do(MetaspaceClosure*); -- to locate all the embedded pointers
 93   //
 94   // Calling these methods would be trivial if these two were virtual methods.
 95   // However, to save space, MetaspaceObj has NO vtable. The vtable is introduced
 96   // only in the Metadata class.
 97   //
 98   // To work around the lack of a vtable, we use the Ref class with templates
 99   // (see MSORef, OtherArrayRef, MSOArrayRef, and MSOPointerArrayRef)
100   // so that we can statically discover the type of a object. The use of Ref
101   // depends on the fact that:
102   //

341     push_with_ref<MSOPointerArrayRef<T>>(mpp, w);
342   }
343 
344 #if 0
345   // Enable this block if you're changing the push(...) methods, to test for types that should be
346   // disallowed. Each of the following "push" calls should result in a compile-time error.
347   void test_disallowed_types(MetaspaceClosure* it) {
348     Hashtable<bool, mtInternal>* h  = NULL;
349     it->push(&h);
350 
351     Array<Hashtable<bool, mtInternal>*>* a6 = NULL;
352     it->push(&a6);
353 
354     Array<int*>* a7 = NULL;
355     it->push(&a7);
356   }
357 #endif
358 
359   template <class T> void push_method_entry(T** mpp, intptr_t* p) {
360     Ref* ref = new MSORef<T>(mpp, _default);
361     push_special(_method_entry_ref, ref, (intptr_t*)p);








362     if (!ref->keep_after_pushing()) {
363       delete ref;
364     }
365   }
366 
367   // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently
368   // used to mark the method entry points in Method/ConstMethod.
369   virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) {
370     assert(type == _method_entry_ref, "only special type allowed for now");




371   }
372 };
373 
374 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once.
375 class UniqueMetaspaceClosure : public MetaspaceClosure {
376   static const int INITIAL_TABLE_SIZE = 15889;
377   static const int MAX_TABLE_SIZE     = 1000000;
378 
379   // Do not override. Returns true if we are discovering ref->obj() for the first time.
380   virtual bool do_ref(Ref* ref, bool read_only);
381 
382 public:
383   // Gets called the first time we discover an object.
384   virtual bool do_unique_ref(Ref* ref, bool read_only) = 0;
385   UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE) {}
386 
387 private:
388   ResizeableResourceHashtable<address, bool, ResourceObj::C_HEAP,
389                               mtClassShared> _has_been_visited;
390 };

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

345     push_with_ref<MSOPointerArrayRef<T>>(mpp, w);
346   }
347 
348 #if 0
349   // Enable this block if you're changing the push(...) methods, to test for types that should be
350   // disallowed. Each of the following "push" calls should result in a compile-time error.
351   void test_disallowed_types(MetaspaceClosure* it) {
352     Hashtable<bool, mtInternal>* h  = NULL;
353     it->push(&h);
354 
355     Array<Hashtable<bool, mtInternal>*>* a6 = NULL;
356     it->push(&a6);
357 
358     Array<int*>* a7 = NULL;
359     it->push(&a7);
360   }
361 #endif
362 
363   template <class T> void push_method_entry(T** mpp, intptr_t* p) {
364     Ref* ref = new MSORef<T>(mpp, _default);
365     push_special(_method_entry_ref, ref, p);
366     if (!ref->keep_after_pushing()) {
367       delete ref;
368     }
369   }
370 
371   template <class T> void push_internal_pointer(T** mpp, intptr_t* p) {
372     Ref* ref = new MSORef<T>(mpp, _default);
373     push_special(_internal_pointer_ref, ref, p);
374     if (!ref->keep_after_pushing()) {
375       delete ref;
376     }
377   }
378 
379   // This is for tagging special pointers that are not a reference to MetaspaceObj. It's currently
380   // used to mark the method entry points in Method/ConstMethod.
381   virtual void push_special(SpecialRef type, Ref* obj, intptr_t* p) {
382     assert_valid(type);
383   }
384 
385   static void assert_valid(SpecialRef type) {
386     assert(type == _method_entry_ref || type == _internal_pointer_ref, "only special types allowed for now");
387   }
388 };
389 
390 // This is a special MetaspaceClosure that visits each unique MetaspaceObj once.
391 class UniqueMetaspaceClosure : public MetaspaceClosure {
392   static const int INITIAL_TABLE_SIZE = 15889;
393   static const int MAX_TABLE_SIZE     = 1000000;
394 
395   // Do not override. Returns true if we are discovering ref->obj() for the first time.
396   virtual bool do_ref(Ref* ref, bool read_only);
397 
398 public:
399   // Gets called the first time we discover an object.
400   virtual bool do_unique_ref(Ref* ref, bool read_only) = 0;
401   UniqueMetaspaceClosure() : _has_been_visited(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE) {}
402 
403 private:
404   ResizeableResourceHashtable<address, bool, ResourceObj::C_HEAP,
405                               mtClassShared> _has_been_visited;
406 };
< prev index next >