Path: blob/master/test/hotspot/jtreg/gc/g1/TestFromCardCacheIndex.java
40942 views
/*1* Copyright (c) 2018, 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*/2223/*24* @test TestFromCardCacheIndex.java25* @bug 819648526* @summary Ensure that G1 does not miss a remembered set entry due to from card cache default value indices.27* @requires vm.gc.G128* @requires vm.debug29* @requires vm.bits != "32"30* @library /test/lib31* @modules java.base/jdk.internal.misc32* java.management33* @build sun.hotspot.WhiteBox34* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox35* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. -Xms20M -Xmx20M -XX:+UseCompressedOops -XX:G1HeapRegionSize=1M -XX:HeapBaseMinAddress=2199011721216 -XX:+UseG1GC -verbose:gc gc.g1.TestFromCardCacheIndex36*/37package gc.g1;3839import sun.hotspot.WhiteBox;4041/**42* Repeatedly tries to generate references from objects that contained a card with the same index43* of the from card cache default value.44*/45public class TestFromCardCacheIndex {46private static WhiteBox WB;4748// Shift value to calculate card indices from addresses.49private static final int CardSizeShift = 9;5051/**52* Returns the last address on the heap within the object.53*54* @param The Object array to get the last address from.55*/56private static long getObjectLastAddress(Object[] o) {57return WB.getObjectAddress(o) + WB.getObjectSize(o) - 1;58}5960/**61* Returns the (truncated) 32 bit card index for the given address.62*63* @param The address to get the 32 bit card index from.64*/65private static int getCardIndex32bit(long address) {66return (int)(address >> CardSizeShift);67}6869// The source arrays that are placed on the heap in old gen.70private static int numArrays = 7000;71private static int arraySize = 508;72// Size of a humongous byte array, a bit less than a 1M region. This makes sure73// that we always create a cross-region reference when referencing it.74private static int byteArraySize = 1024*1023;7576public static void main(String[] args) {77WB = sun.hotspot.WhiteBox.getWhiteBox();78for (int i = 0; i < 5; i++) {79runTest();80WB.fullGC();81}82}8384public static void runTest() {85System.out.println("Starting test");8687// Spray the heap with random object arrays in the hope that we get one88// at the proper place.89Object[][] arrays = new Object[numArrays][];90for (int i = 0; i < numArrays; i++) {91arrays[i] = new Object[arraySize];92}9394// Make sure that everything is in old gen.95WB.fullGC();9697// Find if we got an allocation at the right spot.98Object[] arrayWithCardMinus1 = findArray(arrays);99100if (arrayWithCardMinus1 == null) {101System.out.println("Array with card -1 not found. Trying again.");102return;103} else {104System.out.println("Array with card -1 found.");105}106107System.out.println("Modifying the last card in the array with a new object in a different region...");108// Create a target object that is guaranteed to be in a different region.109byte[] target = new byte[byteArraySize];110111// Modify the last entry of the object we found.112arrayWithCardMinus1[arraySize - 1] = target;113114target = null;115// Make sure that the dirty cards are flushed by doing a GC.116System.out.println("Doing a GC.");117WB.youngGC();118119System.out.println("The crash didn't reproduce. Trying again.");120}121122/**123* Finds an returns an array that contains a (32 bit truncated) card with value -1.124*/125private static Object[] findArray(Object[][] arrays) {126for (int i = 0; i < arrays.length; i++) {127Object[] target = arrays[i];128if (target == null) {129continue;130}131WB.getObjectAddress(target); // startAddress not used132final long lastAddress = getObjectLastAddress(target);133final int card = getCardIndex32bit(lastAddress);134if (card == -1) {135Object[] foundArray = target;136return foundArray;137}138}139return null;140}141}142143144145