Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/test/gc/shenandoah/compiler/TestUnsafeOffheapSwap.java
32285 views
/*1* Copyright (c) 2019, 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*/2223/**24* @test TestUnsafeOffheapSwap25* @summary Miscompilation in Unsafe off-heap swap routines26* @key gc27*28* @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation29* -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC30* TestUnsafeOffheapSwap31*/3233import java.util.*;34import java.lang.reflect.*;35import sun.misc.Unsafe;3637public class TestUnsafeOffheapSwap {3839static final int SIZE = 10000;40static final long SEED = 1;4142static final sun.misc.Unsafe UNSAFE;43static final int SCALE;4445static {46try {47Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");48f.setAccessible(true);49UNSAFE = (sun.misc.Unsafe) f.get(null);50SCALE = UNSAFE.ARRAY_INT_INDEX_SCALE;51} catch (Exception e) {52throw new RuntimeException("Unable to get Unsafe instance.", e);53}54}5556static Memory mem;57static int[] arr;5859public static void main(String[] args) throws Exception {60// Bug is exposed when memory.addr is not known statically61mem = new Memory(SIZE*SCALE);62arr = new int[SIZE];6364for (int i = 0; i < 10; i++) {65test();66}67}6869static void test() {70Random rnd = new Random(SEED);71for (int i = 0; i < SIZE; i++) {72int value = rnd.nextInt();73mem.setInt(i, value);74arr[i] = value;75}7677for (int i = 0; i < SIZE; i++) {78if (arr[i] != mem.getInt(i)) {79throw new IllegalStateException("TESTBUG: Values mismatch before swaps");80}81}8283for (int i = 1; i < SIZE; i++) {84mem.swap(i - 1, i);85int tmp = arr[i - 1];86arr[i - 1] = arr[i];87arr[i] = tmp;88}8990for (int i = 0; i < SIZE; i++) {91if (arr[i] != mem.getInt(i)) {92throw new IllegalStateException("Values mismatch after swaps");93}94}95}9697static class Memory {98private final long addr;99100Memory(int size) {101addr = UNSAFE.allocateMemory(size);102}103104public int getInt(int idx) {105return UNSAFE.getInt(addr + idx*SCALE);106}107108public void setInt(int idx, int val) {109UNSAFE.putInt(addr + idx*SCALE, val);110}111112public void swap(int a, int b) {113int tmp = getInt(a);114setInt(a, getInt(b));115setInt(b, tmp);116}117}118}119120121