From 3e3610d3599cb148bd895b6652c3f76614e0ef60 Mon Sep 17 00:00:00 2001 From: kevinw Date: Wed, 2 Dec 2015 13:58:34 +0530 Subject: [PATCH] 8065579: WB method to start G1 concurrent mark cycle should be introduced Summary: Add a WhiteBox callback to the VM to start a concurrent mark cycle in G1. Reviewed-by: tschatzl, sjohanss Contributed-by: Leonid Mesnik --- .../gc_implementation/g1/g1CollectedHeap.cpp | 1 + .../gc_implementation/g1/vm_operations_g1.cpp | 8 +-- src/share/vm/gc_interface/gcCause.cpp | 3 + src/share/vm/gc_interface/gcCause.hpp | 1 + src/share/vm/prims/whitebox.cpp | 14 ++++- test/gc/whitebox/TestConcMarkCycleWB.java | 57 +++++++++++++++++++ .../whitebox/sun/hotspot/WhiteBox.java | 8 ++- 7 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 test/gc/whitebox/TestConcMarkCycleWB.java diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 4b3799d0a..f5212f059 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2331,6 +2331,7 @@ bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent; case GCCause::_g1_humongous_allocation: return true; case GCCause::_update_allocation_context_stats_inc: return true; + case GCCause::_wb_conc_mark: return true; default: return false; } } diff --git a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp index 32f8269ae..47267f21d 100644 --- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp +++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp @@ -90,12 +90,8 @@ bool VM_G1IncCollectionPause::doit_prologue() { void VM_G1IncCollectionPause::doit() { G1CollectedHeap* g1h = G1CollectedHeap::heap(); - assert(!_should_initiate_conc_mark || - ((_gc_cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || - (_gc_cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent) || - _gc_cause == GCCause::_g1_humongous_allocation || - _gc_cause == GCCause::_update_allocation_context_stats_inc), - "only a GC locker, a System.gc(), stats update or a hum allocation induced GC should start a cycle"); + assert(!_should_initiate_conc_mark || g1h->should_do_concurrent_full_gc(_gc_cause), + "only a GC locker, a System.gc(), stats update, whitebox, or a hum allocation induced GC should start a cycle"); if (_word_size > 0) { // An allocation has been requested. So, try to do that first. diff --git a/src/share/vm/gc_interface/gcCause.cpp b/src/share/vm/gc_interface/gcCause.cpp index 4778d8aa4..a364214bd 100644 --- a/src/share/vm/gc_interface/gcCause.cpp +++ b/src/share/vm/gc_interface/gcCause.cpp @@ -54,6 +54,9 @@ const char* GCCause::to_string(GCCause::Cause cause) { case _wb_young_gc: return "WhiteBox Initiated Young GC"; + case _wb_conc_mark: + return "WhiteBox Initiated Concurrent Mark"; + case _update_allocation_context_stats_inc: case _update_allocation_context_stats_full: return "Update Allocation Context Stats"; diff --git a/src/share/vm/gc_interface/gcCause.hpp b/src/share/vm/gc_interface/gcCause.hpp index cb8dddd5c..26ad48f73 100644 --- a/src/share/vm/gc_interface/gcCause.hpp +++ b/src/share/vm/gc_interface/gcCause.hpp @@ -47,6 +47,7 @@ class GCCause : public AllStatic { _heap_inspection, _heap_dump, _wb_young_gc, + _wb_conc_mark, _update_allocation_context_stats_inc, _update_allocation_context_stats_full, diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp index ddf702d20..ef1da19d2 100644 --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -45,6 +45,7 @@ #if INCLUDE_ALL_GCS #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" #include "gc_implementation/g1/concurrentMark.hpp" +#include "gc_implementation/g1/concurrentMarkThread.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp" #endif // INCLUDE_ALL_GCS @@ -323,8 +324,16 @@ WB_END WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o)) G1CollectedHeap* g1 = G1CollectedHeap::heap(); - ConcurrentMark* cm = g1->concurrent_mark(); - return cm->concurrent_marking_in_progress(); + return g1->concurrent_mark()->cmThread()->during_cycle(); +WB_END + +WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o)) + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + if (!g1h->concurrent_mark()->cmThread()->during_cycle()) { + g1h->collect(GCCause::_wb_conc_mark); + return true; + } + return false; WB_END WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o)) @@ -1031,6 +1040,7 @@ static JNINativeMethod methods[] = { {CC"g1NumMaxRegions", CC"()J", (void*)&WB_G1NumMaxRegions }, {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions }, {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize }, + {CC"g1StartConcMarkCycle", CC"()Z", (void*)&WB_G1StartMarkCycle }, {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;", (void*)&WB_G1AuxiliaryMemoryUsage }, #endif // INCLUDE_ALL_GCS diff --git a/test/gc/whitebox/TestConcMarkCycleWB.java b/test/gc/whitebox/TestConcMarkCycleWB.java new file mode 100644 index 000000000..2d97bc739 --- /dev/null +++ b/test/gc/whitebox/TestConcMarkCycleWB.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test TestConMarkCycleWB + * @bug 8065579 + * @requires vm.gc=="null" | vm.gc=="G1" + * @library /testlibrary /testlibrary/whitebox + * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestConcMarkCycleWB + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC TestConcMarkCycleWB + * @summary Verifies that ConcurrentMarking-related WB works properly + */ +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import sun.hotspot.WhiteBox; + +public class TestConcMarkCycleWB { + + public static void main(String[] args) throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + + wb.youngGC(); + assertTrue(wb.g1StartConcMarkCycle()); + while (wb.g1InConcurrentMark()) { + Thread.sleep(5); + } + + wb.fullGC(); + assertTrue(wb.g1StartConcMarkCycle()); + while (wb.g1InConcurrentMark()) { + Thread.sleep(5); + } + assertTrue(wb.g1StartConcMarkCycle()); + } +} diff --git a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java index c5651fee2..99bb67000 100644 --- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java @@ -174,12 +174,16 @@ public class WhiteBox { public native long incMetaspaceCapacityUntilGC(long increment); public native long metaspaceCapacityUntilGC(); - // force Young GC + // Force Young GC public native void youngGC(); - // force Full GC + // Force Full GC public native void fullGC(); + // Method tries to start concurrent mark cycle. + // It returns false if CM Thread is always in concurrent cycle. + public native boolean g1StartConcMarkCycle(); + // Tests on ReservedSpace/VirtualSpace classes public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations); public native void runMemoryUnitTests(); -- GitLab