1 /*
   2  * Copyright (c) 2024, 2025, Oracle and/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 package compiler.gcbarriers;
  25 
  26 import compiler.lib.ir_framework.*;
  27 import java.lang.invoke.VarHandle;
  28 import java.lang.invoke.MethodHandles;
  29 import java.lang.ref.Reference;
  30 import java.lang.ref.ReferenceQueue;
  31 import java.lang.ref.SoftReference;
  32 import java.lang.ref.WeakReference;
  33 import java.util.concurrent.ThreadLocalRandom;
  34 import jdk.test.lib.Asserts;
  35 
  36 /**
  37  * @test
  38  * @summary Test that G1 barriers are generated and optimized as expected.
  39  * @library /test/lib /
  40  * @requires vm.gc.G1
  41  * @run driver compiler.gcbarriers.TestG1BarrierGeneration
  42  */
  43 
  44 public class TestG1BarrierGeneration {
  45     static final String PRE_ONLY = "pre";
  46     static final String POST_ONLY = "post";
  47     static final String POST_ONLY_NOT_NULL = "post notnull";
  48     static final String PRE_AND_POST = "pre post";
  49     static final String PRE_AND_POST_NOT_NULL = "pre post notnull";
  50     static final String ANY = ".*";
  51 
  52     static class Outer {
  53         Object f;
  54     }
  55 
  56     static class OuterWithVolatileField {
  57         volatile Object f;
  58     }
  59 
  60     static class OuterWithFewFields implements Cloneable {
  61         Object f1;
  62         Object f2;
  63         public Object clone() throws CloneNotSupportedException {
  64             return super.clone();
  65         }
  66     }
  67 
  68     static class OuterWithManyFields implements Cloneable {
  69         Object f1;
  70         Object f2;
  71         Object f3;
  72         Object f4;
  73         Object f5;
  74         Object f6;
  75         Object f7;
  76         Object f8;
  77         Object f9;
  78         Object f10;
  79         public Object clone() throws CloneNotSupportedException {
  80             return super.clone();
  81         }
  82     }
  83 
  84     static final VarHandle fVarHandle;
  85     static {
  86         MethodHandles.Lookup l = MethodHandles.lookup();
  87         try {
  88             fVarHandle = l.findVarHandle(Outer.class, "f", Object.class);
  89         } catch (Exception e) {
  90             throw new Error(e);
  91         }
  92     }
  93 
  94     @DontInline
  95     static void nonInlinedMethod() {}
  96 
  97     public static void main(String[] args) {
  98         TestFramework framework = new TestFramework();
  99         Scenario[] scenarios = new Scenario[2*2];
 100         int scenarioIndex = 0;
 101         for (int i = 0; i < 2; i++) {
 102             for (int j = 0; j < 2; j++) {
 103                 scenarios[scenarioIndex] =
 104                     new Scenario(scenarioIndex,
 105                                  "-XX:CompileCommand=inline,java.lang.ref.*::*",
 106                                  "-XX:" + (i == 0 ? "-" : "+") + "UseCompressedOops",
 107                                  "-XX:" + (j == 0 ? "-" : "+") + "ReduceInitialCardMarks");
 108                 scenarioIndex++;
 109             }
 110         }
 111         framework.addScenarios(scenarios);
 112         framework.start();
 113     }
 114 
 115     @Test
 116     @IR(applyIf = {"UseCompressedOops", "false"},
 117         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 118         phase = CompilePhase.FINAL_CODE)
 119     @IR(applyIf = {"UseCompressedOops", "true"},
 120         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 121         phase = CompilePhase.FINAL_CODE)
 122     public static void testStore(Outer o, Object o1) {
 123         o.f = o1;
 124     }
 125 
 126     @Test
 127     @IR(applyIf = {"UseCompressedOops", "false"},
 128         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 129         phase = CompilePhase.FINAL_CODE)
 130     @IR(applyIf = {"UseCompressedOops", "true"},
 131         counts = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 132         phase = CompilePhase.FINAL_CODE)
 133     public static void testStoreNull(Outer o) {
 134         o.f = null;
 135     }
 136 
 137     @Test
 138     @IR(applyIf = {"UseCompressedOops", "false"},
 139         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 140         phase = CompilePhase.FINAL_CODE)
 141     @IR(applyIf = {"UseCompressedOops", "true"},
 142         counts = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 143         phase = CompilePhase.FINAL_CODE)
 144     public static void testStoreObfuscatedNull(Outer o, Object o1) {
 145         Object o2 = o1;
 146         for (int i = 0; i < 4; i++) {
 147             if ((i % 2) == 0) {
 148                 o2 = null;
 149             }
 150         }
 151         // o2 is null here, but this is only known to C2 after applying some
 152         // optimizations (loop unrolling, IGVN).
 153         o.f = o2;
 154     }
 155 
 156     @Test
 157     @IR(applyIf = {"UseCompressedOops", "false"},
 158         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST_NOT_NULL, "1"},
 159         phase = CompilePhase.FINAL_CODE)
 160     @IR(applyIf = {"UseCompressedOops", "true"},
 161         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST_NOT_NULL, "1"},
 162         phase = CompilePhase.FINAL_CODE)
 163     public static void testStoreNotNull(Outer o, Object o1) {
 164         if (o1.hashCode() == 42) {
 165             return;
 166         }
 167         o.f = o1;
 168     }
 169 
 170     @Test
 171     @IR(applyIf = {"UseCompressedOops", "false"},
 172         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "2"},
 173         phase = CompilePhase.FINAL_CODE)
 174     @IR(applyIf = {"UseCompressedOops", "true"},
 175         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "2"},
 176         phase = CompilePhase.FINAL_CODE)
 177     public static void testStoreTwice(Outer o, Outer p, Object o1) {
 178         o.f = o1;
 179         p.f = o1;
 180     }
 181 
 182     @Test
 183     @IR(applyIf = {"UseCompressedOops", "false"},
 184         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 185         phase = CompilePhase.FINAL_CODE)
 186     @IR(applyIf = {"UseCompressedOops", "true"},
 187         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 188         phase = CompilePhase.FINAL_CODE)
 189     public static void testStoreVolatile(OuterWithVolatileField o, Object o1) {
 190         o.f = o1;
 191     }
 192 
 193     @Test
 194     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 195         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 196         phase = CompilePhase.FINAL_CODE)
 197     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 198         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 199         phase = CompilePhase.FINAL_CODE)
 200     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 201         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 202         phase = CompilePhase.FINAL_CODE)
 203     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 204         failOn = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 205                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 206         phase = CompilePhase.FINAL_CODE)
 207     public static Outer testStoreOnNewObject(Object o1) {
 208         Outer o = new Outer();
 209         o.f = o1;
 210         return o;
 211     }
 212 
 213     @Test
 214     @IR(failOn = {IRNode.STORE_P, IRNode.STORE_N},
 215         phase = CompilePhase.BEFORE_MACRO_EXPANSION)
 216     public static Outer testStoreNullOnNewObject() {
 217         Outer o = new Outer();
 218         o.f = null;
 219         return o;
 220     }
 221 
 222     @Test
 223     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 224         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY_NOT_NULL, "1"},
 225         phase = CompilePhase.FINAL_CODE)
 226     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 227         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY_NOT_NULL, "1"},
 228         phase = CompilePhase.FINAL_CODE)
 229     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 230         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 231         phase = CompilePhase.FINAL_CODE)
 232     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 233         failOn = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 234                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 235         phase = CompilePhase.FINAL_CODE)
 236     public static Outer testStoreNotNullOnNewObject(Object o1) {
 237         if (o1.hashCode() == 42) {
 238             return null;
 239         }
 240         Outer o = new Outer();
 241         o.f = o1;
 242         return o;
 243     }
 244 
 245     @Test
 246     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 247         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 248         phase = CompilePhase.FINAL_CODE)
 249     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 250         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 251         phase = CompilePhase.FINAL_CODE)
 252     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 253         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 254         phase = CompilePhase.FINAL_CODE)
 255     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 256         failOn = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 257                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 258         phase = CompilePhase.FINAL_CODE)
 259     public static Outer testStoreOnNewObjectInTwoPaths(Object o1, boolean c) {
 260         Outer o;
 261         if (c) {
 262             o = new Outer();
 263             o.f = o1;
 264         } else {
 265             o = new Outer();
 266             o.f = o1;
 267         }
 268         return o;
 269     }
 270 
 271     @Test
 272     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 273         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 274         phase = CompilePhase.FINAL_CODE)
 275     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 276         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 277         phase = CompilePhase.FINAL_CODE)
 278     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 279         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 280         phase = CompilePhase.FINAL_CODE)
 281     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 282         failOn = {IRNode.G1_STORE_N, IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 283         phase = CompilePhase.FINAL_CODE)
 284     public static Outer testStoreConditionallyOnNewObject(Object o1, boolean c) {
 285         Outer o = new Outer();
 286         if (c) {
 287             o.f = o1;
 288         }
 289         return o;
 290     }
 291 
 292     @Test
 293     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 294         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 295         phase = CompilePhase.FINAL_CODE)
 296     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 297         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 298         phase = CompilePhase.FINAL_CODE)
 299     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 300         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 301         phase = CompilePhase.FINAL_CODE)
 302     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 303         failOn = {IRNode.G1_STORE_N, IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 304         phase = CompilePhase.FINAL_CODE)
 305     public static Outer testStoreOnNewObjectAfterException(Object o1, boolean c) throws Exception {
 306         Outer o = new Outer();
 307         if (c) {
 308             throw new Exception("");
 309         }
 310         o.f = o1;
 311         return o;
 312     }
 313 
 314     @Test
 315     @IR(applyIf = {"UseCompressedOops", "false"},
 316         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 317         phase = CompilePhase.FINAL_CODE)
 318     @IR(applyIf = {"UseCompressedOops", "true"},
 319         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 320         phase = CompilePhase.FINAL_CODE)
 321     public static Outer testStoreOnNewObjectAfterCall(Object o1) {
 322         Outer o = new Outer();
 323         nonInlinedMethod();
 324         o.f = o1;
 325         return o;
 326     }
 327 
 328     @Run(test = {"testStore",
 329                  "testStoreNull",
 330                  "testStoreObfuscatedNull",
 331                  "testStoreNotNull",
 332                  "testStoreTwice",
 333                  "testStoreVolatile",
 334                  "testStoreOnNewObject",
 335                  "testStoreNullOnNewObject",
 336                  "testStoreNotNullOnNewObject",
 337                  "testStoreOnNewObjectInTwoPaths",
 338                  "testStoreConditionallyOnNewObject",
 339                  "testStoreOnNewObjectAfterException",
 340                  "testStoreOnNewObjectAfterCall"})
 341     public void runStoreTests() {
 342         {
 343             Outer o = new Outer();
 344             Object o1 = new Object();
 345             testStore(o, o1);
 346             Asserts.assertEquals(o1, o.f);
 347         }
 348         {
 349             Outer o = new Outer();
 350             testStoreNull(o);
 351             Asserts.assertNull(o.f);
 352         }
 353         {
 354             Outer o = new Outer();
 355             Object o1 = new Object();
 356             testStoreObfuscatedNull(o, o1);
 357             Asserts.assertNull(o.f);
 358         }
 359         {
 360             Outer o = new Outer();
 361             Object o1 = new Object();
 362             testStoreNotNull(o, o1);
 363             Asserts.assertEquals(o1, o.f);
 364         }
 365         {
 366             Outer o = new Outer();
 367             Outer p = new Outer();
 368             Object o1 = new Object();
 369             testStoreTwice(o, p, o1);
 370             Asserts.assertEquals(o1, o.f);
 371             Asserts.assertEquals(o1, p.f);
 372         }
 373         {
 374             OuterWithVolatileField o = new OuterWithVolatileField();
 375             Object o1 = new Object();
 376             testStoreVolatile(o, o1);
 377             Asserts.assertEquals(o1, o.f);
 378         }
 379         {
 380             Object o1 = new Object();
 381             Outer o = testStoreOnNewObject(o1);
 382             Asserts.assertEquals(o1, o.f);
 383         }
 384         {
 385             Outer o = testStoreNullOnNewObject();
 386             Asserts.assertNull(o.f);
 387         }
 388         {
 389             Object o1 = new Object();
 390             Outer o = testStoreNotNullOnNewObject(o1);
 391             Asserts.assertEquals(o1, o.f);
 392         }
 393         {
 394             Object o1 = new Object();
 395             Outer o = testStoreOnNewObjectInTwoPaths(o1, ThreadLocalRandom.current().nextBoolean());
 396             Asserts.assertEquals(o1, o.f);
 397         }
 398         {
 399             Object o1 = new Object();
 400             boolean c = ThreadLocalRandom.current().nextBoolean();
 401             Outer o = testStoreConditionallyOnNewObject(o1, c);
 402             Asserts.assertTrue(o.f == (c ? o1 : null));
 403         }
 404         {
 405             Object o1 = new Object();
 406             boolean c = ThreadLocalRandom.current().nextBoolean();
 407             try {
 408                 Outer o = testStoreOnNewObjectAfterException(o1, c);
 409             } catch (Exception e) {}
 410         }
 411         {
 412             Object o1 = new Object();
 413             Outer o = testStoreOnNewObjectAfterCall(o1);
 414             Asserts.assertEquals(o1, o.f);
 415         }
 416     }
 417 
 418     @Test
 419     @IR(applyIf = {"UseCompressedOops", "false"},
 420         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 421         phase = CompilePhase.FINAL_CODE)
 422     @IR(applyIf = {"UseCompressedOops", "true"},
 423         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 424         phase = CompilePhase.FINAL_CODE)
 425     public static void testArrayStore(Object[] a, int index, Object o1) {
 426         a[index] = o1;
 427     }
 428 
 429     @Test
 430     @IR(applyIf = {"UseCompressedOops", "false"},
 431         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 432         phase = CompilePhase.FINAL_CODE)
 433     @IR(applyIf = {"UseCompressedOops", "true"},
 434         counts = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 435         phase = CompilePhase.FINAL_CODE)
 436     public static void testArrayStoreNull(Object[] a, int index) {
 437         a[index] = null;
 438     }
 439 
 440     @Test
 441     @IR(applyIf = {"UseCompressedOops", "false"},
 442         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST_NOT_NULL, "1"},
 443         phase = CompilePhase.FINAL_CODE)
 444     @IR(applyIf = {"UseCompressedOops", "true"},
 445         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST_NOT_NULL, "1"},
 446         phase = CompilePhase.FINAL_CODE)
 447     public static void testArrayStoreNotNull(Object[] a, int index, Object o1) {
 448         if (o1.hashCode() == 42) {
 449             return;
 450         }
 451         a[index] = o1;
 452     }
 453 
 454     @Test
 455     @IR(applyIf = {"UseCompressedOops", "false"},
 456         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "2"},
 457         phase = CompilePhase.FINAL_CODE)
 458     @IR(applyIf = {"UseCompressedOops", "true"},
 459         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "2"},
 460         phase = CompilePhase.FINAL_CODE)
 461     public static void testArrayStoreTwice(Object[] a, Object[] b, int index, Object o1) {
 462         a[index] = o1;
 463         b[index] = o1;
 464     }
 465 
 466     @Test
 467     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 468         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 469         phase = CompilePhase.FINAL_CODE)
 470     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 471         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 472         phase = CompilePhase.FINAL_CODE)
 473     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 474         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 475         phase = CompilePhase.FINAL_CODE)
 476     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 477         failOn = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 478                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 479         phase = CompilePhase.FINAL_CODE)
 480     public static Object[] testStoreOnNewArrayAtKnownIndex(Object o1) {
 481         Object[] a = new Object[10];
 482         a[4] = o1;
 483         return a;
 484     }
 485 
 486     @Test
 487     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 488         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 489         phase = CompilePhase.FINAL_CODE)
 490     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 491         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 492         phase = CompilePhase.FINAL_CODE)
 493     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 494         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 495         phase = CompilePhase.FINAL_CODE)
 496     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 497         failOn = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 498                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 499         phase = CompilePhase.FINAL_CODE)
 500     public static Object[] testStoreOnNewArrayAtUnknownIndex(Object o1, int index) {
 501         Object[] a = new Object[10];
 502         a[index] = o1;
 503         return a;
 504     }
 505 
 506     @Test
 507     @IR(failOn = IRNode.SAFEPOINT)
 508     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 509         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, ">1"},
 510         phase = CompilePhase.FINAL_CODE)
 511     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 512         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, ">1"},
 513         phase = CompilePhase.FINAL_CODE)
 514     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 515         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY},
 516         phase = CompilePhase.FINAL_CODE)
 517     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 518         failOn = {IRNode.G1_STORE_N, IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 519         phase = CompilePhase.FINAL_CODE)
 520     public static Object[] testStoreAllOnNewSmallArray(Object o1) {
 521         Object[] a = new Object[64];
 522         for (int i = 0; i < a.length; i++) {
 523             a[i] = o1;
 524         }
 525         return a;
 526     }
 527 
 528     @Test
 529     @IR(counts = {IRNode.SAFEPOINT, "1"})
 530     @IR(applyIf = {"UseCompressedOops", "false"},
 531         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 532         phase = CompilePhase.FINAL_CODE)
 533     @IR(applyIf = {"UseCompressedOops", "true"},
 534         counts = {IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 535         phase = CompilePhase.FINAL_CODE)
 536     public static Object[] testStoreAllOnNewLargeArray(Object o1) {
 537         Object[] a = new Object[1024];
 538         for (int i = 0; i < a.length; i++) {
 539             a[i] = o1;
 540         }
 541         return a;
 542     }
 543 
 544     @Run(test = {"testArrayStore",
 545                  "testArrayStoreNull",
 546                  "testArrayStoreNotNull",
 547                  "testArrayStoreTwice",
 548                  "testStoreOnNewArrayAtKnownIndex",
 549                  "testStoreOnNewArrayAtUnknownIndex",
 550                  "testStoreAllOnNewSmallArray",
 551                  "testStoreAllOnNewLargeArray"})
 552     public void runArrayStoreTests() {
 553         {
 554             Object[] a = new Object[10];
 555             Object o1 = new Object();
 556             testArrayStore(a, 4, o1);
 557             Asserts.assertEquals(o1, a[4]);
 558         }
 559         {
 560             Object[] a = new Object[10];
 561             testArrayStoreNull(a, 4);
 562             Asserts.assertNull(a[4]);
 563         }
 564         {
 565             Object[] a = new Object[10];
 566             Object o1 = new Object();
 567             testArrayStoreNotNull(a, 4, o1);
 568             Asserts.assertEquals(o1, a[4]);
 569         }
 570         {
 571             Object[] a = new Object[10];
 572             Object[] b = new Object[10];
 573             Object o1 = new Object();
 574             testArrayStoreTwice(a, b, 4, o1);
 575             Asserts.assertEquals(o1, a[4]);
 576             Asserts.assertEquals(o1, b[4]);
 577         }
 578         {
 579             Object o1 = new Object();
 580             Object[] a = testStoreOnNewArrayAtKnownIndex(o1);
 581             Asserts.assertEquals(o1, a[4]);
 582         }
 583         {
 584             Object o1 = new Object();
 585             Object[] a = testStoreOnNewArrayAtUnknownIndex(o1, 5);
 586             Asserts.assertEquals(o1, a[5]);
 587         }
 588         {
 589             Object o1 = new Object();
 590             Object[] a = testStoreAllOnNewSmallArray(o1);
 591             for (int i = 0; i < a.length; i++) {
 592                 Asserts.assertEquals(o1, a[i]);
 593             }
 594         }
 595         {
 596             Object o1 = new Object();
 597             Object[] a = testStoreAllOnNewLargeArray(o1);
 598             for (int i = 0; i < a.length; i++) {
 599                 Asserts.assertEquals(o1, a[i]);
 600             }
 601         }
 602     }
 603 
 604     @Test
 605     public static Object[] testCloneArrayOfObjects(Object[] a) {
 606         Object[] a1 = null;
 607         try {
 608             a1 = a.clone();
 609         } catch (Exception e) {}
 610         return a1;
 611     }
 612 
 613     @Test
 614     @IR(applyIf = {"ReduceInitialCardMarks", "true"},
 615         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY,
 616                   IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 617                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 618         phase = CompilePhase.FINAL_CODE)
 619     @IR(applyIfAnd = {"ReduceInitialCardMarks", "false", "UseCompressedOops", "false"},
 620         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 621         phase = CompilePhase.FINAL_CODE)
 622     @IR(applyIfAnd = {"ReduceInitialCardMarks", "false", "UseCompressedOops", "true"},
 623         counts = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 624         phase = CompilePhase.FINAL_CODE)
 625     public static OuterWithFewFields testCloneObjectWithFewFields(OuterWithFewFields o) {
 626         Object o1 = null;
 627         try {
 628             o1 = o.clone();
 629         } catch (Exception e) {}
 630         return (OuterWithFewFields)o1;
 631     }
 632 
 633     @Test
 634     @IR(applyIf = {"ReduceInitialCardMarks", "true"},
 635         counts = {IRNode.CALL_OF, "jlong_disjoint_arraycopy", "1"})
 636     @IR(applyIf = {"ReduceInitialCardMarks", "false"},
 637         counts = {IRNode.CALL_OF, "G1BarrierSetRuntime::clone", "1"})
 638     public static OuterWithManyFields testCloneObjectWithManyFields(OuterWithManyFields o) {
 639         Object o1 = null;
 640         try {
 641             o1 = o.clone();
 642         } catch (Exception e) {}
 643         return (OuterWithManyFields)o1;
 644     }
 645 
 646     @Run(test = {"testCloneArrayOfObjects",
 647                  "testCloneObjectWithFewFields",
 648                  "testCloneObjectWithManyFields"})
 649     public void runCloneTests() {
 650         {
 651             Object o1 = new Object();
 652             Object[] a = new Object[4];
 653             for (int i = 0; i < 4; i++) {
 654                 a[i] = o1;
 655             }
 656             Object[] a1 = testCloneArrayOfObjects(a);
 657             for (int i = 0; i < 4; i++) {
 658                 Asserts.assertEquals(o1, a1[i]);
 659             }
 660         }
 661         {
 662             Object a = new Object();
 663             Object b = new Object();
 664             OuterWithFewFields o = new OuterWithFewFields();
 665             o.f1 = a;
 666             o.f2 = b;
 667             OuterWithFewFields o1 = testCloneObjectWithFewFields(o);
 668             Asserts.assertEquals(a, o1.f1);
 669             Asserts.assertEquals(b, o1.f2);
 670         }
 671         {
 672             Object a = new Object();
 673             Object b = new Object();
 674             Object c = new Object();
 675             Object d = new Object();
 676             Object e = new Object();
 677             Object f = new Object();
 678             Object g = new Object();
 679             Object h = new Object();
 680             Object i = new Object();
 681             Object j = new Object();
 682             OuterWithManyFields o = new OuterWithManyFields();
 683             o.f1 = a;
 684             o.f2 = b;
 685             o.f3 = c;
 686             o.f4 = d;
 687             o.f5 = e;
 688             o.f6 = f;
 689             o.f7 = g;
 690             o.f8 = h;
 691             o.f9 = i;
 692             o.f10 = j;
 693             OuterWithManyFields o1 = testCloneObjectWithManyFields(o);
 694             Asserts.assertEquals(a, o1.f1);
 695             Asserts.assertEquals(b, o1.f2);
 696             Asserts.assertEquals(c, o1.f3);
 697             Asserts.assertEquals(d, o1.f4);
 698             Asserts.assertEquals(e, o1.f5);
 699             Asserts.assertEquals(f, o1.f6);
 700             Asserts.assertEquals(g, o1.f7);
 701             Asserts.assertEquals(h, o1.f8);
 702             Asserts.assertEquals(i, o1.f9);
 703             Asserts.assertEquals(j, o1.f10);
 704         }
 705     }
 706 
 707     @Test
 708     @IR(applyIf = {"UseCompressedOops", "false"},
 709         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 710         phase = CompilePhase.FINAL_CODE)
 711     @IR(applyIf = {"UseCompressedOops", "true"},
 712         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 713         phase = CompilePhase.FINAL_CODE)
 714     static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) {
 715         return fVarHandle.compareAndExchange(o, oldVal, newVal);
 716     }
 717 
 718     @Test
 719     @IR(applyIf = {"UseCompressedOops", "false"},
 720         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 721         phase = CompilePhase.FINAL_CODE)
 722     @IR(applyIf = {"UseCompressedOops", "true"},
 723         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 724         phase = CompilePhase.FINAL_CODE)
 725     static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) {
 726         return fVarHandle.compareAndSet(o, oldVal, newVal);
 727     }
 728 
 729     @Test
 730     @IR(applyIf = {"UseCompressedOops", "false"},
 731         counts = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 732         phase = CompilePhase.FINAL_CODE)
 733     @IR(applyIf = {"UseCompressedOops", "true"},
 734         counts = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 735         phase = CompilePhase.FINAL_CODE)
 736     static Object testGetAndSet(Outer o, Object newVal) {
 737         return fVarHandle.getAndSet(o, newVal);
 738     }
 739 
 740     // IR checks are disabled for s390 because barriers are not elided (to be investigated).
 741     @Test
 742     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 743         applyIfPlatform = {"s390", "false"},
 744         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 745         phase = CompilePhase.FINAL_CODE)
 746     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 747         applyIfPlatform = {"s390", "false"},
 748         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 749         phase = CompilePhase.FINAL_CODE)
 750     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 751         applyIfPlatform = {"s390", "false"},
 752         failOn = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, ANY},
 753         phase = CompilePhase.FINAL_CODE)
 754     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 755         applyIfPlatform = {"s390", "false"},
 756         failOn = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, ANY},
 757         phase = CompilePhase.FINAL_CODE)
 758     static Object testCompareAndExchangeOnNewObject(Object oldVal, Object newVal) {
 759         Outer o = new Outer();
 760         o.f = oldVal;
 761         return fVarHandle.compareAndExchange(o, oldVal, newVal);
 762     }
 763 
 764     // IR checks are disabled for s390 when OOPs compression is disabled
 765     // because barriers are not elided in this configuration (to be investigated).
 766     @Test
 767     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 768         applyIfPlatform = {"s390", "false"},
 769         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 770         phase = CompilePhase.FINAL_CODE)
 771     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 772         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 773         phase = CompilePhase.FINAL_CODE)
 774     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 775         applyIfPlatform = {"s390", "false"},
 776         failOn = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, ANY},
 777         phase = CompilePhase.FINAL_CODE)
 778     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 779         failOn = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, ANY},
 780         phase = CompilePhase.FINAL_CODE)
 781     static boolean testCompareAndSwapOnNewObject(Object oldVal, Object newVal) {
 782         Outer o = new Outer();
 783         o.f = oldVal;
 784         return fVarHandle.compareAndSet(o, oldVal, newVal);
 785     }
 786 
 787     @Test
 788     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 789         counts = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 790         phase = CompilePhase.FINAL_CODE)
 791     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 792         counts = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 793         phase = CompilePhase.FINAL_CODE)
 794     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 795         failOn = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, ANY},
 796         phase = CompilePhase.FINAL_CODE)
 797     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 798         failOn = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, ANY},
 799         phase = CompilePhase.FINAL_CODE)
 800     static Object testGetAndSetOnNewObject(Object oldVal, Object newVal) {
 801         Outer o = new Outer();
 802         o.f = oldVal;
 803         return fVarHandle.getAndSet(o, newVal);
 804     }
 805 
 806     @Test
 807     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 808         counts = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 809         phase = CompilePhase.FINAL_CODE)
 810     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 811         counts = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 812         phase = CompilePhase.FINAL_CODE)
 813     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 814         failOn = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, ANY},
 815         phase = CompilePhase.FINAL_CODE)
 816     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 817         failOn = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, ANY},
 818         phase = CompilePhase.FINAL_CODE)
 819     static Object testGetAndSetConditionallyOnNewObject(Object oldVal, Object newVal, boolean c) {
 820         Outer o = new Outer();
 821         o.f = oldVal;
 822         if (c) {
 823             return fVarHandle.getAndSet(o, newVal);
 824         }
 825         return oldVal;
 826     }
 827 
 828     @Test
 829     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 830         counts = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 831         phase = CompilePhase.FINAL_CODE)
 832     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 833         counts = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 834         phase = CompilePhase.FINAL_CODE)
 835     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 836         failOn = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, ANY},
 837         phase = CompilePhase.FINAL_CODE)
 838     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 839         failOn = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, ANY},
 840         phase = CompilePhase.FINAL_CODE)
 841     static Object testGetAndSetOnNewObjectAfterException(Object oldVal, Object newVal, boolean c) throws Exception {
 842         Outer o = new Outer();
 843         if (c) {
 844             throw new Exception("");
 845         }
 846         o.f = oldVal;
 847         return fVarHandle.getAndSet(o, newVal);
 848     }
 849 
 850     @Test
 851     @IR(applyIf = {"UseCompressedOops", "false"},
 852         counts = {IRNode.G1_GET_AND_SET_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 853         phase = CompilePhase.FINAL_CODE)
 854     @IR(applyIf = {"UseCompressedOops", "true"},
 855         counts = {IRNode.G1_GET_AND_SET_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 856         phase = CompilePhase.FINAL_CODE)
 857     static Object testGetAndSetOnNewObjectAfterCall(Object oldVal, Object newVal) {
 858         Outer o = new Outer();
 859         nonInlinedMethod();
 860         o.f = oldVal;
 861         return fVarHandle.getAndSet(o, newVal);
 862     }
 863 
 864     @Run(test = {"testCompareAndExchange",
 865                  "testCompareAndSwap",
 866                  "testGetAndSet",
 867                  "testCompareAndExchangeOnNewObject",
 868                  "testCompareAndSwapOnNewObject",
 869                  "testGetAndSetOnNewObject",
 870                  "testGetAndSetConditionallyOnNewObject",
 871                  "testGetAndSetOnNewObjectAfterException",
 872                  "testGetAndSetOnNewObjectAfterCall"})
 873     public void runAtomicTests() {
 874         {
 875             Outer o = new Outer();
 876             Object oldVal = new Object();
 877             o.f = oldVal;
 878             Object newVal = new Object();
 879             Object oldVal2 = testCompareAndExchange(o, oldVal, newVal);
 880             Asserts.assertEquals(oldVal, oldVal2);
 881             Asserts.assertEquals(o.f, newVal);
 882         }
 883         {
 884             Outer o = new Outer();
 885             Object oldVal = new Object();
 886             o.f = oldVal;
 887             Object cmpVal = new Object();
 888             Object newVal = new Object();
 889             Object oldVal2 = testCompareAndExchange(o, cmpVal, newVal);
 890             Asserts.assertEquals(oldVal2, oldVal);
 891             Asserts.assertEquals(o.f, oldVal);
 892         }
 893         {
 894             Outer o = new Outer();
 895             Object oldVal = new Object();
 896             o.f = oldVal;
 897             Object newVal = new Object();
 898             boolean b = testCompareAndSwap(o, oldVal, newVal);
 899             Asserts.assertTrue(b);
 900             Asserts.assertEquals(o.f, newVal);
 901         }
 902         {
 903             Outer o = new Outer();
 904             Object oldVal = new Object();
 905             o.f = oldVal;
 906             Object cmpVal = new Object();
 907             Object newVal = new Object();
 908             boolean b = testCompareAndSwap(o, cmpVal, newVal);
 909             Asserts.assertFalse(b);
 910             Asserts.assertEquals(o.f, oldVal);
 911         }
 912         {
 913             Outer o = new Outer();
 914             Object oldVal = new Object();
 915             o.f = oldVal;
 916             Object newVal = new Object();
 917             Object oldVal2 = testGetAndSet(o, newVal);
 918             Asserts.assertEquals(oldVal, oldVal2);
 919             Asserts.assertEquals(o.f, newVal);
 920         }
 921         {
 922             Object oldVal = new Object();
 923             Object newVal = new Object();
 924             Object oldVal2 = testCompareAndExchangeOnNewObject(oldVal, newVal);
 925             Asserts.assertEquals(oldVal, oldVal2);
 926         }
 927         {
 928             Object oldVal = new Object();
 929             Object newVal = new Object();
 930             boolean b = testCompareAndSwapOnNewObject(oldVal, newVal);
 931             Asserts.assertTrue(b);
 932         }
 933         {
 934             Object oldVal = new Object();
 935             Object newVal = new Object();
 936             Object oldVal2 = testGetAndSetOnNewObject(oldVal, newVal);
 937             Asserts.assertEquals(oldVal, oldVal2);
 938         }
 939         {
 940             Object oldVal = new Object();
 941             Object newVal = new Object();
 942             boolean c = ThreadLocalRandom.current().nextBoolean();
 943             Object oldVal2 = testGetAndSetConditionallyOnNewObject(oldVal, newVal, c);
 944             Asserts.assertEquals(oldVal, oldVal2);
 945         }
 946         {
 947             Object oldVal = new Object();
 948             Object newVal = new Object();
 949             boolean c = ThreadLocalRandom.current().nextBoolean();
 950             try {
 951                 Object oldVal2 = testGetAndSetOnNewObjectAfterException(oldVal, newVal, c);
 952             } catch (Exception e) {}
 953         }
 954         {
 955             Object oldVal = new Object();
 956             Object newVal = new Object();
 957             Object oldVal2 = testGetAndSetOnNewObjectAfterCall(oldVal, newVal);
 958             Asserts.assertEquals(oldVal, oldVal2);
 959         }
 960     }
 961 
 962     @Test
 963     @IR(applyIf = {"UseCompressedOops", "false"},
 964         counts = {IRNode.G1_LOAD_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 965         phase = CompilePhase.FINAL_CODE)
 966     @IR(applyIf = {"UseCompressedOops", "true"},
 967         counts = {IRNode.G1_LOAD_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 968         phase = CompilePhase.FINAL_CODE)
 969     static Object testLoadSoftReference(SoftReference<Object> ref) {
 970         return ref.get();
 971     }
 972 
 973     @Test
 974     @IR(applyIf = {"UseCompressedOops", "false"},
 975         counts = {IRNode.G1_LOAD_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 976         phase = CompilePhase.FINAL_CODE)
 977     @IR(applyIf = {"UseCompressedOops", "true"},
 978         counts = {IRNode.G1_LOAD_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 979         phase = CompilePhase.FINAL_CODE)
 980     static Object testLoadWeakReference(WeakReference<Object> ref) {
 981         return ref.get();
 982     }
 983 
 984     @Run(test = {"testLoadSoftReference",
 985                  "testLoadWeakReference"})
 986     public void runReferenceTests() {
 987         {
 988             Object o1 = new Object();
 989             SoftReference<Object> sref = new SoftReference<Object>(o1);
 990             Object o2 = testLoadSoftReference(sref);
 991             Asserts.assertTrue(o2 == o1 || o2 == null);
 992         }
 993         {
 994             Object o1 = new Object();
 995             WeakReference<Object> wref = new WeakReference<Object>(o1);
 996             Object o2 = testLoadWeakReference(wref);
 997             Asserts.assertTrue(o2 == o1 || o2 == null);
 998         }
 999     }
1000 }