1 /*
2  * Copyright (c) 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 
TestObject(int id)45         private TestObject(int id) {
46             this.id = id;
47         }
48 
49         @Override
equals(Object o)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
hashCode()62         public int hashCode() {
63             return Objects.hash(id);
64         }
65 
66         @Override
toString()67         public String toString() {
68             return "TestObject{id=" + id + '}';
69         }
70     }
71 
72     // c = constant (heap-allocated); v = virtual; u = unknown (heap-allocated)
73 
cvvNoMatchCAS()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
testcvvNoMatchCAS()80     public void testcvvNoMatchCAS() {
81         testAtomicVirtualization("cvvNoMatchCAS", JavaConstant.INT_0);
82     }
83 
cvvNoMatchCAE()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
testcvvNoMatchCAE()90     public void testcvvNoMatchCAE() {
91         testAtomicVirtualization("cvvNoMatchCAE", JavaConstant.NULL_POINTER);
92     }
93 
ccvNoMatchCAS()94     public static boolean ccvNoMatchCAS() {
95         AtomicReference<TestObject> a = new AtomicReference<>(null);
96         return a.compareAndSet(OBJ1, new TestObject(3));
97     }
98 
99     @Test
testccvNoMatchCAS()100     public void testccvNoMatchCAS() {
101         testAtomicVirtualization("ccvNoMatchCAS", JavaConstant.INT_0);
102     }
103 
ccvNoMatchCAE()104     public static Object ccvNoMatchCAE() {
105         AtomicReference<TestObject> a = new AtomicReference<>(null);
106         return a.compareAndExchange(OBJ1, new TestObject(3));
107     }
108 
109     @Test
testccvNoMatchCAE()110     public void testccvNoMatchCAE() {
111         testAtomicVirtualization("ccvNoMatchCAE", JavaConstant.NULL_POINTER);
112     }
113 
cccNoMatchCAS()114     public static boolean cccNoMatchCAS() {
115         AtomicReference<TestObject> a = new AtomicReference<>(null);
116         return a.compareAndSet(OBJ1, OBJ2);
117     }
118 
119     @Test
testcccNoMatchCAS()120     public void testcccNoMatchCAS() {
121         testAtomicVirtualization("cccNoMatchCAS", JavaConstant.INT_0);
122     }
123 
cccNoMatchCAE()124     public static Object cccNoMatchCAE() {
125         AtomicReference<TestObject> a = new AtomicReference<>(null);
126         return a.compareAndExchange(OBJ1, OBJ2);
127     }
128 
129     @Test
testcccNoMatchCAE()130     public void testcccNoMatchCAE() {
131         testAtomicVirtualization("cccNoMatchCAE", JavaConstant.NULL_POINTER);
132     }
133 
ccvCAS()134     public static boolean ccvCAS() {
135         AtomicReference<TestObject> a = new AtomicReference<>(null);
136         return a.compareAndSet(null, new TestObject(3));
137     }
138 
139     @Test
testccvCAS()140     public void testccvCAS() {
141         testAtomicVirtualization("ccvCAS", JavaConstant.INT_1);
142     }
143 
ccvCAE()144     public static Object ccvCAE() {
145         AtomicReference<TestObject> a = new AtomicReference<>(null);
146         return a.compareAndExchange(null, new TestObject(3));
147     }
148 
149     @Test
testccvCAE()150     public void testccvCAE() {
151         testAtomicVirtualization("ccvCAE", null, 0);
152     }
153 
cccCAS()154     public static boolean cccCAS() {
155         AtomicReference<TestObject> a = new AtomicReference<>(null);
156         return a.compareAndSet(null, OBJ2);
157     }
158 
159     @Test
testcccCAS()160     public void testcccCAS() {
161         testAtomicVirtualization("cccCAS", JavaConstant.INT_1);
162     }
163 
cccCAE()164     public static Object cccCAE() {
165         AtomicReference<TestObject> a = new AtomicReference<>(null);
166         return a.compareAndExchange(null, OBJ2);
167     }
168 
169     @Test
testcccCAE()170     public void testcccCAE() {
171         testAtomicVirtualization("cccCAE", null);
172     }
173 
vvvNoMatchCAS()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
testvvvNoMatchCAS()180     public void testvvvNoMatchCAS() {
181         testAtomicVirtualization("vvvNoMatchCAS", JavaConstant.INT_0);
182     }
183 
vvvNoMatchCAE()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
testvvvNoMatchCAE()190     public void testvvvNoMatchCAE() {
191         testAtomicVirtualization("vvvNoMatchCAE", null, 1);
192     }
193 
vcvNoMatchCAS()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
testvcvNoMatchCAS()200     public void testvcvNoMatchCAS() {
201         testAtomicVirtualization("vcvNoMatchCAS", JavaConstant.INT_0);
202     }
203 
vcvNoMatchCAE()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
testvcvNoMatchCAE()210     public void testvcvNoMatchCAE() {
211         testAtomicVirtualization("vcvNoMatchCAE", null, 1);
212     }
213 
vccNoMatchCAS()214     public static boolean vccNoMatchCAS() {
215         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
216         return a.compareAndSet(OBJ1, OBJ2);
217     }
218 
219     @Test
testvccNoMatchCAS()220     public void testvccNoMatchCAS() {
221         testAtomicVirtualization("vccNoMatchCAS", JavaConstant.INT_0);
222     }
223 
vccNoMatchCAE()224     public static Object vccNoMatchCAE() {
225         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
226         return a.compareAndExchange(OBJ1, OBJ2);
227     }
228 
229     @Test
testvccNoMatchCAE()230     public void testvccNoMatchCAE() {
231         testAtomicVirtualization("vccNoMatchCAE", null, 1);
232     }
233 
uvvCAS()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
testuvvCAS()240     public void testuvvCAS() {
241         testAtomicVirtualization("uvvCAS", JavaConstant.INT_0);
242     }
243 
uvvCAE()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
testuvvCAE()250     public void testuvvCAE() {
251         testAtomicVirtualization("uvvCAE", null);
252     }
253 
uuvCAS()254     public static boolean uuvCAS() {
255         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
256         return a.compareAndSet(obj7, new TestObject(3));
257     }
258 
259     @Test
testuuvCAS()260     public void testuuvCAS() {
261         testAtomicVirtualization("uuvCAS", null, 2);
262     }
263 
uuvCAE()264     public static Object uuvCAE() {
265         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
266         return a.compareAndExchange(obj7, new TestObject(3));
267     }
268 
269     @Test
testuuvCAE()270     public void testuuvCAE() {
271         testAtomicVirtualization("uuvCAE", null, 2);
272     }
273 
uuuCAS()274     public static boolean uuuCAS() {
275         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
276         return a.compareAndSet(obj7, obj8);
277     }
278 
279     @Test
testuuuCAS()280     public void testuuuCAS() {
281         testAtomicVirtualization("uuuCAS", null);
282     }
283 
uuuCAE()284     public static Object uuuCAE() {
285         AtomicReference<TestObject> a = new AtomicReference<>(obj6);
286         return a.compareAndExchange(obj7, obj8);
287     }
288 
289     @Test
testuuuCAE()290     public void testuuuCAE() {
291         testAtomicVirtualization("uuuCAE", null);
292     }
293 
vuvCAS()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
testvuvCAS()300     public void testvuvCAS() {
301         testAtomicVirtualization("vuvCAS", JavaConstant.INT_0);
302     }
303 
vuvCAE()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
testvuvCAE()310     public void testvuvCAE() {
311         testAtomicVirtualization("vuvCAE", null, 1);
312     }
313 
vuuCAS()314     public static boolean vuuCAS() {
315         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
316         return a.compareAndSet(obj6, obj7);
317     }
318 
319     @Test
testvuuCAS()320     public void testvuuCAS() {
321         testAtomicVirtualization("vuuCAS", JavaConstant.INT_0);
322     }
323 
vuuCAE()324     public static Object vuuCAE() {
325         AtomicReference<TestObject> a = new AtomicReference<>(new TestObject(3));
326         return a.compareAndExchange(obj6, obj7);
327     }
328 
329     @Test
testvuuCAE()330     public void testvuuCAE() {
331         testAtomicVirtualization("vuuCAE", null, 1);
332     }
333 
testAtomicVirtualization(String snippet, JavaConstant expectedValue)334     private void testAtomicVirtualization(String snippet, JavaConstant expectedValue) {
335         testAtomicVirtualization(snippet, expectedValue, 0);
336     }
337 
testAtomicVirtualization(String snippet, JavaConstant expectedValue, int expectedAllocations)338     protected void testAtomicVirtualization(String snippet, JavaConstant expectedValue, int expectedAllocations) {
339         testEscapeAnalysis(snippet, expectedValue, false, expectedAllocations);
340         test(snippet);
341     }
342 }
343