1 /* 2 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package gc.shenandoah.generational; 26 27 import jdk.test.whitebox.WhiteBox; 28 import java.util.Random; 29 import java.util.HashMap; 30 31 /* 32 * To avoid the risk of false regressions identified by this test, the heap 33 * size is set artificially high. Though this test is known to run reliably 34 * in 66 MB heap, the heap size for this test run is currently set to 256 MB. 35 */ 36 37 /* 38 * @test id=generational 39 * @requires vm.gc.Shenandoah 40 * @summary Confirm that card marking and remembered set scanning do not crash. 41 * @library /testlibrary /test/lib / 42 * @build jdk.test.whitebox.WhiteBox 43 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 44 * @run main/othervm -Xbootclasspath/a:. 45 * -Xms256m -Xmx256m 46 * -XX:+IgnoreUnrecognizedVMOptions 47 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 48 * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational 49 * -XX:NewRatio=1 -XX:+UnlockExperimentalVMOptions 50 * -XX:ShenandoahGuaranteedGCInterval=3000 51 * -XX:-UseDynamicNumberOfGCThreads -XX:-ShenandoahPacing 52 * gc.shenandoah.generational.TestConcurrentEvac 53 */ 54 55 public class TestConcurrentEvac { 56 private static WhiteBox wb = WhiteBox.getWhiteBox(); 57 58 private static final int RANDOM_SEED = 46; 59 60 // Smaller table will cause creation of more old-gen garbage 61 // as previous entries in table are overwritten with new values. 62 private static final int TABLE_SIZE = 53; 63 private static final int MAX_STRING_LENGTH = 47; 64 private static final int SENTENCE_LENGTH = 5; 65 66 private static Random random = new Random(RANDOM_SEED); 67 68 public static class Node { 69 70 private String name; 71 72 // Each Node instance holds an array containing all substrings of its name 73 74 // This array has entries from 0 .. (name.length() - 1). 75 // numSubstrings[i] represents the number of substrings that 76 // correspond to a name of length i+1. 77 private static int [] numSubstrings; 78 79 static { 80 // Initialize numSubstrings. 81 // For a name of length N, there are 82 // N substrings of length 1 83 // N-1 substrings of length 2 84 // N-2 substrings of length 3 85 // ... 86 // 1 substring of length N 87 // Note that: 88 // numSubstrings[0] = 1 89 // numSubstrings[1] = 3 90 // numSubstrings[i] = (i + 1) + numSubstrings[i - 1] 91 numSubstrings = new int[MAX_STRING_LENGTH]; 92 numSubstrings[0] = 1; 93 for (int i = 1; i < MAX_STRING_LENGTH; i++) { 94 numSubstrings[i] = (i + 1) + numSubstrings[i - 1]; 95 } 96 } 97 98 private String [] substrings; 99 private Node [] neighbors; 100 101 public Node(String name) { 102 this.name = name; 103 this.substrings = new String[numSubstrings[name.length() - 1]]; 104 105 int index = 0; 106 for (int substringLength = 1; substringLength <= name.length(); substringLength++) { 107 for (int offset = 0; offset + substringLength <= name.length(); offset++) { 108 this.substrings[index++] = name.substring(offset, offset + substringLength); 109 } 110 } 111 } 112 113 public String value() { 114 return name; 115 } 116 117 public String arbitrarySubstring() { 118 int index = TestConcurrentEvac.randomUnsignedInt(substrings.length); 119 return substrings[index]; 120 } 121 } 122 123 124 // Return random int between 1 and MAX_STRING_LENGTH inclusive 125 static int randomStringLength() { 126 return randomUnsignedInt(MAX_STRING_LENGTH - 1) + 1; 127 } 128 129 static String randomCharacter() { 130 int index = randomUnsignedInt(52); 131 return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".substring(index, index + 1); 132 } 133 134 static String randomString() { 135 int length = randomStringLength(); 136 String result = new String(); // make the compiler work for this garbage... 137 for (int i = 0; i < length; i++) { 138 result += randomCharacter(); 139 } 140 return result; 141 } 142 143 static int randomUnsignedInt(int max) { 144 return random.nextInt(max); 145 } 146 147 static int randomIndex() { 148 return randomUnsignedInt(TABLE_SIZE); 149 } 150 151 public static void main(String args[]) throws Exception { 152 HashMap<Integer, Node> table = new HashMap<Integer, Node>(TABLE_SIZE); 153 154 if (!wb.getBooleanVMFlag("UseShenandoahGC") || !wb.getStringVMFlag("ShenandoahGCMode").equals("generational")) { 155 throw new IllegalStateException("Command-line options not honored!"); 156 } 157 158 for (int count = java.lang.Integer.MAX_VALUE/1024; count >= 0; count--) { 159 int index = randomIndex(); 160 String name = randomString(); 161 table.put(index, new Node(name)); 162 } 163 164 String conclusion = ""; 165 166 for (int i = 0; i < SENTENCE_LENGTH; i++) { 167 Node node = table.get(randomIndex()); 168 if (node == null) { 169 i--; 170 } else { 171 String s = node.arbitrarySubstring(); 172 conclusion += s; 173 conclusion += " "; 174 } 175 } 176 177 conclusion = conclusion.substring(0, conclusion.length() - 1); 178 179 System.out.println("Conclusion is [" + conclusion + "]"); 180 181 if (!conclusion.equals("HN TInkzoLSDFVJYM mQAirHXbbgCJmUWozx DeispxWF MYFKBh")) { 182 throw new IllegalStateException("Random sequence of words did not end well!"); 183 } 184 } 185 }