# HG changeset patch # User ehelin # Date 1386262195 -3600 # Node ID 816c89d5957d870194af9d85ec7485b111fee584 # Parent e84d2afb2fb099862b71c290b755a40bb6d49d9e# Parent 50287b659eb834321f08f225156063a92d5da2fb Merge diff -r e84d2afb2fb0 -r 816c89d5957d agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java --- a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Tue Dec 03 13:56:10 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Thu Dec 05 17:49:55 2013 +0100 @@ -103,14 +103,14 @@ @Override public void remove() { /* not supported */ } - HeapRegionIterator(Address addr) { + HeapRegionIterator(long committedLength) { index = 0; - length = length(); + length = committedLength; } } - public Iterator heapRegionIterator() { - return new HeapRegionIterator(addr); + public Iterator heapRegionIterator(long committedLength) { + return new HeapRegionIterator(committedLength); } public G1HeapRegionTable(Address addr) { diff -r e84d2afb2fb0 -r 816c89d5957d agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java --- a/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Tue Dec 03 13:56:10 2013 -0800 +++ b/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Thu Dec 05 17:49:55 2013 +0100 @@ -42,6 +42,8 @@ public class HeapRegionSeq extends VMObject { // G1HeapRegionTable _regions static private long regionsFieldOffset; + // uint _committed_length + static private CIntegerField committedLengthField; static { VM.registerVMInitializedObserver(new Observer() { @@ -55,6 +57,7 @@ Type type = db.lookupType("HeapRegionSeq"); regionsFieldOffset = type.getField("_regions").getOffset(); + committedLengthField = type.getCIntegerField("_committed_length"); } private G1HeapRegionTable regions() { @@ -67,8 +70,12 @@ return regions().length(); } + public long committedLength() { + return committedLengthField.getValue(addr); + } + public Iterator heapRegionIterator() { - return regions().heapRegionIterator(); + return regions().heapRegionIterator(committedLength()); } public HeapRegionSeq(Address addr) { diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/gc_implementation/shared/markSweep.cpp --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Thu Dec 05 17:49:55 2013 +0100 @@ -66,29 +66,10 @@ klass->oops_do(&MarkSweep::adjust_pointer_closure); } -void MarkSweep::follow_klass(Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - MarkSweep::follow_class_loader(cld); -} - -void MarkSweep::adjust_klass(Klass* klass) { - ClassLoaderData* cld = klass->class_loader_data(); - // The actual processing of the klass is done when we - // traverse the list of Klasses in the class loader data. - MarkSweep::adjust_class_loader(cld); -} - void MarkSweep::follow_class_loader(ClassLoaderData* cld) { cld->oops_do(&MarkSweep::mark_and_push_closure, &MarkSweep::follow_klass_closure, true); } -void MarkSweep::adjust_class_loader(ClassLoaderData* cld) { - cld->oops_do(&MarkSweep::adjust_pointer_closure, &MarkSweep::adjust_klass_closure, true); -} - - void MarkSweep::follow_stack() { do { while (!_marking_stack.is_empty()) { diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/gc_implementation/shared/markSweep.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Thu Dec 05 17:49:55 2013 +0100 @@ -172,10 +172,8 @@ static void follow_stack(); // Empty marking stack. static void follow_klass(Klass* klass); - static void adjust_klass(Klass* klass); static void follow_class_loader(ClassLoaderData* cld); - static void adjust_class_loader(ClassLoaderData* cld); static void preserve_mark(oop p, markOop mark); // Save the mark word so it can be restored later diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/gc_implementation/shared/markSweep.inline.hpp --- a/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Thu Dec 05 17:49:55 2013 +0100 @@ -44,6 +44,11 @@ } } +inline void MarkSweep::follow_klass(Klass* klass) { + oop op = klass->klass_holder(); + MarkSweep::mark_and_push(&op); +} + template inline void MarkSweep::follow_root(T* p) { assert(!Universe::heap()->is_in_reserved(p), "roots shouldn't be things within the heap"); diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Dec 05 17:49:55 2013 +0100 @@ -2180,7 +2180,6 @@ obj, \ MarkSweep::adjust_pointer(p), \ assert_is_in) - MarkSweep::adjust_klass(obj->klass()); return size; } diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/oops/instanceMirrorKlass.cpp --- a/src/share/vm/oops/instanceMirrorKlass.cpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/oops/instanceMirrorKlass.cpp Thu Dec 05 17:49:55 2013 +0100 @@ -155,7 +155,13 @@ // Follow the klass field in the mirror. Klass* klass = java_lang_Class::as_Klass(obj); if (klass != NULL) { - MarkSweep::follow_klass(klass); + // For anonymous classes we need to handle the class loader data, + // otherwise it won't be claimed and can be unloaded. + if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) { + MarkSweep::follow_class_loader(klass->class_loader_data()); + } else { + MarkSweep::follow_klass(klass); + } } else { // If klass is NULL then this a mirror for a primitive type. // We don't have to follow them, since they are handled as strong @@ -196,17 +202,6 @@ int size = oop_size(obj); InstanceKlass::oop_adjust_pointers(obj); - // Follow the klass field in the mirror. - Klass* klass = java_lang_Class::as_Klass(obj); - if (klass != NULL) { - MarkSweep::adjust_klass(klass); - } else { - // If klass is NULL then this a mirror for a primitive type. - // We don't have to follow them, since they are handled as strong - // roots in Universe::oops_do. - assert(java_lang_Class::is_primitive(obj), "Sanity check"); - } - InstanceMirrorKlass_OOP_ITERATE( \ start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \ MarkSweep::adjust_pointer(p), \ diff -r e84d2afb2fb0 -r 816c89d5957d src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Tue Dec 03 13:56:10 2013 -0800 +++ b/src/share/vm/oops/objArrayKlass.cpp Thu Dec 05 17:49:55 2013 +0100 @@ -569,7 +569,6 @@ // Get size before changing pointers. // Don't call size() or oop_size() since that is a virtual call. int size = a->object_size(); - MarkSweep::adjust_klass(a->klass()); ObjArrayKlass_OOP_ITERATE(a, p, MarkSweep::adjust_pointer(p)) return size; }