8293824: gc/whitebox/TestConcMarkCycleWB.java failed "RuntimeException: assertTrue: expected true, was false"
Reviewed-by: iwalulya, tschatzl
This commit is contained in:
parent
8254cbb21d
commit
b743519ba9
src/hotspot/share
test
hotspot/jtreg
gc
g1
TestGCLogMessages.javaTestHumongousRemsetsMatch.javaTestMixedGCLiveThreshold.javaTestNoEagerReclaimOfHumongousRegions.javaTestRegionLivenessPrint.javaTestRemarkCleanupMXBean.javaTestSkipRebuildRemsetPhase.javaTestVerifyGCType.java
humongousObjects
stress
testlibrary/g1
whitebox
runtime/ClassUnload
jdk/com/sun/management/GarbageCollectorMXBean
lib/jdk/test/whitebox
@ -388,6 +388,7 @@ G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h,
|
||||
_first_overflow_barrier_sync(),
|
||||
_second_overflow_barrier_sync(),
|
||||
|
||||
_completed_mark_cycles(0),
|
||||
_has_overflown(false),
|
||||
_concurrent(false),
|
||||
_has_aborted(false),
|
||||
@ -1010,11 +1011,19 @@ void G1ConcurrentMark::concurrent_cycle_start() {
|
||||
_g1h->trace_heap_before_gc(_gc_tracer_cm);
|
||||
}
|
||||
|
||||
void G1ConcurrentMark::concurrent_cycle_end() {
|
||||
uint G1ConcurrentMark::completed_mark_cycles() const {
|
||||
return Atomic::load(&_completed_mark_cycles);
|
||||
}
|
||||
|
||||
void G1ConcurrentMark::concurrent_cycle_end(bool mark_cycle_completed) {
|
||||
_g1h->collector_state()->set_clearing_bitmap(false);
|
||||
|
||||
_g1h->trace_heap_after_gc(_gc_tracer_cm);
|
||||
|
||||
if (mark_cycle_completed) {
|
||||
Atomic::inc(&_completed_mark_cycles, memory_order_relaxed);
|
||||
}
|
||||
|
||||
if (has_aborted()) {
|
||||
log_info(gc, marking)("Concurrent Mark Abort");
|
||||
_gc_tracer_cm->report_concurrent_mode_failure();
|
||||
|
@ -327,6 +327,9 @@ class G1ConcurrentMark : public CHeapObj<mtGC> {
|
||||
WorkerThreadsBarrierSync _first_overflow_barrier_sync;
|
||||
WorkerThreadsBarrierSync _second_overflow_barrier_sync;
|
||||
|
||||
// Number of completed mark cycles.
|
||||
volatile uint _completed_mark_cycles;
|
||||
|
||||
// This is set by any task, when an overflow on the global data
|
||||
// structures is detected
|
||||
volatile bool _has_overflown;
|
||||
@ -501,7 +504,7 @@ public:
|
||||
void concurrent_cycle_start();
|
||||
// Abandon current marking iteration due to a Full GC.
|
||||
bool concurrent_cycle_abort();
|
||||
void concurrent_cycle_end();
|
||||
void concurrent_cycle_end(bool mark_cycle_completed);
|
||||
|
||||
// Notifies marking threads to abort. This is a best-effort notification. Does not
|
||||
// guarantee or update any state after the call. Root region scan must not be
|
||||
@ -593,6 +596,8 @@ public:
|
||||
|
||||
inline bool do_yield_check();
|
||||
|
||||
uint completed_mark_cycles() const;
|
||||
|
||||
bool has_aborted() { return _has_aborted; }
|
||||
|
||||
void print_summary_info();
|
||||
|
@ -334,6 +334,6 @@ void G1ConcurrentMarkThread::concurrent_cycle_end(bool mark_cycle_completed) {
|
||||
G1CollectedHeap::heap()->increment_old_marking_cycles_completed(true /* concurrent */,
|
||||
mark_cycle_completed /* heap_examined */);
|
||||
|
||||
_cm->concurrent_cycle_end();
|
||||
_cm->concurrent_cycle_end(mark_cycle_completed);
|
||||
ConcurrentGCBreakpoints::notify_active_to_idle();
|
||||
}
|
||||
|
@ -497,16 +497,13 @@ WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
|
||||
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1InConcurrentMark: G1 GC is not enabled");
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))
|
||||
WB_ENTRY(jint, WB_G1CompletedConcurrentMarkCycles(JNIEnv* env, jobject o))
|
||||
if (UseG1GC) {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
if (!g1h->concurrent_mark()->cm_thread()->in_progress()) {
|
||||
g1h->collect(GCCause::_wb_conc_mark);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
G1ConcurrentMark* cm = g1h->concurrent_mark();
|
||||
return cm->completed_mark_cycles();
|
||||
}
|
||||
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1StartMarkCycle: G1 GC is not enabled");
|
||||
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1CompletedConcurrentMarkCycles: G1 GC is not enabled");
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
|
||||
@ -2533,13 +2530,13 @@ static JNINativeMethod methods[] = {
|
||||
#endif
|
||||
#if INCLUDE_G1GC
|
||||
{CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
|
||||
{CC"g1CompletedConcurrentMarkCycles", CC"()I", (void*)&WB_G1CompletedConcurrentMarkCycles},
|
||||
{CC"g1IsHumongous0", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
|
||||
{CC"g1BelongsToHumongousRegion0", CC"(J)Z", (void*)&WB_G1BelongsToHumongousRegion},
|
||||
{CC"g1BelongsToFreeRegion0", CC"(J)Z", (void*)&WB_G1BelongsToFreeRegion},
|
||||
{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"g1HasRegionsToUncommit", CC"()Z", (void*)&WB_G1HasRegionsToUncommit},
|
||||
{CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
|
||||
(void*)&WB_G1AuxiliaryMemoryUsage },
|
||||
|
@ -368,7 +368,7 @@ public class TestGCLogMessages {
|
||||
static class GCTestWithConcurrentStart {
|
||||
public static void main(String [] args) {
|
||||
jdk.test.whitebox.WhiteBox WB = jdk.test.whitebox.WhiteBox.getWhiteBox();
|
||||
WB.g1StartConcMarkCycle();
|
||||
WB.g1StartConcurrentGC();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,12 +65,7 @@ public class TestHumongousRemsetsMatch {
|
||||
}
|
||||
|
||||
wb.fullGC();
|
||||
|
||||
// Trigger a concurrent cycle and wait until the Remark pause
|
||||
wb.g1StartConcMarkCycle();
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(200);
|
||||
}
|
||||
wb.g1RunConcurrentGC();
|
||||
wb.youngGC(); // Trigger verification error.
|
||||
|
||||
System.out.println(lotsOfHumongousObjects + " " + alignmentFudge);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 2022, 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
|
||||
@ -135,12 +135,7 @@ public class TestMixedGCLiveThreshold {
|
||||
|
||||
// Memory objects have been promoted to old by full GC.
|
||||
// Concurrent cycle may select regions for rebuilding
|
||||
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
|
||||
|
||||
// Sleep to make sure concurrent cycle is done
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
wb.g1RunConcurrentGC();
|
||||
System.out.println(used);
|
||||
}
|
||||
|
||||
|
@ -78,10 +78,7 @@ public class TestNoEagerReclaimOfHumongousRegions {
|
||||
garbageAndRefList.clear();
|
||||
|
||||
// Run a concurrent mark cycle to mark all references but the static one as dead.
|
||||
wb.g1StartConcMarkCycle();
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
wb.g1RunConcurrentGC();
|
||||
|
||||
// Run a young collection to make sure humongous object still can't be eagerly reclaimed.
|
||||
wb.youngGC();
|
||||
|
@ -44,10 +44,7 @@ public class TestRegionLivenessPrint {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
WhiteBox wb = WhiteBox.getWhiteBox();
|
||||
// Run a concurrent mark cycle to trigger the liveness accounting log messages.
|
||||
wb.g1StartConcMarkCycle();
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
wb.g1RunConcurrentGC();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, Alibaba Group Holding Limited. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -39,11 +40,12 @@ package gc.g1;
|
||||
* gc.g1.TestRemarkCleanupMXBean
|
||||
*/
|
||||
|
||||
import static jdk.test.whitebox.WhiteBox.getWhiteBox;
|
||||
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
import jdk.test.whitebox.gc.GC;
|
||||
import gc.testlibrary.g1.MixedGCProvoker;
|
||||
|
||||
public class TestRemarkCleanupMXBean {
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -60,7 +62,7 @@ public class TestRemarkCleanupMXBean {
|
||||
}
|
||||
|
||||
long before = g1ConcGCBean.getCollectionCount();
|
||||
MixedGCProvoker.provokeConcMarkCycle();
|
||||
getWhiteBox().g1RunConcurrentGC();
|
||||
long after = g1ConcGCBean.getCollectionCount();
|
||||
|
||||
if (after >= before + 2) { // Must report a Remark and a Cleanup
|
||||
|
@ -67,13 +67,7 @@ public class TestSkipRebuildRemsetPhase {
|
||||
|
||||
// Memory objects have been promoted to old by full GC.
|
||||
// Concurrent cycle should not select any regions for rebuilding
|
||||
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
|
||||
|
||||
// Sleep to make sure concurrent cycle is done
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
wb.g1RunConcurrentGC();
|
||||
System.out.println(used);
|
||||
}
|
||||
|
||||
|
@ -273,22 +273,26 @@ public class TestVerifyGCType {
|
||||
partialFree(used);
|
||||
|
||||
used = alloc1M();
|
||||
wb.g1StartConcMarkCycle(); // concurrent-start, remark and cleanup
|
||||
partialFree(used);
|
||||
|
||||
// Sleep to make sure concurrent cycle is done
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
Thread.sleep(1000);
|
||||
wb.concurrentGCAcquireControl();
|
||||
try {
|
||||
wb.concurrentGCRunTo(wb.AFTER_MARKING_STARTED);
|
||||
partialFree(used);
|
||||
|
||||
wb.concurrentGCRunToIdle();
|
||||
|
||||
// Trigger two young GCs while preventing a new concurrent GC.
|
||||
// First will be young-prepare-mixed, second will be mixed.
|
||||
used = alloc1M();
|
||||
wb.youngGC(); // young-prepare-mixed
|
||||
partialFree(used);
|
||||
|
||||
used = alloc1M();
|
||||
wb.youngGC(); // mixed
|
||||
partialFree(used);
|
||||
} finally {
|
||||
wb.concurrentGCReleaseControl();
|
||||
}
|
||||
|
||||
// Trigger two young GCs, first will be young-prepare-mixed, second will be mixed.
|
||||
used = alloc1M();
|
||||
wb.youngGC(); // young-prepare-mixed
|
||||
partialFree(used);
|
||||
|
||||
used = alloc1M();
|
||||
wb.youngGC(); // mixed
|
||||
partialFree(used);
|
||||
}
|
||||
|
||||
private static Object[] alloc1M() {
|
||||
|
@ -126,9 +126,7 @@ public class TestHumongousClassLoader {
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1RunConcurrentGC();
|
||||
}
|
||||
},
|
||||
FULL_GC_MEMORY_PRESSURE {
|
||||
|
@ -79,9 +79,7 @@ public class TestObjectCollected {
|
||||
CMC {
|
||||
@Override
|
||||
public void provoke() {
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1RunConcurrentGC();
|
||||
}
|
||||
},
|
||||
FULL_GC_MEMORY_PRESSURE {
|
||||
|
@ -41,9 +41,7 @@ public enum GC {
|
||||
@Override
|
||||
public Runnable get() {
|
||||
return () -> {
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.g1RunConcurrentGC();
|
||||
};
|
||||
}
|
||||
|
||||
@ -67,13 +65,15 @@ public enum GC {
|
||||
@Override
|
||||
public Runnable get() {
|
||||
return () -> {
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
|
||||
WHITE_BOX.g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.concurrentGCAcquireControl();
|
||||
try {
|
||||
WHITE_BOX.youngGC();
|
||||
WHITE_BOX.youngGC();
|
||||
WHITE_BOX.concurrentGCRunTo(WHITE_BOX.AFTER_MARKING_STARTED);
|
||||
WHITE_BOX.concurrentGCRunToIdle();
|
||||
} finally {
|
||||
WHITE_BOX.concurrentGCReleaseControl();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -141,19 +141,18 @@ public enum GC {
|
||||
@Override
|
||||
public Runnable get() {
|
||||
return () -> {
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
|
||||
WHITE_BOX.g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
|
||||
WHITE_BOX.youngGC();
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
// Provoking Mixed GC
|
||||
WHITE_BOX.youngGC();// second evacuation pause will be mixed
|
||||
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||
WHITE_BOX.concurrentGCAcquireControl();
|
||||
try {
|
||||
WHITE_BOX.youngGC();
|
||||
WHITE_BOX.youngGC();
|
||||
WHITE_BOX.concurrentGCRunTo(WHITE_BOX.AFTER_MARKING_STARTED);
|
||||
WHITE_BOX.concurrentGCRunToIdle();
|
||||
WHITE_BOX.youngGC();
|
||||
// Provoking Mixed GC
|
||||
WHITE_BOX.youngGC();// second evacuation pause will be mixed
|
||||
} finally {
|
||||
WHITE_BOX.concurrentGCReleaseControl();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2022, 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
|
||||
@ -33,7 +33,7 @@ public final class GCTokens {
|
||||
|
||||
public static final String WB_INITIATED_YOUNG_GC = "Young (Normal) (WhiteBox Initiated Young GC)";
|
||||
public static final String WB_INITIATED_MIXED_GC = "Young (Mixed) (WhiteBox Initiated Young GC)";
|
||||
public static final String WB_INITIATED_CMC = "WhiteBox Initiated Concurrent Mark";
|
||||
public static final String WB_INITIATED_CMC = "WhiteBox Initiated Run to Breakpoint";
|
||||
public static final String FULL_GC = "Full (System.gc())";
|
||||
public static final String FULL_GC_MEMORY_PRESSURE = "WhiteBox Initiated Full GC";
|
||||
public static final String CMC = "Concurrent Mark)";
|
||||
|
@ -270,6 +270,9 @@ public class TestMultiThreadStressRSet {
|
||||
*/
|
||||
private static class Shifter extends Thread {
|
||||
|
||||
// Only one thread at a time can be controlling concurrent GC.
|
||||
static final Object concGCMonitor = new Object();
|
||||
static Shifter concGCController = null;
|
||||
final TestMultiThreadStressRSet boss;
|
||||
final int sleepTime;
|
||||
final int shift;
|
||||
@ -292,9 +295,28 @@ public class TestMultiThreadStressRSet {
|
||||
objs[j] = null;
|
||||
}
|
||||
}
|
||||
if (!WB.g1InConcurrentMark()) {
|
||||
// If no currently controlling thread and no concurrent GC
|
||||
// in progress, then claim control.
|
||||
synchronized (concGCMonitor) {
|
||||
if ((concGCController == null) && !WB.g1InConcurrentMark()) {
|
||||
concGCController = this;
|
||||
}
|
||||
}
|
||||
if (concGCController == this) {
|
||||
// If we've claimed control then take control, start a
|
||||
// concurrent GC, and release control and the claim,
|
||||
// letting the GC run to completion while we continue
|
||||
// doing work.
|
||||
System.out.println("%% start CMC");
|
||||
WB.g1StartConcMarkCycle();
|
||||
WB.concurrentGCAcquireControl();
|
||||
try {
|
||||
WB.concurrentGCRunTo(WB.AFTER_MARKING_STARTED, false);
|
||||
} finally {
|
||||
WB.concurrentGCReleaseControl();
|
||||
synchronized (concGCMonitor) {
|
||||
concGCController = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("%% CMC is already in progress");
|
||||
}
|
||||
|
@ -293,10 +293,7 @@ public class TestStressRSetCoarsening {
|
||||
if (pre > cur) {
|
||||
// Number of references went down.
|
||||
// Need to provoke recalculation of RSet.
|
||||
WB.g1StartConcMarkCycle();
|
||||
while (WB.g1InConcurrentMark()) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
WB.g1RunConcurrentGC(false);
|
||||
}
|
||||
|
||||
// To force the use of rememebered set entries we need to provoke a GC.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, 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
|
||||
@ -73,20 +73,12 @@ public class MixedGCProvoker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provoke a concurrent mark cycle, and wait for it to end.
|
||||
*/
|
||||
public static void provokeConcMarkCycle() {
|
||||
Helpers.waitTillCMCFinished(getWhiteBox(), 10);
|
||||
getWhiteBox().g1StartConcMarkCycle();
|
||||
Helpers.waitTillCMCFinished(getWhiteBox(), 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provoke at least one mixed gc by starting a marking cycle, waiting for its end and triggering two GCs.
|
||||
* Provoke at least one mixed gc by performing a concurrent collection
|
||||
* and triggering two GCs.
|
||||
* @param liveOldObjects The objects supposed to survive this marking cycle.
|
||||
*/
|
||||
public static void provokeMixedGC(List<byte[]> liveOldObjects) {
|
||||
provokeConcMarkCycle();
|
||||
getWhiteBox().g1RunConcurrentGC();
|
||||
getWhiteBox().youngGC(); // the "Prepare Mixed" gc
|
||||
getWhiteBox().youngGC(); // the "Mixed" gc
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*/
|
||||
|
||||
package gc.whitebox;
|
||||
|
||||
/*
|
||||
* @test TestConMarkCycleWB
|
||||
* @bug 8065579
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.compiler
|
||||
* java.management
|
||||
* jdk.internal.jvmstat/sun.jvmstat.monitor
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC gc.whitebox.TestConcMarkCycleWB
|
||||
* @summary Verifies that ConcurrentMarking-related WB works properly
|
||||
*/
|
||||
import static jdk.test.lib.Asserts.assertTrue;
|
||||
import jdk.test.whitebox.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());
|
||||
}
|
||||
}
|
@ -50,23 +50,9 @@ import jdk.test.lib.classloader.ClassUnloadCommon;
|
||||
public class UnloadTestWithVerifyDuringGC {
|
||||
private static final WhiteBox wb = WhiteBox.getWhiteBox();
|
||||
|
||||
private static void waitUntilConcMarkFinished() throws Exception {
|
||||
while (wb.g1InConcurrentMark()) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Got InterruptedException while waiting for concurrent mark to finish");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void triggerUnloadingWithConcurrentMark() throws Exception {
|
||||
// Try to unload classes using concurrent mark. First wait for any currently running concurrent
|
||||
// cycle.
|
||||
waitUntilConcMarkFinished();
|
||||
wb.g1StartConcMarkCycle();
|
||||
waitUntilConcMarkFinished();
|
||||
// Try to unload classes using concurrent mark.
|
||||
wb.g1RunConcurrentGC();
|
||||
}
|
||||
|
||||
private static String className = "test.Empty";
|
||||
|
@ -46,8 +46,8 @@ import com.sun.management.GcInfo;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.lang.reflect.Field;
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
import jdk.test.whitebox.gc.GC;
|
||||
import gc.testlibrary.g1.MixedGCProvoker;
|
||||
|
||||
public class GarbageCollectionNotificationContentTest {
|
||||
private static HashMap<String,GarbageCollectionNotificationInfo> listenerInvoked
|
||||
@ -106,7 +106,7 @@ public class GarbageCollectionNotificationContentTest {
|
||||
}
|
||||
// Trigger G1's concurrent mark
|
||||
if (GC.G1.isSelected()) {
|
||||
MixedGCProvoker.provokeConcMarkCycle();
|
||||
WhiteBox.getWhiteBox().g1RunConcurrentGC();
|
||||
}
|
||||
int wakeup = 0;
|
||||
synchronized(synchronizer) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2022, 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
|
||||
@ -46,8 +46,8 @@ import com.sun.management.GcInfo;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.lang.reflect.Field;
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
import jdk.test.whitebox.gc.GC;
|
||||
import gc.testlibrary.g1.MixedGCProvoker;
|
||||
|
||||
public class GarbageCollectionNotificationTest {
|
||||
private static HashMap<String,Boolean> listenerInvoked = new HashMap<String,Boolean>();
|
||||
@ -107,7 +107,7 @@ public class GarbageCollectionNotificationTest {
|
||||
}
|
||||
// Trigger G1's concurrent mark
|
||||
if (GC.G1.isSelected()) {
|
||||
MixedGCProvoker.provokeConcMarkCycle();
|
||||
WhiteBox.getWhiteBox().g1RunConcurrentGC();
|
||||
}
|
||||
int wakeup = 0;
|
||||
synchronized(synchronizer) {
|
||||
|
@ -165,7 +165,52 @@ public class WhiteBox {
|
||||
}
|
||||
|
||||
// G1
|
||||
|
||||
public native boolean g1InConcurrentMark();
|
||||
public native int g1CompletedConcurrentMarkCycles();
|
||||
|
||||
// Perform a complete concurrent GC cycle, using concurrent GC breakpoints.
|
||||
// Completes any in-progress cycle before performing the requested cycle.
|
||||
// Returns true if the cycle completed successfully. If the cycle was not
|
||||
// successful (e.g. it was aborted), then throws RuntimeException if
|
||||
// errorIfFail is true, returning false otherwise.
|
||||
public boolean g1RunConcurrentGC(boolean errorIfFail) {
|
||||
try {
|
||||
// Take control, waiting until any in-progress cycle completes.
|
||||
concurrentGCAcquireControl();
|
||||
int count = g1CompletedConcurrentMarkCycles();
|
||||
concurrentGCRunTo(AFTER_MARKING_STARTED, false);
|
||||
concurrentGCRunToIdle();
|
||||
if (count < g1CompletedConcurrentMarkCycles()) {
|
||||
return true;
|
||||
} else if (errorIfFail) {
|
||||
throw new RuntimeException("Concurrent GC aborted");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
concurrentGCReleaseControl();
|
||||
}
|
||||
}
|
||||
|
||||
public void g1RunConcurrentGC() {
|
||||
g1RunConcurrentGC(true);
|
||||
}
|
||||
|
||||
// Start a concurrent GC cycle, using concurrent GC breakpoints.
|
||||
// The concurrent GC will continue in parallel with the caller.
|
||||
// Completes any in-progress cycle before starting the requested cycle.
|
||||
public void g1StartConcurrentGC() {
|
||||
try {
|
||||
// Take control, waiting until any in-progress cycle completes.
|
||||
concurrentGCAcquireControl();
|
||||
concurrentGCRunTo(AFTER_MARKING_STARTED, false);
|
||||
} finally {
|
||||
// Release control, permitting the cycle to complete.
|
||||
concurrentGCReleaseControl();
|
||||
}
|
||||
}
|
||||
|
||||
public native boolean g1HasRegionsToUncommit();
|
||||
private native boolean g1IsHumongous0(Object o);
|
||||
public boolean g1IsHumongous(Object o) {
|
||||
@ -540,10 +585,6 @@ public class WhiteBox {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 readFromNoaccessArea();
|
||||
|
Loading…
x
Reference in New Issue
Block a user