8205694: AArch64: Add test to validate volatile load, store and CAS code generation
authoradinn
Thu, 28 Jun 2018 10:09:58 +0000
changeset 50874 551c340ca01a
parent 50873 ce53844224b6
child 50875 2217b2fc29ea
8205694: AArch64: Add test to validate volatile load, store and CAS code generation Summary: Implement tests to check volatile operations are translated to valid code Reviewed-by: aph, kvn, dpochepk
src/hotspot/cpu/aarch64/aarch64.ad
test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileCAS.java
test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileLoad.java
test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileStore.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatileLoad.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatileStore.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesCMS.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesCMSCondMark.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesG1.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesParallel.java
test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesSerial.java
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Thu Jun 28 11:37:02 2018 +0200
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Thu Jun 28 10:09:58 2018 +0000
@@ -1627,7 +1627,7 @@
   // which looks like this
   //
   //   MemBarRelease
-  //   MemBarCPUOrder_(leading)__________________
+  //  {MemBarCPUOrder}_(leading)_________________
   //     C |    M \       \\                   C \
   //       |       \    StoreN/P[mo_release]  CastP2X
   //       |    Bot \    /
@@ -1663,7 +1663,7 @@
   // The graph for a CAS varies slightly, the difference being
   // that the StoreN/P node is replaced by a CompareAndSwapP/N node
   // and the trailing MemBarVolatile by a MemBarCPUOrder +
-  // MemBarAcquire pair.
+  // MemBarAcquire pair (also the MemBarCPUOrder nodes are not optional).
   //
   //   MemBarRelease
   //   MemBarCPUOrder_(leading)_______________
@@ -1691,7 +1691,7 @@
   //          |  . . .  \  / Bot
   //          |       MergeMem
   //          |          |
-  //       {MemBarCPUOrder}
+  //        MemBarCPUOrder
   //        MemBarVolatile (trailing)
   //
   //
@@ -1716,7 +1716,8 @@
   // So with G1 the pre-write and releasing store subgraph looks like
   // this (the nested Ifs are omitted).
   //
-  //  MemBarRelease (leading)____________
+  //  MemBarRelease
+  // {MemBarCPUOrder}_(leading)___________
   //     C |  ||  M \   M \    M \  M \ . . .
   //       | LoadB   \  LoadL  LoadN   \
   //       | /        \                 \
@@ -1932,7 +1933,7 @@
   // the following 3 Mem flow subgraphs is present.
   //
   //   MemBarRelease
-  //   MemBarCPUOrder {leading}
+  //  {MemBarCPUOrder} {leading}
   //          |  \      . . .
   //          |  StoreN/P[mo_release]  . . .
   //          |   /
@@ -1961,7 +1962,7 @@
   //   MemBarAcquire {trailing}
   //
   // if the correct configuration is present returns the trailing
-  // membar otherwise NULL.
+  // or cardmark membar otherwise NULL.
   //
   // the input membar is expected to be either a cpuorder membar or a
   // release membar. in the latter case it should not have a cpu membar
@@ -2070,8 +2071,8 @@
           // for a volatile store this can be either a trailing membar
           // or a card mark membar. for a cas it must be a card mark
           // membar
-          assert(cas == NULL || is_card_mark_membar(mbar),
-                 "in CAS graph volatile membar must be a card mark");
+          guarantee(cas == NULL || is_card_mark_membar(mbar),
+                    "in CAS graph volatile membar must be a card mark");
 	} else if (cas != NULL && x->Opcode() == Op_MemBarAcquire) {
 	  mbar = x->as_MemBar();
 	}
@@ -2197,15 +2198,16 @@
       }
     }
 
-    // we should not have both a store and a cas
-    if (st == NULL & cas == NULL) {
+    // we cannot have both a store and a cas
+    if (st == NULL && cas == NULL) {
+      // we have neither -- this is not a normal graph
       return NULL;
     }
     if (st == NULL) {
       // if we started from a volatile membar and found a CAS then the
       // original membar ought to be for a card mark
-      assert((barrier_is_acquire || is_card_mark_membar(barrier)),
-             "unexpected volatile barrier (i.e. not card mark) in CAS graph");
+      guarantee((barrier_is_acquire || is_card_mark_membar(barrier)),
+                "unexpected volatile barrier (i.e. not card mark) in CAS graph");
       // check that the CAS feeds the merge we used to get here via an
       // intermediary SCMemProj
       Node *scmemproj = NULL;
@@ -2227,8 +2229,8 @@
       }
     } else {
       // we should not have found a store if we started from an acquire
-      assert(!barrier_is_acquire,
-             "unexpected trailing acquire barrier in volatile store graph");
+      guarantee(!barrier_is_acquire,
+                "unexpected trailing acquire barrier in volatile store graph");
 
       // the store should feed the merge we used to get here
       for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) {
@@ -2396,7 +2398,7 @@
     }
 
     // sanity check this feed turns up as the expected slice
-    assert(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge");
+    guarantee(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge");
 
     MemBarNode *trailing = NULL;
     // be sure we have a trailing membar fed by the merge
@@ -2831,8 +2833,8 @@
 
   // the barrier must be a cpuorder mmebar fed by a release membar
 
-  assert(barrier->Opcode() == Op_MemBarCPUOrder,
-	 "CAS not fed by cpuorder membar!");
+  guarantee(barrier->Opcode() == Op_MemBarCPUOrder,
+            "CAS not fed by cpuorder membar!");
 
   MemBarNode *b = parent_membar(barrier);
   assert ((b != NULL && b->Opcode() == Op_MemBarRelease),
@@ -2841,7 +2843,7 @@
   // does this lead a normal subgraph?
   MemBarNode *mbar = leading_to_normal(barrier);
 
-  assert(mbar != NULL, "CAS not embedded in normal graph!");
+  guarantee(mbar != NULL, "CAS not embedded in normal graph!");
 
   // if this is a card mark membar check we have a trailing acquire
 
@@ -2849,9 +2851,9 @@
     mbar = card_mark_to_trailing(mbar);
   }
 
-  assert(mbar != NULL, "card mark membar for CAS not embedded in normal graph!");
-
-  assert(mbar->Opcode() == Op_MemBarAcquire, "trailing membar should be an acquire");
+  guarantee(mbar != NULL, "card mark membar for CAS not embedded in normal graph!");
+
+  guarantee(mbar->Opcode() == Op_MemBarAcquire, "trailing membar should be an acquire");
 #endif // ASSERT
   // so we can just return true here
   return true;
@@ -2875,7 +2877,7 @@
   }
 
   // if we are implementing volatile puts using barriers then the
-  // object put as an str so we must insert the dmb ishst
+  // object put is an str so we must insert the dmb ishst
 
   if (UseBarriersForVolatile) {
     return false;
@@ -8400,7 +8402,8 @@
   predicate(unnecessary_storestore(n));
 
   ins_cost(INSN_COST);
-  format %{ "strb zr, $mem\t# byte" %}
+  format %{ "storestore (elided)\n\t"
+            "strb zr, $mem\t# byte" %}
 
   ins_encode(aarch64_enc_strb0(mem));
 
@@ -8414,8 +8417,9 @@
   match(Set mem (StoreCM mem zero));
 
   ins_cost(INSN_COST * 2);
-  format %{ "dmb ishst"
-      "\n\tstrb zr, $mem\t# byte" %}
+  format %{ "storestore\n\t"
+            "dmb ishst"
+            "\n\tstrb zr, $mem\t# byte" %}
 
   ins_encode(aarch64_enc_strb0_ordered(mem));
 
@@ -9193,7 +9197,8 @@
   match(MemBarAcquire);
   ins_cost(VOLATILE_REF_COST);
 
-  format %{ "membar_acquire" %}
+  format %{ "membar_acquire\n\t"
+            "dmb ish" %}
 
   ins_encode %{
     __ block_comment("membar_acquire");
@@ -9246,7 +9251,8 @@
   match(MemBarRelease);
   ins_cost(VOLATILE_REF_COST);
 
-  format %{ "membar_release" %}
+  format %{ "membar_release\n\t"
+            "dmb ish" %}
 
   ins_encode %{
     __ block_comment("membar_release");
@@ -9298,7 +9304,8 @@
   match(MemBarVolatile);
   ins_cost(VOLATILE_REF_COST*100);
 
-  format %{ "membar_volatile" %}
+  format %{ "membar_volatile\n\t"
+             "dmb ish"%}
 
   ins_encode %{
     __ block_comment("membar_volatile");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileCAS.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.c2.aarch64;
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+class TestUnsafeVolatileCAS
+{
+    public volatile int f_int = 0;
+    public volatile Integer f_obj = Integer.valueOf(0);
+
+    public static Unsafe unsafe = Unsafe.getUnsafe();
+    public static Field f_int_field;
+    public static Field f_obj_field;
+    public static long f_int_off;
+    public static long f_obj_off;
+
+    static {
+        try {
+            f_int_field = TestUnsafeVolatileCAS.class.getField("f_int");
+            f_obj_field = TestUnsafeVolatileCAS.class.getField("f_obj");
+            f_int_off = unsafe.objectFieldOffset(f_int_field);
+            f_obj_off = unsafe.objectFieldOffset(f_obj_field);
+        } catch (Exception e) {
+            System.out.println("reflection failed " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args)
+    {
+        final TestUnsafeVolatileCAS t = new TestUnsafeVolatileCAS();
+        for (int i = 0; i < 100_000; i++) {
+            t.f_int = -1;
+            t.testInt(-1, i);
+            if (t.f_int != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+        Integer minusOne = Integer.valueOf(-1);
+        for (int i = 0; i < 100_000; i++) {
+            t.f_obj = minusOne;
+            t.testObj(minusOne, Integer.valueOf(i));
+            if (t.f_obj != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+    }
+    public void testInt(int x, int i)
+    {
+        unsafe.compareAndSetInt(this, f_int_off, x, i);
+    }
+
+    public void testObj(Object x, Object o)
+    {
+        unsafe.compareAndSetObject(this, f_obj_off, x, o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileLoad.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,56 @@
+package compiler.c2.aarch64;
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+class TestUnsafeVolatileLoad
+{
+    public volatile int f_int = 0;
+    public volatile Integer f_obj = Integer.valueOf(0);
+
+    public static Unsafe unsafe = Unsafe.getUnsafe();
+    public static Field f_int_field;
+    public static Field f_obj_field;
+    public static long f_int_off;
+    public static long f_obj_off;
+
+    static {
+        try {
+            f_int_field = TestUnsafeVolatileLoad.class.getField("f_int");
+            f_obj_field = TestUnsafeVolatileLoad.class.getField("f_obj");
+            f_int_off = unsafe.objectFieldOffset(f_int_field);
+            f_obj_off = unsafe.objectFieldOffset(f_obj_field);
+        } catch (Exception e) {
+            System.out.println("reflection failed " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args)
+    {
+        final TestUnsafeVolatileLoad t = new TestUnsafeVolatileLoad();
+        for (int i = 0; i < 100_000; i++) {
+            t.f_int = i;
+            int r = t.testInt();
+            if (r != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+        for (int i = 0; i < 100_000; i++) {
+            t.f_obj = Integer.valueOf(i);
+            int r = t.testObj();
+            if (r != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+    }
+    public int testInt()
+    {
+        return unsafe.getIntVolatile(this, f_int_off);
+    }
+
+    public int testObj()
+    {
+        return ((Integer)unsafe.getObjectVolatile(this, f_obj_off));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestUnsafeVolatileStore.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.c2.aarch64;
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+class TestUnsafeVolatileStore
+{
+    public volatile int f_int = 0;
+    public volatile Integer f_obj = Integer.valueOf(0);
+
+    public static Unsafe unsafe = Unsafe.getUnsafe();
+    public static Field f_int_field;
+    public static Field f_obj_field;
+    public static long f_int_off;
+    public static long f_obj_off;
+
+    static {
+        try {
+            f_int_field = TestUnsafeVolatileStore.class.getField("f_int");
+            f_obj_field = TestUnsafeVolatileStore.class.getField("f_obj");
+            f_int_off = unsafe.objectFieldOffset(f_int_field);
+            f_obj_off = unsafe.objectFieldOffset(f_obj_field);
+        } catch (Exception e) {
+            System.out.println("reflection failed " + e);
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args)
+    {
+        final TestUnsafeVolatileStore t = new TestUnsafeVolatileStore();
+        for (int i = 0; i < 100_000; i++) {
+            t.f_int = -1;
+            t.testInt(i);
+            if (t.f_int != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+        for (int i = 0; i < 100_000; i++) {
+            t.f_obj = null;
+            t.testObj(Integer.valueOf(i));
+            if (t.f_obj != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+    }
+    public void testInt(int i)
+    {
+        unsafe.putIntVolatile(this, f_int_off, i);
+    }
+
+    public void testObj(Object o)
+    {
+        unsafe.putObjectVolatile(this, f_obj_off, o);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatileLoad.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.c2.aarch64;
+
+class TestVolatileLoad
+{
+    public volatile int f_int = 0;
+    public volatile Integer f_obj = Integer.valueOf(0);
+
+    public static void main(String[] args)
+    {
+        final TestVolatileLoad t = new TestVolatileLoad();
+        for (int i = 0; i < 100_000; i++) {
+            t.f_int = i;
+            int r = t.testInt();
+            if (r != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+        for (int i = 0; i < 100_000; i++) {
+            t.f_obj = Integer.valueOf(i);
+            int r = t.testObj();
+            if (r != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+    }
+    public int testInt()
+    {
+        return f_int;
+    }
+
+    public int testObj()
+    {
+        return f_obj;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatileStore.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.c2.aarch64;
+
+class TestVolatileStore
+{
+    public volatile int f_int = 0;
+    public volatile Integer f_obj = Integer.valueOf(0);
+
+    public static void main(String[] args)
+    {
+        final TestVolatileStore t = new TestVolatileStore();
+        for (int i = 0; i < 100_000; i++) {
+            t.f_int = -1;
+            t.testInt(i);
+            if (t.f_int != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+        for (int i = 0; i < 100_000; i++) {
+            t.f_obj = null;
+            t.testObj(Integer.valueOf(i));
+            if (t.f_obj != i) {
+                throw new RuntimeException("bad result!");
+            }
+        }
+    }
+    public void testInt(int i)
+    {
+        f_int = i;
+    }
+
+    public void testObj(Integer o)
+    {
+        f_obj = o;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * common code to run and validate tests of code generation for
+ * volatile ops on AArch64
+ *
+ * incoming args are <testclass> <testtype>
+ *
+ * where <testclass> in {TestVolatileLoad,
+ *                       TestVolatileStore,
+ *                       TestUnsafeVolatileLoad,
+ *                       TestUnsafeVolatileStore,
+ *                       TestUnsafeVolatileCAS}
+ * and <testtype> in {G1,
+ *                    CMS,
+ *                    CMSCondCardMark,
+ *                    Serial,
+ *                    Parallel}
+ */
+
+
+package compiler.c2.aarch64;
+
+import java.util.List;
+import java.util.Iterator;
+import java.io.*;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+// runner class that spawns a new JVM to exercises a combination of
+// volatile MemOp and GC. The ops are compiled with the dmb -->
+// ldar/stlr transforms either enabled or disabled. this runner parses
+// the PrintOptoAssembly output checking that the generated code is
+// correct.
+
+public class TestVolatiles {
+    public void runtest(String classname, String testType) throws Throwable {
+        // n.b. clients omit the package name for the class
+        String fullclassname = "compiler.c2.aarch64." + classname;
+        // build up a command line for the spawned JVM
+        String[] procArgs;
+        int argcount;
+        // add one or two extra arguments according to test type
+        // i.e. GC type plus GC conifg
+        switch(testType) {
+        case "G1":
+            argcount = 8;
+            procArgs = new String[argcount];
+            procArgs[argcount - 2] = "-XX:+UseG1GC";
+            break;
+        case "Parallel":
+            argcount = 8;
+            procArgs = new String[argcount];
+            procArgs[argcount - 2] = "-XX:+UseParallelGC";
+            break;
+        case "Serial":
+            argcount = 8;
+            procArgs = new String[argcount];
+            procArgs[argcount - 2] = "-XX:+UseSerialGC";
+            break;
+        case "CMS":
+            argcount = 9 ;
+            procArgs = new String[argcount];
+            procArgs[argcount - 3] = "-XX:+UseConcMarkSweepGC";
+            procArgs[argcount - 2] = "-XX:-UseCondCardMark";
+            break;
+        case "CMSCondMark":
+            argcount = 9 ;
+            procArgs = new String[argcount];
+            procArgs[argcount - 3] = "-XX:+UseConcMarkSweepGC";
+            procArgs[argcount - 2] = "-XX:+UseCondCardMark";
+            break;
+        default:
+            throw new RuntimeException("unexpected test type " + testType);
+        }
+
+        // fill in arguments common to all cases
+
+        // the first round of test enables transform of barriers to
+        // use acquiring loads and releasing stores by setting arg
+        // zero appropriately. this arg is reset in the second run to
+        // disable the transform.
+
+        procArgs[0] = "-XX:-UseBarriersForVolatile";
+
+        procArgs[1] = "-XX:-TieredCompilation";
+        procArgs[2] = "-XX:+PrintOptoAssembly";
+        procArgs[3] = "-XX:CompileCommand=compileonly," + fullclassname + "::" + "test*";
+        procArgs[4] = "--add-exports";
+        procArgs[5] = "java.base/jdk.internal.misc=ALL-UNNAMED";
+        procArgs[argcount - 1] = fullclassname;
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+        output.stderrShouldBeEmptyIgnoreVMWarnings();
+        output.stdoutShouldNotBeEmpty();
+        output.shouldHaveExitValue(0);
+
+        // check the output for the correct asm sequence as
+        // appropriate to test class, test type and whether transform
+        // was applied
+
+        checkoutput(output, classname, testType, false);
+
+        // rerun the test class without the transform applied and
+        // check the alternative generation is as expected
+
+        procArgs[0] = "-XX:+UseBarriersForVolatile";
+
+        pb = ProcessTools.createJavaProcessBuilder(procArgs);
+        output = new OutputAnalyzer(pb.start());
+
+        output.stderrShouldBeEmptyIgnoreVMWarnings();
+        output.stdoutShouldNotBeEmpty();
+        output.shouldHaveExitValue(0);
+
+        // again check the output for the correct asm sequence
+
+        checkoutput(output, classname, testType, true);
+    }
+
+    // skip through output returning a line containing the desireed
+    // substring or null
+    private String skipTo(Iterator<String> iter, String substring)
+    {
+        while (iter.hasNext()) {
+            String nextLine = iter.next();
+            if (nextLine.contains(substring)) {
+                return nextLine;
+            }
+        }
+        return null;
+    }
+
+    // locate the start of compiler output for the desired method and
+    // then check that each expected instruction occurs in the output
+    // in the order supplied. throw an excpetion if not found.
+    // n.b. the spawned JVM's output is included in the exception
+    // message to make it easeir to identify what is missing.
+
+    private void checkCompile(Iterator<String> iter, String methodname, String[] expected, OutputAnalyzer output)
+    {
+        // trace call to allow eyeball check of what we are checking against
+        System.out.println("checkCompile(" + methodname + ",");
+        String sepr = "  { ";
+        for (String s : expected) {
+            System.out.print(sepr);
+            System.out.print(s);
+            sepr = ",\n    ";
+        }
+        System.out.println(" })");
+
+        // look for the start of an opto assembly print block
+        String match = skipTo(iter, "{method}");
+        if (match == null) {
+            throw new RuntimeException("Missing compiler output for " + methodname + "!\n\n" + output.getOutput());
+        }
+        // check the compiled method name is right
+        match = skipTo(iter, "- name:");
+        if (match == null) {
+            throw new RuntimeException("Missing compiled method name!\n\n" + output.getOutput());
+        }
+        if (!match.contains(methodname)) {
+            throw new RuntimeException("Wrong method " + match + "!\n  -- expecting " + methodname + "\n\n" + output.getOutput());
+        }
+        // make sure we can match each expected term in order
+        for (String s : expected) {
+            match = skipTo(iter, s);
+            if (match == null) {
+                throw new RuntimeException("Missing expected output " + s + "!\n\n" + output.getOutput());
+            }
+        }
+    }
+
+    // check for expected asm output from a volatile load
+
+    private void checkload(OutputAnalyzer output, String testType, boolean useBarriersForVolatile) throws Throwable
+    {
+        Iterator<String> iter = output.asLines().listIterator();
+
+        // we shoud see this same sequence for normal or unsafe volatile load
+        // for both int and Object fields
+
+        String[] matches;
+
+        if (!useBarriersForVolatile) {
+            matches = new String[] {
+                "ldarw",
+                "membar_acquire (elided)",
+                "ret"
+            };
+        } else {
+            matches = new String[] {
+                "ldrw",
+                "membar_acquire",
+                "dmb ish",
+                "ret"
+            };
+        }
+
+        checkCompile(iter, "testInt", matches, output);
+
+        checkCompile(iter, "testObj", matches, output) ;
+
+    }
+
+    // check for expected asm output from a volatile store
+
+    private void checkstore(OutputAnalyzer output, String testType, boolean useBarriersForVolatile) throws Throwable
+    {
+        Iterator<String> iter = output.asLines().listIterator();
+
+        String[] matches;
+
+        // non object stores are straightforward
+        if (!useBarriersForVolatile) {
+            // this is the sequence of instructions for all cases
+            matches = new String[] {
+                "membar_release (elided)",
+                "stlrw",
+                "membar_volatile (elided)",
+                "ret"
+            };
+        } else {
+            // this is the alternative sequence of instructions
+            matches = new String[] {
+                "membar_release",
+                "dmb ish",
+                "strw",
+                "membar_volatile",
+                "dmb ish",
+                "ret"
+            };
+        }
+
+        checkCompile(iter, "testInt", matches, output);
+
+        // object stores will be as above except for when the GC
+        // introduces barriers for card marking
+
+        if (!useBarriersForVolatile) {
+            switch (testType) {
+            default:
+                // this is the basic sequence of instructions
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "stlrw",
+                    "membar_volatile (elided)",
+                    "ret"
+                };
+                break;
+            case "G1":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "stlrw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "strb",
+                    "membar_volatile (elided)",
+                    "ret"
+                };
+                break;
+            case "CMSCondCardMark":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "stlrw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_volatile (elided)",
+                    "ret"
+                };
+                break;
+            case "CMS":
+                // a volatile card mark membar should not be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "stlrw",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_volatile (elided)",
+                    "ret"
+                };
+                break;
+            }
+        } else {
+            switch (testType) {
+            default:
+                // this is the basic sequence of instructions
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "strw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "G1":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "strw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "strb",
+                    "membar_volatile",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "CMSCondCardMark":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "strw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_volatile",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "CMS":
+                // a volatile card mark membar should not be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be generated
+                // as "dmb ishst"
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "strw",
+                    "storestore",
+                    "dmb ishst",
+                    "strb",
+                    "membar_volatile",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            }
+        }
+
+        checkCompile(iter, "testObj", matches, output);
+    }
+
+    // check for expected asm output from a volatile cas
+
+    private void checkcas(OutputAnalyzer output, String testType, boolean useBarriersForVolatile) throws Throwable
+    {
+        Iterator<String> iter = output.asLines().listIterator();
+
+        String[] matches;
+
+        // non object stores are straightforward
+        if (!useBarriersForVolatile) {
+            // this is the sequence of instructions for all cases
+            matches = new String[] {
+                "membar_release (elided)",
+                "cmpxchgw_acq",
+                "membar_acquire (elided)",
+                "ret"
+            };
+        } else {
+            // this is the alternative sequence of instructions
+            matches = new String[] {
+                "membar_release",
+                "dmb ish",
+                "cmpxchgw",
+                "membar_acquire",
+                "dmb ish",
+                "ret"
+            };
+        }
+
+        checkCompile(iter, "testInt", matches, output);
+
+        // object stores will be as above except for when the GC
+        // introduces barriers for card marking
+
+        if (!useBarriersForVolatile) {
+            switch (testType) {
+            default:
+                // this is the basic sequence of instructions
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "cmpxchgw_acq",
+                    "strb",
+                    "membar_acquire (elided)",
+                    "ret"
+                };
+                break;
+            case "G1":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "cmpxchgw_acq",
+                    "membar_volatile",
+                    "dmb ish",
+                    "strb",
+                    "membar_acquire (elided)",
+                    "ret"
+                };
+                break;
+            case "CMSCondCardMark":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "cmpxchgw_acq",
+                    "membar_volatile",
+                    "dmb ish",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_acquire (elided)",
+                    "ret"
+                };
+                break;
+            case "CMS":
+                // a volatile card mark membar should not be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release (elided)",
+                    "cmpxchgw_acq",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_acquire (elided)",
+                    "ret"
+                };
+                break;
+            }
+        } else {
+            switch (testType) {
+            default:
+                // this is the basic sequence of instructions
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "cmpxchgw",
+                    "membar_acquire",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "G1":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "cmpxchgw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "strb",
+                    "membar_acquire",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "CMSCondCardMark":
+                // a card mark volatile barrier should be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be elided
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "cmpxchgw",
+                    "membar_volatile",
+                    "dmb ish",
+                    "storestore (elided)",
+                    "strb",
+                    "membar_acquire",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            case "CMS":
+                // a volatile card mark membar should not be generated
+                // before the card mark strb from the StoreCM and the
+                // storestore barrier from the StoreCM should be generated
+                // as "dmb ishst"
+                matches = new String[] {
+                    "membar_release",
+                    "dmb ish",
+                    "cmpxchgw",
+                    "storestore",
+                    "dmb ishst",
+                    "strb",
+                    "membar_acquire",
+                    "dmb ish",
+                    "ret"
+                };
+                break;
+            }
+        }
+
+        checkCompile(iter, "testObj", matches, output);
+    }
+
+    // perform a check appropriate to the classname
+
+    private void checkoutput(OutputAnalyzer output, String classname, String testType, boolean useBarriersForVolatile) throws Throwable
+    {
+        // trace call to allow eyeball check of what is being checked
+        System.out.println("checkoutput(" +
+                           classname + ", " +
+                           testType + ", " +
+                           useBarriersForVolatile + ")\n" +
+                           output.getOutput());
+
+        switch (classname) {
+        case "TestVolatileLoad":
+            checkload(output, testType, useBarriersForVolatile);
+            break;
+        case "TestVolatileStore":
+            checkstore(output, testType, useBarriersForVolatile);
+            break;
+        case "TestUnsafeVolatileLoad":
+            checkload(output, testType, useBarriersForVolatile);
+            break;
+        case "TestUnsafeVolatileStore":
+            checkstore(output, testType, useBarriersForVolatile);
+            break;
+        case "TestUnsafeVolatileCAS":
+            checkcas(output, testType, useBarriersForVolatile);
+            break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesCMS.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary C2 should use ldar, stlr and ldaxr+stlxr insns for volatile operations
+ * @library /test/lib /
+ *
+ * @modules java.base/jdk.internal.misc
+ *
+ * @requires os.arch=="aarch64" & vm.debug == true &
+ *           vm.flavor == "server" & !vm.graal.enabled &
+ *           vm.gc.ConcMarkSweep
+ *
+ * @build compiler.c2.aarch64.TestVolatiles
+ *        compiler.c2.aarch64.TestVolatileLoad
+ *        compiler.c2.aarch64.TestUnsafeVolatileLoad
+ *        compiler.c2.aarch64.TestVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileCAS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMS
+ *      TestVolatileLoad CMS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMS
+ *      TestVolatileStore CMS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMS
+ *      TestUnsafeVolatileLoad CMS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMS
+ *      TestUnsafeVolatileStore CMS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMS
+ *      TestUnsafeVolatileCAS CMS
+ */
+
+package compiler.c2.aarch64;
+
+public class TestVolatilesCMS {
+    public static void main(String args[]) throws Throwable
+    {
+        // delegate work to shared code
+        new TestVolatiles().runtest(args[0], args[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesCMSCondMark.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary C2 should use ldar, stlr and ldaxr+stlxr insns for volatile operations
+ * @library /test/lib /
+ *
+ * @modules java.base/jdk.internal.misc
+ *
+ * @requires os.arch=="aarch64" & vm.debug == true &
+ *           vm.flavor == "server" & !vm.graal.enabled &
+ *           vm.gc.ConcMarkSweep
+ *
+ * @build compiler.c2.aarch64.TestVolatiles
+ *        compiler.c2.aarch64.TestVolatileLoad
+ *        compiler.c2.aarch64.TestUnsafeVolatileLoad
+ *        compiler.c2.aarch64.TestVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileCAS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMSCondMark
+ *      TestVolatileLoad CMSCondMark
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMSCondMark
+ *      TestVolatileStore CMSCondMark
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMSCondMark
+ *      TestUnsafeVolatileLoad CMSCondMark
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMSCondMark
+ *      TestUnsafeVolatileStore CMSCondMark
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesCMSCondMark
+ *      TestUnsafeVolatileCAS CMSCondMark
+ */
+
+package compiler.c2.aarch64;
+
+public class TestVolatilesCMSCondMark {
+    public static void main(String args[]) throws Throwable
+    {
+        // delegate work to shared code
+        new TestVolatiles().runtest(args[0], args[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesG1.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary C2 should use ldar, stlr and ldaxr+stlxr insns for volatile operations
+ * @library /test/lib /
+ *
+ * @modules java.base/jdk.internal.misc
+ *
+ * @requires os.arch=="aarch64" & vm.debug == true &
+ *           vm.flavor == "server" & !vm.graal.enabled &
+ *           vm.gc.G1
+ *
+ * @build compiler.c2.aarch64.TestVolatiles
+ *        compiler.c2.aarch64.TestVolatileLoad
+ *        compiler.c2.aarch64.TestUnsafeVolatileLoad
+ *        compiler.c2.aarch64.TestVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileCAS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesG1
+ *      TestVolatileLoad G1
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesG1
+ *      TestVolatileStore G1
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesG1
+ *      TestUnsafeVolatileLoad G1
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesG1
+ *      TestUnsafeVolatileStore G1
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesG1
+ *      TestUnsafeVolatileCAS G1
+ */
+
+package compiler.c2.aarch64;
+
+public class TestVolatilesG1 {
+    public static void main(String args[]) throws Throwable
+    {
+        // delegate work to shared code
+        new TestVolatiles().runtest(args[0], args[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesParallel.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary C2 should use ldar, stlr and ldaxr+stlxr insns for volatile operations
+ * @library /test/lib /
+ *
+ * @modules java.base/jdk.internal.misc
+ *
+ * @requires os.arch=="aarch64" & vm.debug == true &
+ *           vm.flavor == "server" & !vm.graal.enabled &
+ *           vm.gc.Parallel
+ *
+ * @build compiler.c2.aarch64.TestVolatiles
+ *        compiler.c2.aarch64.TestVolatileLoad
+ *        compiler.c2.aarch64.TestUnsafeVolatileLoad
+ *        compiler.c2.aarch64.TestVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileCAS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesParallel
+ *      TestVolatileLoad Parallel
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesParallel
+ *      TestVolatileStore Parallel
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesParallel
+ *      TestUnsafeVolatileLoad Parallel
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesParallel
+ *      TestUnsafeVolatileStore Parallel
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesParallel
+ *      TestUnsafeVolatileCAS Parallel
+ */
+
+package compiler.c2.aarch64;
+
+public class TestVolatilesParallel {
+    public static void main(String args[]) throws Throwable
+    {
+        // delegate work to shared code
+        new TestVolatiles().runtest(args[0], args[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatilesSerial.java	Thu Jun 28 10:09:58 2018 +0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2018, Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary C2 should use ldar, stlr and ldaxr+stlxr insns for volatile operations
+ * @library /test/lib /
+ *
+ * @modules java.base/jdk.internal.misc
+ *
+ * @requires os.arch=="aarch64" & vm.debug == true &
+ *           vm.flavor == "server" & !vm.graal.enabled &
+ *           vm.gc.Serial
+ *
+ * @build compiler.c2.aarch64.TestVolatiles
+ *        compiler.c2.aarch64.TestVolatileLoad
+ *        compiler.c2.aarch64.TestUnsafeVolatileLoad
+ *        compiler.c2.aarch64.TestVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileStore
+ *        compiler.c2.aarch64.TestUnsafeVolatileCAS
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesSerial
+ *      TestVolatileLoad Serial
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesSerial
+ *      TestVolatileStore Serial
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesSerial
+ *      TestUnsafeVolatileLoad Serial
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesSerial
+ *      TestUnsafeVolatileStore Serial
+ *
+ * @run driver compiler.c2.aarch64.TestVolatilesSerial
+ *      TestUnsafeVolatileCAS Serial
+ */
+
+package compiler.c2.aarch64;
+
+public class TestVolatilesSerial {
+    public static void main(String args[]) throws Throwable
+    {
+        // delegate work to shared code
+        new TestVolatiles().runtest(args[0], args[1]);
+    }
+}