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     @Warmup(5000)
 553     public void runArrayStoreTests() {
 554         {
 555             Object[] a = new Object[10];
 556             Object o1 = new Object();
 557             testArrayStore(a, 4, o1);
 558             Asserts.assertEquals(o1, a[4]);
 559         }
 560         {
 561             Object[] a = new Object[10];
 562             testArrayStoreNull(a, 4);
 563             Asserts.assertNull(a[4]);
 564         }
 565         {
 566             Object[] a = new Object[10];
 567             Object o1 = new Object();
 568             testArrayStoreNotNull(a, 4, o1);
 569             Asserts.assertEquals(o1, a[4]);
 570         }
 571         {
 572             Object[] a = new Object[10];
 573             Object[] b = new Object[10];
 574             Object o1 = new Object();
 575             testArrayStoreTwice(a, b, 4, o1);
 576             Asserts.assertEquals(o1, a[4]);
 577             Asserts.assertEquals(o1, b[4]);
 578         }
 579         {
 580             Object o1 = new Object();
 581             Object[] a = testStoreOnNewArrayAtKnownIndex(o1);
 582             Asserts.assertEquals(o1, a[4]);
 583         }
 584         {
 585             Object o1 = new Object();
 586             Object[] a = testStoreOnNewArrayAtUnknownIndex(o1, 5);
 587             Asserts.assertEquals(o1, a[5]);
 588         }
 589         {
 590             Object o1 = new Object();
 591             Object[] a = testStoreAllOnNewSmallArray(o1);
 592             for (int i = 0; i < a.length; i++) {
 593                 Asserts.assertEquals(o1, a[i]);
 594             }
 595         }
 596         {
 597             Object o1 = new Object();
 598             Object[] a = testStoreAllOnNewLargeArray(o1);
 599             for (int i = 0; i < a.length; i++) {
 600                 Asserts.assertEquals(o1, a[i]);
 601             }
 602         }
 603     }
 604 
 605     @Test
 606     public static Object[] testCloneArrayOfObjects(Object[] a) {
 607         Object[] a1 = null;
 608         try {
 609             a1 = a.clone();
 610         } catch (Exception e) {}
 611         return a1;
 612     }
 613 
 614     @Test
 615     @IR(applyIf = {"ReduceInitialCardMarks", "true"},
 616         failOn = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, ANY,
 617                   IRNode.G1_STORE_N_WITH_BARRIER_FLAG, ANY,
 618                   IRNode.G1_ENCODE_P_AND_STORE_N_WITH_BARRIER_FLAG, ANY},
 619         phase = CompilePhase.FINAL_CODE)
 620     @IR(applyIfAnd = {"ReduceInitialCardMarks", "false", "UseCompressedOops", "false"},
 621         counts = {IRNode.G1_STORE_P_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 622         phase = CompilePhase.FINAL_CODE)
 623     @IR(applyIfAnd = {"ReduceInitialCardMarks", "false", "UseCompressedOops", "true"},
 624         counts = {IRNode.G1_STORE_N_WITH_BARRIER_FLAG, POST_ONLY, "2"},
 625         phase = CompilePhase.FINAL_CODE)
 626     public static OuterWithFewFields testCloneObjectWithFewFields(OuterWithFewFields o) {
 627         Object o1 = null;
 628         try {
 629             o1 = o.clone();
 630         } catch (Exception e) {}
 631         return (OuterWithFewFields)o1;
 632     }
 633 
 634     @Test
 635     @IR(applyIf = {"ReduceInitialCardMarks", "true"},
 636         counts = {IRNode.CALL_OF, "jlong_disjoint_arraycopy", "1"})
 637     @IR(applyIf = {"ReduceInitialCardMarks", "false"},
 638         counts = {IRNode.CALL_OF, "G1BarrierSetRuntime::clone", "1"})
 639     public static OuterWithManyFields testCloneObjectWithManyFields(OuterWithManyFields o) {
 640         Object o1 = null;
 641         try {
 642             o1 = o.clone();
 643         } catch (Exception e) {}
 644         return (OuterWithManyFields)o1;
 645     }
 646 
 647     @Run(test = {"testCloneArrayOfObjects",
 648                  "testCloneObjectWithFewFields",
 649                  "testCloneObjectWithManyFields"})
 650     public void runCloneTests() {
 651         {
 652             Object o1 = new Object();
 653             Object[] a = new Object[4];
 654             for (int i = 0; i < 4; i++) {
 655                 a[i] = o1;
 656             }
 657             Object[] a1 = testCloneArrayOfObjects(a);
 658             for (int i = 0; i < 4; i++) {
 659                 Asserts.assertEquals(o1, a1[i]);
 660             }
 661         }
 662         {
 663             Object a = new Object();
 664             Object b = new Object();
 665             OuterWithFewFields o = new OuterWithFewFields();
 666             o.f1 = a;
 667             o.f2 = b;
 668             OuterWithFewFields o1 = testCloneObjectWithFewFields(o);
 669             Asserts.assertEquals(a, o1.f1);
 670             Asserts.assertEquals(b, o1.f2);
 671         }
 672         {
 673             Object a = new Object();
 674             Object b = new Object();
 675             Object c = new Object();
 676             Object d = new Object();
 677             Object e = new Object();
 678             Object f = new Object();
 679             Object g = new Object();
 680             Object h = new Object();
 681             Object i = new Object();
 682             Object j = new Object();
 683             OuterWithManyFields o = new OuterWithManyFields();
 684             o.f1 = a;
 685             o.f2 = b;
 686             o.f3 = c;
 687             o.f4 = d;
 688             o.f5 = e;
 689             o.f6 = f;
 690             o.f7 = g;
 691             o.f8 = h;
 692             o.f9 = i;
 693             o.f10 = j;
 694             OuterWithManyFields o1 = testCloneObjectWithManyFields(o);
 695             Asserts.assertEquals(a, o1.f1);
 696             Asserts.assertEquals(b, o1.f2);
 697             Asserts.assertEquals(c, o1.f3);
 698             Asserts.assertEquals(d, o1.f4);
 699             Asserts.assertEquals(e, o1.f5);
 700             Asserts.assertEquals(f, o1.f6);
 701             Asserts.assertEquals(g, o1.f7);
 702             Asserts.assertEquals(h, o1.f8);
 703             Asserts.assertEquals(i, o1.f9);
 704             Asserts.assertEquals(j, o1.f10);
 705         }
 706     }
 707 
 708     @Test
 709     @IR(applyIf = {"UseCompressedOops", "false"},
 710         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 711         phase = CompilePhase.FINAL_CODE)
 712     @IR(applyIf = {"UseCompressedOops", "true"},
 713         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 714         phase = CompilePhase.FINAL_CODE)
 715     static Object testCompareAndExchange(Outer o, Object oldVal, Object newVal) {
 716         return fVarHandle.compareAndExchange(o, oldVal, newVal);
 717     }
 718 
 719     @Test
 720     @IR(applyIf = {"UseCompressedOops", "false"},
 721         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 722         phase = CompilePhase.FINAL_CODE)
 723     @IR(applyIf = {"UseCompressedOops", "true"},
 724         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 725         phase = CompilePhase.FINAL_CODE)
 726     static boolean testCompareAndSwap(Outer o, Object oldVal, Object newVal) {
 727         return fVarHandle.compareAndSet(o, oldVal, newVal);
 728     }
 729 
 730     @Test
 731     @IR(applyIf = {"UseCompressedOops", "false"},
 732         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 733         phase = CompilePhase.FINAL_CODE)
 734     @IR(applyIf = {"UseCompressedOops", "true"},
 735         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 736         phase = CompilePhase.FINAL_CODE)
 737     static Object testGetAndSet(Outer o, Object newVal) {
 738         return fVarHandle.getAndSet(o, newVal);
 739     }
 740 
 741     // IR checks are disabled for s390 because barriers are not elided (to be investigated).
 742     @Test
 743     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 744         applyIfPlatform = {"s390", "false"},
 745         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 746         phase = CompilePhase.FINAL_CODE)
 747     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 748         applyIfPlatform = {"s390", "false"},
 749         counts = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 750         phase = CompilePhase.FINAL_CODE)
 751     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 752         applyIfPlatform = {"s390", "false"},
 753         failOn = {IRNode.G1_COMPARE_AND_EXCHANGE_P_WITH_BARRIER_FLAG, ANY},
 754         phase = CompilePhase.FINAL_CODE)
 755     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 756         applyIfPlatform = {"s390", "false"},
 757         failOn = {IRNode.G1_COMPARE_AND_EXCHANGE_N_WITH_BARRIER_FLAG, ANY},
 758         phase = CompilePhase.FINAL_CODE)
 759     static Object testCompareAndExchangeOnNewObject(Object oldVal, Object newVal) {
 760         Outer o = new Outer();
 761         o.f = oldVal;
 762         return fVarHandle.compareAndExchange(o, oldVal, newVal);
 763     }
 764 
 765     // IR checks are disabled for s390 when OOPs compression is disabled
 766     // because barriers are not elided in this configuration (to be investigated).
 767     @Test
 768     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 769         applyIfPlatform = {"s390", "false"},
 770         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 771         phase = CompilePhase.FINAL_CODE)
 772     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 773         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 774         phase = CompilePhase.FINAL_CODE)
 775     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 776         applyIfPlatform = {"s390", "false"},
 777         failOn = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, ANY},
 778         phase = CompilePhase.FINAL_CODE)
 779     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 780         failOn = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, ANY},
 781         phase = CompilePhase.FINAL_CODE)
 782     static boolean testCompareAndSwapOnNewObject(Object oldVal, Object newVal) {
 783         Outer o = new Outer();
 784         o.f = oldVal;
 785         return fVarHandle.compareAndSet(o, oldVal, newVal);
 786     }
 787 
 788     @Test
 789     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 790         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 791         phase = CompilePhase.FINAL_CODE)
 792     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 793         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 794         phase = CompilePhase.FINAL_CODE)
 795     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 796         failOn = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, ANY},
 797         phase = CompilePhase.FINAL_CODE)
 798     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 799         failOn = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, ANY},
 800         phase = CompilePhase.FINAL_CODE)
 801     static Object testGetAndSetOnNewObject(Object oldVal, Object newVal) {
 802         Outer o = new Outer();
 803         o.f = oldVal;
 804         return fVarHandle.getAndSet(o, newVal);
 805     }
 806 
 807     @Test
 808     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 809         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 810         phase = CompilePhase.FINAL_CODE)
 811     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 812         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 813         phase = CompilePhase.FINAL_CODE)
 814     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 815         failOn = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, ANY},
 816         phase = CompilePhase.FINAL_CODE)
 817     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 818         failOn = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, ANY},
 819         phase = CompilePhase.FINAL_CODE)
 820     static Object testGetAndSetConditionallyOnNewObject(Object oldVal, Object newVal, boolean c) {
 821         Outer o = new Outer();
 822         o.f = oldVal;
 823         if (c) {
 824             return fVarHandle.getAndSet(o, newVal);
 825         }
 826         return oldVal;
 827     }
 828 
 829     @Test
 830     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "false"},
 831         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 832         phase = CompilePhase.FINAL_CODE)
 833     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "false"},
 834         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, POST_ONLY, "1"},
 835         phase = CompilePhase.FINAL_CODE)
 836     @IR(applyIfAnd = {"UseCompressedOops", "false", "ReduceInitialCardMarks", "true"},
 837         failOn = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, ANY},
 838         phase = CompilePhase.FINAL_CODE)
 839     @IR(applyIfAnd = {"UseCompressedOops", "true", "ReduceInitialCardMarks", "true"},
 840         failOn = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, ANY},
 841         phase = CompilePhase.FINAL_CODE)
 842     static Object testGetAndSetOnNewObjectAfterException(Object oldVal, Object newVal, boolean c) throws Exception {
 843         Outer o = new Outer();
 844         if (c) {
 845             throw new Exception("");
 846         }
 847         o.f = oldVal;
 848         return fVarHandle.getAndSet(o, newVal);
 849     }
 850 
 851     @Test
 852     @IR(applyIf = {"UseCompressedOops", "false"},
 853         counts = {IRNode.G1_COMPARE_AND_SWAP_P_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 854         phase = CompilePhase.FINAL_CODE)
 855     @IR(applyIf = {"UseCompressedOops", "true"},
 856         counts = {IRNode.G1_COMPARE_AND_SWAP_N_WITH_BARRIER_FLAG, PRE_AND_POST, "1"},
 857         phase = CompilePhase.FINAL_CODE)
 858     static Object testGetAndSetOnNewObjectAfterCall(Object oldVal, Object newVal) {
 859         Outer o = new Outer();
 860         nonInlinedMethod();
 861         o.f = oldVal;
 862         return fVarHandle.getAndSet(o, newVal);
 863     }
 864 
 865     @Run(test = {"testCompareAndExchange",
 866                  "testCompareAndSwap",
 867                  "testGetAndSet",
 868                  "testCompareAndExchangeOnNewObject",
 869                  "testCompareAndSwapOnNewObject",
 870                  "testGetAndSetOnNewObject",
 871                  "testGetAndSetConditionallyOnNewObject",
 872                  "testGetAndSetOnNewObjectAfterException",
 873                  "testGetAndSetOnNewObjectAfterCall"})
 874     public void runAtomicTests() {
 875         {
 876             Outer o = new Outer();
 877             Object oldVal = new Object();
 878             o.f = oldVal;
 879             Object newVal = new Object();
 880             Object oldVal2 = testCompareAndExchange(o, oldVal, newVal);
 881             Asserts.assertEquals(oldVal, oldVal2);
 882             Asserts.assertEquals(o.f, newVal);
 883         }
 884         {
 885             Outer o = new Outer();
 886             Object oldVal = new Object();
 887             o.f = oldVal;
 888             Object cmpVal = new Object();
 889             Object newVal = new Object();
 890             Object oldVal2 = testCompareAndExchange(o, cmpVal, newVal);
 891             Asserts.assertEquals(oldVal2, oldVal);
 892             Asserts.assertEquals(o.f, oldVal);
 893         }
 894         {
 895             Outer o = new Outer();
 896             Object oldVal = new Object();
 897             o.f = oldVal;
 898             Object newVal = new Object();
 899             boolean b = testCompareAndSwap(o, oldVal, newVal);
 900             Asserts.assertTrue(b);
 901             Asserts.assertEquals(o.f, newVal);
 902         }
 903         {
 904             Outer o = new Outer();
 905             Object oldVal = new Object();
 906             o.f = oldVal;
 907             Object cmpVal = new Object();
 908             Object newVal = new Object();
 909             boolean b = testCompareAndSwap(o, cmpVal, newVal);
 910             Asserts.assertFalse(b);
 911             Asserts.assertEquals(o.f, oldVal);
 912         }
 913         {
 914             Outer o = new Outer();
 915             Object oldVal = new Object();
 916             o.f = oldVal;
 917             Object newVal = new Object();
 918             Object oldVal2 = testGetAndSet(o, newVal);
 919             Asserts.assertEquals(oldVal, oldVal2);
 920             Asserts.assertEquals(o.f, newVal);
 921         }
 922         {
 923             Object oldVal = new Object();
 924             Object newVal = new Object();
 925             Object oldVal2 = testCompareAndExchangeOnNewObject(oldVal, newVal);
 926             Asserts.assertEquals(oldVal, oldVal2);
 927         }
 928         {
 929             Object oldVal = new Object();
 930             Object newVal = new Object();
 931             boolean b = testCompareAndSwapOnNewObject(oldVal, newVal);
 932             Asserts.assertTrue(b);
 933         }
 934         {
 935             Object oldVal = new Object();
 936             Object newVal = new Object();
 937             Object oldVal2 = testGetAndSetOnNewObject(oldVal, newVal);
 938             Asserts.assertEquals(oldVal, oldVal2);
 939         }
 940         {
 941             Object oldVal = new Object();
 942             Object newVal = new Object();
 943             boolean c = ThreadLocalRandom.current().nextBoolean();
 944             Object oldVal2 = testGetAndSetConditionallyOnNewObject(oldVal, newVal, c);
 945             Asserts.assertEquals(oldVal, oldVal2);
 946         }
 947         {
 948             Object oldVal = new Object();
 949             Object newVal = new Object();
 950             boolean c = ThreadLocalRandom.current().nextBoolean();
 951             try {
 952                 Object oldVal2 = testGetAndSetOnNewObjectAfterException(oldVal, newVal, c);
 953             } catch (Exception e) {}
 954         }
 955         {
 956             Object oldVal = new Object();
 957             Object newVal = new Object();
 958             Object oldVal2 = testGetAndSetOnNewObjectAfterCall(oldVal, newVal);
 959             Asserts.assertEquals(oldVal, oldVal2);
 960         }
 961     }
 962 
 963     @Test
 964     @IR(applyIf = {"UseCompressedOops", "false"},
 965         counts = {IRNode.G1_LOAD_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 966         phase = CompilePhase.FINAL_CODE)
 967     @IR(applyIf = {"UseCompressedOops", "true"},
 968         counts = {IRNode.G1_LOAD_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 969         phase = CompilePhase.FINAL_CODE)
 970     static Object testLoadSoftReference(SoftReference<Object> ref) {
 971         return ref.get();
 972     }
 973 
 974     @Test
 975     @IR(applyIf = {"UseCompressedOops", "false"},
 976         counts = {IRNode.G1_LOAD_P_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 977         phase = CompilePhase.FINAL_CODE)
 978     @IR(applyIf = {"UseCompressedOops", "true"},
 979         counts = {IRNode.G1_LOAD_N_WITH_BARRIER_FLAG, PRE_ONLY, "1"},
 980         phase = CompilePhase.FINAL_CODE)
 981     static Object testLoadWeakReference(WeakReference<Object> ref) {
 982         return ref.get();
 983     }
 984 
 985     @Run(test = {"testLoadSoftReference",
 986                  "testLoadWeakReference"})
 987     public void runReferenceTests() {
 988         {
 989             Object o1 = new Object();
 990             SoftReference<Object> sref = new SoftReference<Object>(o1);
 991             Object o2 = testLoadSoftReference(sref);
 992             Asserts.assertTrue(o2 == o1 || o2 == null);
 993         }
 994         {
 995             Object o1 = new Object();
 996             WeakReference<Object> wref = new WeakReference<Object>(o1);
 997             Object o2 = testLoadWeakReference(wref);
 998             Asserts.assertTrue(o2 == o1 || o2 == null);
 999         }
1000     }
1001 }