--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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<HeapRegion> heapRegionIterator() {
- return new HeapRegionIterator(addr);
+ public Iterator<HeapRegion> heapRegionIterator(long committedLength) {
+ return new HeapRegionIterator(committedLength);
}
public G1HeapRegionTable(Address addr) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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<HeapRegion> heapRegionIterator() {
- return regions().heapRegionIterator();
+ return regions().heapRegionIterator(committedLength());
}
public HeapRegionSeq(Address addr) {
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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()) {
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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 <class T> inline void MarkSweep::follow_root(T* p) {
assert(!Universe::heap()->is_in_reserved(p),
"roots shouldn't be things within the heap");
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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;
}
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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), \
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Tue Dec 03 13:56:10 2013 -0800
+++ b/hotspot/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;
}