8055098: WB API should be extended to provide information about size and age of object.
Summary: Extend the WhiteBox API to provide information about the size and age of objects. Further add a mechanism to trigger a young GC.
Reviewed-by: tschatzl, sjohanss
Contributed-by: Leonid Mesnik <leonid.mesnik@oracle.com>
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Aug 21 16:44:41 2014 +0200
@@ -2516,7 +2516,7 @@
}
}
} else {
- if (cause == GCCause::_gc_locker
+ if (cause == GCCause::_gc_locker || cause == GCCause::_wb_young_gc
DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {
// Schedule a standard evacuation pause. We're setting word_size
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Thu Aug 21 16:44:41 2014 +0200
@@ -70,7 +70,7 @@
"must be a ParallelScavengeHeap");
GCCauseSetter gccs(heap, _gc_cause);
- if (_gc_cause == GCCause::_gc_locker
+ if (_gc_cause == GCCause::_gc_locker || _gc_cause == GCCause::_wb_young_gc
DEBUG_ONLY(|| _gc_cause == GCCause::_scavenge_alot)) {
// If (and only if) the scavenge fails, this will invoke a full gc.
heap->invoke_scavenge();
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Aug 21 16:44:41 2014 +0200
@@ -51,6 +51,9 @@
case _heap_dump:
return "Heap Dump Initiated GC";
+ case _wb_young_gc:
+ return "WhiteBox Initiated Young GC";
+
case _no_gc:
return "No GC";
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Aug 21 16:44:41 2014 +0200
@@ -46,6 +46,7 @@
_gc_locker,
_heap_inspection,
_heap_dump,
+ _wb_young_gc,
/* implementation independent, but reserved for GC use */
_no_gc,
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Aug 21 16:44:41 2014 +0200
@@ -708,15 +708,18 @@
#else // INCLUDE_ALL_GCS
ShouldNotReachHere();
#endif // INCLUDE_ALL_GCS
+ } else if (cause == GCCause::_wb_young_gc) {
+ // minor collection for WhiteBox API
+ collect(cause, 0);
} else {
#ifdef ASSERT
- if (cause == GCCause::_scavenge_alot) {
- // minor collection only
- collect(cause, 0);
- } else {
- // Stop-the-world full collection
- collect(cause, n_gens() - 1);
- }
+ if (cause == GCCause::_scavenge_alot) {
+ // minor collection only
+ collect(cause, 0);
+ } else {
+ // Stop-the-world full collection
+ collect(cause, n_gens() - 1);
+ }
#else
// Stop-the-world full collection
collect(cause, n_gens() - 1);
--- a/hotspot/src/share/vm/prims/whitebox.cpp Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Thu Aug 21 16:44:41 2014 +0200
@@ -47,6 +47,7 @@
#include "utilities/exceptions.hpp"
#if INCLUDE_ALL_GCS
+#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
#include "gc_implementation/g1/concurrentMark.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
@@ -227,6 +228,30 @@
(size_t) magnitude, (size_t) iterations);
WB_END
+WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj))
+ oop p = JNIHandles::resolve(obj);
+#if INCLUDE_ALL_GCS
+ if (UseG1GC) {
+ G1CollectedHeap* g1 = G1CollectedHeap::heap();
+ const HeapRegion* hr = g1->heap_region_containing(p);
+ if (hr == NULL) {
+ return false;
+ }
+ return !(hr->is_young());
+ } else if (UseParallelGC) {
+ ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
+ return !psh->is_in_young(p);
+ }
+#endif // INCLUDE_ALL_GCS
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ return !gch->is_in_young(p);
+WB_END
+
+WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj))
+ oop p = JNIHandles::resolve(obj);
+ return p->size() * HeapWordSize;
+WB_END
+
#if INCLUDE_ALL_GCS
WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
G1CollectedHeap* g1 = G1CollectedHeap::heap();
@@ -690,6 +715,9 @@
Universe::heap()->collect(GCCause::_last_ditch_collection);
WB_END
+WB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o))
+ Universe::heap()->collect(GCCause::_wb_young_gc);
+WB_END
WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
// static+volatile in order to force the read to happen
@@ -841,6 +869,8 @@
static JNINativeMethod methods[] = {
{CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress },
+ {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize },
+ {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen },
{CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
{CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
{CC"parseCommandLine",
@@ -919,6 +949,7 @@
(void*)&WB_GetStringVMFlag},
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
+ {CC"youngGC", CC"()V", (void*)&WB_YoungGC },
{CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
{CC"allocateMetaspace",
CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace },
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Wed Aug 20 15:04:39 2014 +0200
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Aug 21 16:44:41 2014 +0200
@@ -73,6 +73,8 @@
// Memory
public native long getObjectAddress(Object o);
public native int getHeapOopSize();
+ public native boolean isObjectInOldGen(Object o);
+ public native long getObjectSize(Object o);
// Runtime
// Make sure class name is in the correct format
@@ -150,6 +152,9 @@
public native long allocateMetaspace(ClassLoader classLoader, long size);
public native void freeMetaspace(ClassLoader classLoader, long addr, long size);
+ // force Young GC
+ public native void youngGC();
+
// force Full GC
public native void fullGC();