Path: blob/master/test/hotspot/jtreg/gc/shenandoah/jni/TestStringCriticalWithDedup.java
64507 views
/*1* Copyright (c) 2021, Red Hat, Inc. 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*22*/2324/* @test TestStringCriticalWithDedup25* @summary Test string deduplication should not cause string critical to crash VM26* @requires vm.gc.Shenandoah27* @modules java.base/java.lang:open28*29* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m30* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+UseStringDeduplication -XX:-CompactStrings31* -XX:+ShenandoahVerify -XX:+ShenandoahDegeneratedGC -XX:ShenandoahTargetNumRegions=409632* TestStringCriticalWithDedup33*34* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m35* -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive -XX:+UseStringDeduplication -XX:-CompactStrings36* -XX:+ShenandoahVerify -XX:-ShenandoahDegeneratedGC -XX:ShenandoahTargetNumRegions=409637* TestStringCriticalWithDedup38*/3940/* @test TestPinnedGarbage41* @summary Test string deduplication should not cause string critical to crash VM42* @requires vm.gc.Shenandoah43* @modules java.base/java.lang:open44*45* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx512m46* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -XX:+UseStringDeduplication -XX:-CompactStrings47* -XX:ShenandoahTargetNumRegions=409648* TestStringCriticalWithDedup49*50* @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx256m51* -XX:+UseShenandoahGC -XX:+UseStringDeduplication -XX:-CompactStrings52* -XX:ShenandoahTargetNumRegions=4096 -XX:+ShenandoahVerify53* TestStringCriticalWithDedup54*/5556import java.util.List;57import java.util.ArrayList;58import java.util.concurrent.*;59import java.lang.reflect.*;6061public class TestStringCriticalWithDedup {62private static Field valueField;6364static {65System.loadLibrary("TestStringCriticalWithDedup");66try {67valueField = String.class.getDeclaredField("value");68valueField.setAccessible(true);69} catch (Exception e) {70throw new RuntimeException(e);71}72}7374private static final int NUM_RUNS = 100;75private static final int STRING_COUNT = 1 << 16;76private static final int LITTLE_GARBAGE_COUNT = 1 << 5;77private static final int PINNED_STRING_COUNT = 1 << 4;7879private static native long pin(String s);80private static native void unpin(String s, long p);818283private static volatile MyClass sink;84public static void main(String[] args) {85ThreadLocalRandom rng = ThreadLocalRandom.current();86for (int i = 0; i < NUM_RUNS; i++) {87test(rng);88}89}9091private static Object getValue(String string) {92try {93return valueField.get(string);94} catch (Exception e) {95throw new RuntimeException(e);96}97}9899private static void pissiblePinString(ThreadLocalRandom rng, List<Tuple> pinnedList, String s) {100int oneInCounter = STRING_COUNT / PINNED_STRING_COUNT;101if (rng.nextInt(oneInCounter) == 1) {102long v = pin(s);103Object value = getValue(s);104pinnedList.add(new Tuple(s, value, v));105}106}107108private static void test(ThreadLocalRandom rng) {109String[] strArray = new String[STRING_COUNT];110List<Tuple> pinnedStrings = new ArrayList<>(PINNED_STRING_COUNT);111for (int i = 0; i < STRING_COUNT; i++) {112// Create some garbage inbetween, so strings can be scattered in113// different regions114createLittleGarbage(rng);115116strArray[i] = new String("Hello" + (i % 10));117pissiblePinString(rng, pinnedStrings, strArray[i]);118}119120// Let deduplication thread to run a bit121try {122Thread.sleep(10);123} catch(Exception e) {124}125126for (int i = 0; i < pinnedStrings.size(); i ++) {127Tuple p = pinnedStrings.get(i);128String s = p.getString();129if (getValue(s) != p.getValue()) {130System.out.println(getValue(s) + " != " + p.getValue());131throw new RuntimeException("String value should be pinned");132}133unpin(p.getString(), p.getValuePointer());134}135}136137private static void createLittleGarbage(ThreadLocalRandom rng) {138int count = rng.nextInt(LITTLE_GARBAGE_COUNT);139for (int index = 0; index < count; index ++) {140sink = new MyClass();141}142}143144private static class Tuple {145String s;146Object value;147long valuePointer;148public Tuple(String s, Object value, long vp) {149this.s = s;150this.value = value;151this.valuePointer = vp;152}153154public String getString() {155return s;156}157public Object getValue() { return value; }158public long getValuePointer() {159return valuePointer;160}161}162163private static class MyClass {164public long[] payload = new long[10];165}166}167168169