Path: blob/master/test/hotspot/jtreg/gc/shenandoah/TestReferenceRefersToShenandoah.java
40942 views
/*1* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package gc.shenandoah;2425/* @test26* @requires vm.gc.Shenandoah27* @library /test/lib28* @build sun.hotspot.WhiteBox29* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox30* @run main/othervm31* -Xbootclasspath/a:.32* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI33* -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=satb34* gc.shenandoah.TestReferenceRefersToShenandoah35*/3637/* @test38* @requires vm.gc.Shenandoah39* @library /test/lib40* @build sun.hotspot.WhiteBox41* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox42* @run main/othervm43* -Xbootclasspath/a:.44* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI45* -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu46* gc.shenandoah.TestReferenceRefersToShenandoah47*/4849/* @test50* @requires vm.gc.Shenandoah51* @library /test/lib52* @build sun.hotspot.WhiteBox53* @modules java.base54* @run main jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox55* @run main/othervm56* -Xbootclasspath/a:.57* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI58* -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=satb -XX:ShenandoahGarbageThreshold=100 -Xmx100m59* gc.shenandoah.TestReferenceRefersToShenandoah60*/6162/* @test63* @requires vm.gc.Shenandoah64* @library /test/lib65* @build sun.hotspot.WhiteBox66* @modules java.base67* @run main jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox68* @run main/othervm69* -Xbootclasspath/a:.70* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI71* -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGarbageThreshold=100 -Xmx100m72* gc.shenandoah.TestReferenceRefersToShenandoah73*/7475import java.lang.ref.PhantomReference;76import java.lang.ref.Reference;77import java.lang.ref.ReferenceQueue;78import java.lang.ref.WeakReference;79import sun.hotspot.WhiteBox;8081public class TestReferenceRefersToShenandoah {82private static final WhiteBox WB = WhiteBox.getWhiteBox();8384private static final class TestObject {85public final int value;8687public TestObject(int value) {88this.value = value;89}90}9192private static volatile TestObject testObjectNone = null;93private static volatile TestObject testObject1 = null;94private static volatile TestObject testObject2 = null;95private static volatile TestObject testObject3 = null;96private static volatile TestObject testObject4 = null;9798private static ReferenceQueue<TestObject> queue = null;99100private static PhantomReference<TestObject> testPhantom1 = null;101102private static WeakReference<TestObject> testWeak2 = null;103private static WeakReference<TestObject> testWeak3 = null;104private static WeakReference<TestObject> testWeak4 = null;105106private static void setup() {107testObjectNone = new TestObject(0);108testObject1 = new TestObject(1);109testObject2 = new TestObject(2);110testObject3 = new TestObject(3);111testObject4 = new TestObject(4);112113queue = new ReferenceQueue<TestObject>();114115testPhantom1 = new PhantomReference<TestObject>(testObject1, queue);116117testWeak2 = new WeakReference<TestObject>(testObject2, queue);118testWeak3 = new WeakReference<TestObject>(testObject3, queue);119testWeak4 = new WeakReference<TestObject>(testObject4, queue);120}121122private static void gcUntilOld(Object o) throws Exception {123if (!WB.isObjectInOldGen(o)) {124WB.fullGC();125if (!WB.isObjectInOldGen(o)) {126fail("object not promoted by full gc");127}128}129}130131private static void gcUntilOld() throws Exception {132gcUntilOld(testObjectNone);133gcUntilOld(testObject1);134gcUntilOld(testObject2);135gcUntilOld(testObject3);136gcUntilOld(testObject4);137138gcUntilOld(testPhantom1);139140gcUntilOld(testWeak2);141gcUntilOld(testWeak3);142gcUntilOld(testWeak4);143}144145private static void progress(String msg) {146System.out.println(msg);147}148149private static void fail(String msg) throws Exception {150throw new RuntimeException(msg);151}152153private static void expectCleared(Reference<TestObject> ref,154String which) throws Exception {155expectNotValue(ref, testObjectNone, which);156if (!ref.refersTo(null)) {157fail("expected " + which + " to be cleared");158}159}160161private static void expectNotCleared(Reference<TestObject> ref,162String which) throws Exception {163expectNotValue(ref, testObjectNone, which);164if (ref.refersTo(null)) {165fail("expected " + which + " to not be cleared");166}167}168169private static void expectValue(Reference<TestObject> ref,170TestObject value,171String which) throws Exception {172expectNotValue(ref, testObjectNone, which);173expectNotCleared(ref, which);174if (!ref.refersTo(value)) {175fail(which + " doesn't refer to expected value");176}177}178179private static void expectNotValue(Reference<TestObject> ref,180TestObject value,181String which) throws Exception {182if (ref.refersTo(value)) {183fail(which + " refers to unexpected value");184}185}186187private static void checkInitialStates() throws Exception {188expectValue(testPhantom1, testObject1, "testPhantom1");189expectValue(testWeak2, testObject2, "testWeak2");190expectValue(testWeak3, testObject3, "testWeak3");191expectValue(testWeak4, testObject4, "testWeak4");192}193194private static void discardStrongReferences() {195// testObjectNone not dropped196testObject1 = null;197testObject2 = null;198// testObject3 not dropped199testObject4 = null;200}201202private static boolean isShenandoahIUMode() {203return "iu".equals(WB.getStringVMFlag("ShenandoahGCMode"));204}205206private static void testConcurrentCollection() throws Exception {207progress("setup concurrent collection test");208setup();209progress("gcUntilOld");210gcUntilOld();211212progress("acquire control of concurrent cycles");213WB.concurrentGCAcquireControl();214try {215progress("check initial states");216checkInitialStates();217218progress("discard strong references");219discardStrongReferences();220221progress("run GC to before marking completed");222WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED);223224progress("fetch test objects, possibly keeping some alive");225expectNotCleared(testPhantom1, "testPhantom1");226expectNotCleared(testWeak2, "testWeak2");227expectValue(testWeak3, testObject3, "testWeak3");228229// For some collectors, calling get() will keep testObject4 alive.230if (testWeak4.get() == null) {231fail("testWeak4 unexpectedly == null");232}233234progress("finish collection");235WB.concurrentGCRunToIdle();236237progress("verify expected clears");238expectCleared(testPhantom1, "testPhantom1");239expectCleared(testWeak2, "testWeak2");240expectValue(testWeak3, testObject3, "testWeak3");241// This is true for all currently supported concurrent collectors,242// except Shenandoah+IU, which allows clearing refs even when243// accessed during concurrent marking.244if (isShenandoahIUMode()) {245expectCleared(testWeak4, "testWeak4");246} else {247expectNotCleared(testWeak4, "testWeak4");248}249250progress("verify get returns expected values");251if (testWeak2.get() != null) {252fail("testWeak2.get() != null");253}254255TestObject obj3 = testWeak3.get();256if (obj3 == null) {257fail("testWeak3.get() returned null");258} else if (obj3.value != 3) {259fail("testWeak3.get().value is " + obj3.value);260}261262TestObject obj4 = testWeak4.get();263if (!isShenandoahIUMode()) {264if (obj4 == null) {265fail("testWeak4.get() returned null");266} else if (obj4.value != 4) {267fail("testWeak4.get().value is " + obj4.value);268}269}270271progress("verify queue entries");272long timeout = 60000; // 1 minute of milliseconds.273while (true) {274Reference<? extends TestObject> ref = queue.remove(timeout);275if (ref == null) {276break;277} else if (ref == testPhantom1) {278testPhantom1 = null;279} else if (ref == testWeak2) {280testWeak2 = null;281} else if (ref == testWeak3) {282testWeak3 = null;283} else if (ref == testWeak4) {284testWeak4 = null;285} else {286fail("unexpected reference in queue");287}288}289if (testPhantom1 != null) {290fail("testPhantom1 not notified");291} else if (testWeak2 != null) {292fail("testWeak2 not notified");293} else if (testWeak3 == null) {294fail("testWeak3 notified");295} else if (testWeak4 == null) {296if (obj4 != null) {297fail("testWeak4 notified");298}299}300301} finally {302progress("release control of concurrent cycles");303WB.concurrentGCReleaseControl();304}305progress("finished concurrent collection test");306}307308private static void testSimpleCollection() throws Exception {309progress("setup simple collection test");310setup();311progress("gcUntilOld");312gcUntilOld();313314progress("check initial states");315checkInitialStates();316317progress("discard strong references");318TestObject tw4 = testWeak4.get(); // Keep testObject4 alive.319discardStrongReferences();320321progress("collect garbage");322WB.fullGC();323324progress("verify expected clears");325expectCleared(testPhantom1, "testPhantom1");326expectCleared(testWeak2, "testWeak2");327expectValue(testWeak3, testObject3, "testWeak3");328expectNotCleared(testWeak4, "testWeak4");329330progress("verify get returns expected values");331if (testWeak2.get() != null) {332fail("testWeak2.get() != null");333} else if (testWeak3.get() != testObject3) {334fail("testWeak3.get() is not expected value");335} else if (testWeak4.get() != tw4) {336fail("testWeak4.get() is not expected value");337}338339progress("finished simple collection test");340}341342public static void main(String[] args) throws Exception {343if (WB.supportsConcurrentGCBreakpoints()) {344testConcurrentCollection();345}346testSimpleCollection();347}348}349350351