1 /*
   2  * Copyright (c) 2018, 2018, 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 
  25 package org.graalvm.compiler.core.jdk9.test.ea;
  26 
  27 import java.util.Objects;
  28 import java.util.concurrent.atomic.AtomicReference;
  29 import org.graalvm.compiler.core.test.ea.EATestBase;
  30 
  31 import org.junit.Test;
  32 
  33 import jdk.vm.ci.meta.JavaConstant;
  34 
  35 public class AtomicVirtualizationTests extends EATestBase {
  36     private static final TestObject OBJ1 = new TestObject(1);
  37     private static final TestObject OBJ2 = new TestObject(2);
  38     private static TestObject obj6 = new TestObject(6);
  39     private static TestObject obj7 = new TestObject(7);
  40     private static TestObject obj8 = new TestObject(8);
  41 
  42     private static final class TestObject {
  43         final int id;
  44 
  45         private TestObject(int id) {
  46             this.id = id;
  47         }
  48 
  49         @Override
  50         public boolean equals(Object o) {
  51             if (this == o) {
  52                 return true;
  53             }
  54             if (o == null || getClass() != o.getClass()) {
  55                 return false;
  56             }
  57             TestObject that = (TestObject) o;
  58             return id == that.id;
  59         }
  60 
  61         @Override
  62         public int hashCode() {
  63             return Objects.hash(id);
  64         }
  65 
  66         @Override
  67         public String toString() {
  68             return "TestObject{id=" + id + '}';
  69         }
  70     }
  71 
  72     // c = constant (heap-allocated); v = virtual; u = unknown (heap-allocated)
  73 
  74     public static boolean cvvNoMatchCAS() {
  75         AtomicReference<TestObject> a = new AtomicReference<>(null);
  76         return a.compareAndSet(new TestObject(3), new TestObject(4));
  77     }
  78 
  79     @Test
  80     public void testcvvNoMatchCAS() {
  81         testAtomicVirtualization("cvvNoMatchCAS", JavaConstant.INT_0);
  82     }
  83 
  84     public static Object cvvNoMatchCAE() {
  85         AtomicReference<TestObject> a = new AtomicReference<>(null);
  86         return a.compareAndExchange(new TestObject(3), new TestObject(4));
  87     }
  88 
  89     @Test
  90     public void testcvvNoMatchCAE() {
  91         testAtomicVirtualization("cvvNoMatchCAE", JavaConstant.NULL_POINTER);
  92     }
  93 
  94     public static boolean ccvNoMatchCAS() {
  95         AtomicReference<TestObject> a = new AtomicReference<>(null);
  96         return a.compareAndSet(OBJ1, new TestObject(3));
  97     }
  98 
  99     @Test
 100     public void testccvNoMatchCAS() {
 101         testAtomicVirtualization("ccvNoMatchCAS", JavaConstant.INT_0);
 102     }
 103 
 104     public static Object ccvNoMatchCAE() {
 105         AtomicReference<TestObject> a = new AtomicReference<>(null);
 106         return a.compareAndExchange(OBJ1, new TestObject(3));
 107     }
 108 
 109     @Test
 110     public void testccvNoMatchCAE() {
 111         testAtomicVirtualization("ccvNoMatchCAE", JavaConstant.NULL_POINTER);
 112     }
 113 
 114     public static boolean cccNoMatchCAS() {
 115         AtomicReference<TestObject> a = new AtomicReference<>(null);
 116         return a.compareAndSet(OBJ1, OBJ2);
 117     }
 118 
 119     @Test
 120     public void testcccNoMatchCAS() {
 121         testAtomicVirtualization("cccNoMatchCAS", JavaConstant.INT_0);
 122     }
 123 
 124     public static Object cccNoMatchCAE() {
 125         AtomicReference<TestObject> a = new AtomicReference<>(null);
 126         return a.compareAndExchange(OBJ1, OBJ2);
 127     }
 128 
 129     @Test
 130     public void testcccNoMatchCAE() {
 131         testAtomicVirtualization("cccNoMatchCAE", JavaConstant.NULL_POINTER);
 132     }
 133 
 134     public static boolean ccvCAS() {
 135         AtomicReference<TestObject> a = new AtomicReference<>(null);
 136         return a.compareAndSet(null, new TestObject(3));
 137     }
 138 
 139     @Test
 140     public void testccvCAS() {
 141         testAtomicVirtualization("ccvCAS", JavaConstant.INT_1);
 142     }
 143 
 144     public static Object ccvCAE() {
 145         AtomicReference<TestObject> a = new AtomicReference<>(null);
 146         return a.compareAndExchange(null, new TestObject(3));
 147     }
 148 
 149     @Test
 150     public void testccvCAE() {
 151         testAtomicVirtualization("ccvCAE", null, 0);
 152     }
 153 
 154     public static boolean cccCAS() {
 155         AtomicReference<TestObject> a = new AtomicReference<>(null);
 156         return a.compareAndSet(null, OBJ2);
 157     }
 158 
 159     @Test
 160     public void testcccCAS() {
 161         testAtomicVirtualization("cccCAS", JavaConstant.INT_1);
 162     }
 163 
 164     public static Object cccCAE() {
 165         AtomicReference<TestObject> a = new AtomicReference<>(null);
 166         return a.compareAndExchange(null, OBJ2);
 167     }
 168 
 169     @Test
 170     public void testcccCAE() {
 171         testAtomicVirtualization("cccCAE", null);
 172     }
 173 
 174     public static boolean vvvNoMatchCAS() {
 175         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 176         return a.compareAndSet(new TestObject(4), new TestObject(5));
 177     }
 178 
 179     @Test
 180     public void testvvvNoMatchCAS() {
 181         testAtomicVirtualization("vvvNoMatchCAS", JavaConstant.INT_0);
 182     }
 183 
 184     public static Object vvvNoMatchCAE() {
 185         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 186         return a.compareAndExchange(new TestObject(4), new TestObject(5));
 187     }
 188 
 189     @Test
 190     public void testvvvNoMatchCAE() {
 191         testAtomicVirtualization("vvvNoMatchCAE", null, 1);
 192     }
 193 
 194     public static boolean vcvNoMatchCAS() {
 195         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 196         return a.compareAndSet(OBJ1, new TestObject(4));
 197     }
 198 
 199     @Test
 200     public void testvcvNoMatchCAS() {
 201         testAtomicVirtualization("vcvNoMatchCAS", JavaConstant.INT_0);
 202     }
 203 
 204     public static Object vcvNoMatchCAE() {
 205         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 206         return a.compareAndExchange(OBJ1, new TestObject(4));
 207     }
 208 
 209     @Test
 210     public void testvcvNoMatchCAE() {
 211         testAtomicVirtualization("vcvNoMatchCAE", null, 1);
 212     }
 213 
 214     public static boolean vccNoMatchCAS() {
 215         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 216         return a.compareAndSet(OBJ1, OBJ2);
 217     }
 218 
 219     @Test
 220     public void testvccNoMatchCAS() {
 221         testAtomicVirtualization("vccNoMatchCAS", JavaConstant.INT_0);
 222     }
 223 
 224     public static Object vccNoMatchCAE() {
 225         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 226         return a.compareAndExchange(OBJ1, OBJ2);
 227     }
 228 
 229     @Test
 230     public void testvccNoMatchCAE() {
 231         testAtomicVirtualization("vccNoMatchCAE", null, 1);
 232     }
 233 
 234     public static boolean uvvCAS() {
 235         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 236         return a.compareAndSet(new TestObject(3), new TestObject(4));
 237     }
 238 
 239     @Test
 240     public void testuvvCAS() {
 241         testAtomicVirtualization("uvvCAS", JavaConstant.INT_0);
 242     }
 243 
 244     public static Object uvvCAE() {
 245         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 246         return a.compareAndExchange(new TestObject(3), new TestObject(4));
 247     }
 248 
 249     @Test
 250     public void testuvvCAE() {
 251         testAtomicVirtualization("uvvCAE", null);
 252     }
 253 
 254     public static boolean uuvCAS() {
 255         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 256         return a.compareAndSet(obj7, new TestObject(3));
 257     }
 258 
 259     @Test
 260     public void testuuvCAS() {
 261         testAtomicVirtualization("uuvCAS", null, 2);
 262     }
 263 
 264     public static Object uuvCAE() {
 265         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 266         return a.compareAndExchange(obj7, new TestObject(3));
 267     }
 268 
 269     @Test
 270     public void testuuvCAE() {
 271         testAtomicVirtualization("uuvCAE", null, 2);
 272     }
 273 
 274     public static boolean uuuCAS() {
 275         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 276         return a.compareAndSet(obj7, obj8);
 277     }
 278 
 279     @Test
 280     public void testuuuCAS() {
 281         testAtomicVirtualization("uuuCAS", null);
 282     }
 283 
 284     public static Object uuuCAE() {
 285         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
 286         return a.compareAndExchange(obj7, obj8);
 287     }
 288 
 289     @Test
 290     public void testuuuCAE() {
 291         testAtomicVirtualization("uuuCAE", null);
 292     }
 293 
 294     public static boolean vuvCAS() {
 295         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 296         return a.compareAndSet(obj6, new TestObject(4));
 297     }
 298 
 299     @Test
 300     public void testvuvCAS() {
 301         testAtomicVirtualization("vuvCAS", JavaConstant.INT_0);
 302     }
 303 
 304     public static Object vuvCAE() {
 305         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 306         return a.compareAndExchange(obj6, new TestObject(4));
 307     }
 308 
 309     @Test
 310     public void testvuvCAE() {
 311         testAtomicVirtualization("vuvCAE", null, 1);
 312     }
 313 
 314     public static boolean vuuCAS() {
 315         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 316         return a.compareAndSet(obj6, obj7);
 317     }
 318 
 319     @Test
 320     public void testvuuCAS() {
 321         testAtomicVirtualization("vuuCAS", JavaConstant.INT_0);
 322     }
 323 
 324     public static Object vuuCAE() {
 325         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
 326         return a.compareAndExchange(obj6, obj7);
 327     }
 328 
 329     @Test
 330     public void testvuuCAE() {
 331         testAtomicVirtualization("vuuCAE", null, 1);
 332     }
 333 
 334     private void testAtomicVirtualization(String snippet, JavaConstant expectedValue) {
 335         testAtomicVirtualization(snippet, expectedValue, 0);
 336     }
 337 
 338     protected void testAtomicVirtualization(String snippet, JavaConstant expectedValue, int expectedAllocations) {
 339         testEscapeAnalysis(snippet, expectedValue, false, expectedAllocations);
 340         test(snippet);
 341     }
 342 }