diff -r ff1e37e7eb83 -r 4c1b88a53c74 src/share/vm/memory/iterator.hpp --- a/src/share/vm/memory/iterator.hpp Wed Mar 12 15:25:35 2014 +0100 +++ b/src/share/vm/memory/iterator.hpp Tue Jun 24 16:20:15 2014 +0200 @@ -134,9 +134,19 @@ }; class KlassToOopClosure : public KlassClosure { + friend class MetadataAwareOopClosure; + friend class MetadataAwareOopsInGenClosure; + OopClosure* _oop_closure; - public: - KlassToOopClosure(OopClosure* oop_closure) : _oop_closure(oop_closure) {} + + // Used when _oop_closure couldn't be set in an initialization list. + void initialize(OopClosure* oop_closure) { + assert(_oop_closure == NULL, "Should only be called once"); + _oop_closure = oop_closure; + } + +public: + KlassToOopClosure(OopClosure* oop_closure = NULL) : _oop_closure(oop_closure) {} virtual void do_klass(Klass* k); }; @@ -154,6 +164,29 @@ void do_cld(ClassLoaderData* cld); }; +// The base class for all concurrent marking closures, +// that participates in class unloading. +// It's used to proxy through the metadata to the oops defined in them. +class MetadataAwareOopClosure: public ExtendedOopClosure { + KlassToOopClosure _klass_closure; + + public: + MetadataAwareOopClosure() : ExtendedOopClosure() { + _klass_closure.initialize(this); + } + MetadataAwareOopClosure(ReferenceProcessor* rp) : ExtendedOopClosure(rp) { + _klass_closure.initialize(this); + } + + virtual bool do_metadata() { return do_metadata_nv(); } + inline bool do_metadata_nv() { return true; } + + virtual void do_klass(Klass* k); + void do_klass_nv(Klass* k); + + virtual void do_class_loader_data(ClassLoaderData* cld); +}; + // ObjectClosure is used for iterating through an object space class ObjectClosure : public Closure { @@ -337,4 +370,16 @@ } }; + +// Helper defines for ExtendOopClosure + +#define if_do_metadata_checked(closure, nv_suffix) \ + /* Make sure the non-virtual and the virtual versions match. */ \ + assert(closure->do_metadata##nv_suffix() == closure->do_metadata(), \ + "Inconsistency in do_metadata"); \ + if (closure->do_metadata##nv_suffix()) + +#define assert_should_ignore_metadata(closure, nv_suffix) \ + assert(!closure->do_metadata##nv_suffix(), "Code to handle metadata is not implemented") + #endif // SHARE_VM_MEMORY_ITERATOR_HPP