8204199: Test fails after 8202670 Graal update jdk-11+17
authordlong
Wed, 06 Jun 2018 09:37:44 -0700
changeset 50431 64e4b1686141
parent 50430 6659a8f57d78
child 50432 3a91f09a46be
child 50485 e2acd1ba1ee5
8204199: Test fails after 8202670 Graal update Reviewed-by: thartmann, kvn
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndExchangeNode.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.jdk9.test/src/org/graalvm/compiler/replacements/jdk9/UnsafeReplacementsTest.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndExchangeNode.java	Wed Jun 06 08:32:08 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/UnsafeCompareAndExchangeNode.java	Wed Jun 06 09:37:44 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 package org.graalvm.compiler.nodes.java;
 
 import jdk.vm.ci.meta.JavaKind;
+import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
 import org.graalvm.compiler.nodes.NodeView;
@@ -55,8 +56,7 @@
     private final LocationIdentity locationIdentity;
 
     public UnsafeCompareAndExchangeNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, JavaKind valueKind, LocationIdentity locationIdentity) {
-        super(TYPE, expected.stamp(NodeView.DEFAULT).meet(newValue.stamp(NodeView.DEFAULT)));
-        assert expected.stamp(NodeView.DEFAULT).isCompatible(newValue.stamp(NodeView.DEFAULT));
+        super(TYPE, meetInputs(expected.stamp(NodeView.DEFAULT), newValue.stamp(NodeView.DEFAULT)));
         this.object = object;
         this.offset = offset;
         this.expected = expected;
@@ -65,6 +65,11 @@
         this.locationIdentity = locationIdentity;
     }
 
+    private static Stamp meetInputs(Stamp expected, Stamp newValue) {
+        assert expected.isCompatible(newValue);
+        return expected.unrestricted().meet(newValue.unrestricted());
+    }
+
     public ValueNode object() {
         return object;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.jdk9.test/src/org/graalvm/compiler/replacements/jdk9/UnsafeReplacementsTest.java	Wed Jun 06 08:32:08 2018 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.jdk9.test/src/org/graalvm/compiler/replacements/jdk9/UnsafeReplacementsTest.java	Wed Jun 06 09:37:44 2018 -0700
@@ -26,11 +26,15 @@
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import org.graalvm.compiler.api.test.Graal;
+import org.graalvm.compiler.core.phases.HighTier;
+import org.graalvm.compiler.options.OptionValues;
 import org.graalvm.compiler.replacements.test.MethodSubstitutionTest;
 import org.graalvm.compiler.runtime.RuntimeProvider;
 import org.graalvm.compiler.test.AddExports;
 import org.junit.Test;
 
+import java.lang.reflect.Field;
+
 @AddExports("java.base/jdk.internal.misc")
 public class UnsafeReplacementsTest extends MethodSubstitutionTest {
 
@@ -310,4 +314,200 @@
         test("unsafeGetAndSetLong");
         test("unsafeGetAndSetObject");
     }
+
+    public static void fieldInstance() {
+        JdkInternalMiscUnsafeAccessTestBoolean.testFieldInstance();
+    }
+
+    @Test
+    public void testFieldInstance() {
+        test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldInstance");
+    }
+
+    public static void array() {
+        JdkInternalMiscUnsafeAccessTestBoolean.testArray();
+    }
+
+    @Test
+    public void testArray() {
+        test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "array");
+    }
+
+    public static void fieldStatic() {
+        JdkInternalMiscUnsafeAccessTestBoolean.testFieldStatic();
+    }
+
+    @Test
+    public void testFieldStatic() {
+        test(new OptionValues(getInitialOptions(), HighTier.Options.Inline, false), "fieldStatic");
+    }
+
+    public static class JdkInternalMiscUnsafeAccessTestBoolean {
+        static final int ITERATIONS = 100000;
+
+        static final int WEAK_ATTEMPTS = 10;
+
+        static final long V_OFFSET;
+
+        static final Object STATIC_V_BASE;
+
+        static final long STATIC_V_OFFSET;
+
+        static final int ARRAY_OFFSET;
+
+        static final int ARRAY_SHIFT;
+
+        static {
+            try {
+                Field staticVField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("staticV");
+                STATIC_V_BASE = unsafe.staticFieldBase(staticVField);
+                STATIC_V_OFFSET = unsafe.staticFieldOffset(staticVField);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            try {
+                Field vField = UnsafeReplacementsTest.JdkInternalMiscUnsafeAccessTestBoolean.class.getDeclaredField("v");
+                V_OFFSET = unsafe.objectFieldOffset(vField);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            ARRAY_OFFSET = unsafe.arrayBaseOffset(boolean[].class);
+            int ascale = unsafe.arrayIndexScale(boolean[].class);
+            ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale);
+        }
+
+        static boolean staticV;
+
+        boolean v;
+
+        @BytecodeParserForceInline
+        public static void testFieldInstance() {
+            JdkInternalMiscUnsafeAccessTestBoolean t = new JdkInternalMiscUnsafeAccessTestBoolean();
+            for (int c = 0; c < ITERATIONS; c++) {
+                testAccess(t, V_OFFSET);
+            }
+        }
+
+        public static void testFieldStatic() {
+            for (int c = 0; c < ITERATIONS; c++) {
+                testAccess(STATIC_V_BASE, STATIC_V_OFFSET);
+            }
+        }
+
+        public static void testArray() {
+            boolean[] array = new boolean[10];
+            for (int c = 0; c < ITERATIONS; c++) {
+                for (int i = 0; i < array.length; i++) {
+                    testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET);
+                }
+            }
+        }
+
+        public static void assertEquals(Object seen, Object expected, String message) {
+            if (seen != expected) {
+                throw new AssertionError(message + " - seen: " + seen + ", expected: " + expected);
+            }
+        }
+
+        // Checkstyle: stop
+        @BytecodeParserForceInline
+        public static void testAccess(Object base, long offset) {
+            // Advanced compare
+            {
+                boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, true);
+                assertEquals(r, false, "success compareAndExchange boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "success compareAndExchange boolean value");
+            }
+
+            {
+                boolean r = unsafe.compareAndExchangeBoolean(base, offset, false, false);
+                assertEquals(r, true, "failing compareAndExchange boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "failing compareAndExchange boolean value");
+            }
+
+            {
+                boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false);
+                assertEquals(r, true, "success compareAndExchangeAcquire boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, false, "success compareAndExchangeAcquire boolean value");
+            }
+
+            {
+                boolean r = unsafe.compareAndExchangeBooleanAcquire(base, offset, true, false);
+                assertEquals(r, false, "failing compareAndExchangeAcquire boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, false, "failing compareAndExchangeAcquire boolean value");
+            }
+
+            {
+                boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, true);
+                assertEquals(r, false, "success compareAndExchangeRelease boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "success compareAndExchangeRelease boolean value");
+            }
+
+            {
+                boolean r = unsafe.compareAndExchangeBooleanRelease(base, offset, false, false);
+                assertEquals(r, true, "failing compareAndExchangeRelease boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "failing compareAndExchangeRelease boolean value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = unsafe.weakCompareAndSetBooleanPlain(base, offset, true, false);
+                }
+                assertEquals(success, true, "weakCompareAndSetPlain boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, false, "weakCompareAndSetPlain boolean value");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = unsafe.weakCompareAndSetBooleanAcquire(base, offset, false, true);
+                }
+                assertEquals(success, true, "weakCompareAndSetAcquire boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "weakCompareAndSetAcquire boolean");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = unsafe.weakCompareAndSetBooleanRelease(base, offset, true, false);
+                }
+                assertEquals(success, true, "weakCompareAndSetRelease boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, false, "weakCompareAndSetRelease boolean");
+            }
+
+            {
+                boolean success = false;
+                for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) {
+                    success = unsafe.weakCompareAndSetBoolean(base, offset, false, true);
+                }
+                assertEquals(success, true, "weakCompareAndSet boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "weakCompareAndSet boolean");
+            }
+
+            unsafe.putBoolean(base, offset, false);
+
+            // Compare set and get
+            {
+                boolean o = unsafe.getAndSetBoolean(base, offset, true);
+                assertEquals(o, false, "getAndSet boolean");
+                boolean x = unsafe.getBoolean(base, offset);
+                assertEquals(x, true, "getAndSet boolean value");
+            }
+
+        }
+        // Checkstyle: resume
+    }
 }