UnsafeEATest.java revision 12651:6ef01bd40ce2
1/*
2 * Copyright (c) 2011, 2014, 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 */
23package org.graalvm.compiler.core.test.ea;
24
25import jdk.vm.ci.meta.JavaConstant;
26
27import org.junit.Assert;
28import org.junit.Test;
29
30import org.graalvm.compiler.nodes.PhiNode;
31import org.graalvm.compiler.nodes.ValuePhiNode;
32import org.graalvm.compiler.nodes.java.LoadFieldNode;
33
34public class UnsafeEATest extends EATestBase {
35
36    public static int zero = 0;
37
38    private static final long fieldOffset1;
39    private static final long fieldOffset2;
40
41    static {
42        try {
43            long localFieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("x"));
44            // Make the fields 8 byte aligned (Required for testing setLong on Architectures which
45            // does not support unaligned memory access
46            if (localFieldOffset1 % 8 == 0) {
47                fieldOffset1 = localFieldOffset1;
48                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
49            } else {
50                fieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
51                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("z"));
52            }
53            assert fieldOffset2 == fieldOffset1 + 4;
54        } catch (Exception e) {
55            throw new RuntimeException(e);
56        }
57    }
58
59    @Test
60    public void testSimpleInt() {
61        testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false);
62    }
63
64    public static int testSimpleIntSnippet() {
65        TestClassInt x = new TestClassInt();
66        UNSAFE.putInt(x, fieldOffset1, 101);
67        return UNSAFE.getInt(x, fieldOffset1);
68    }
69
70    @Test
71    public void testMaterializedInt() {
72        test("testMaterializedIntSnippet");
73    }
74
75    public static TestClassInt testMaterializedIntSnippet() {
76        TestClassInt x = new TestClassInt();
77        UNSAFE.putInt(x, fieldOffset1, 101);
78        return x;
79    }
80
81    @Test
82    public void testSimpleDouble() {
83        testEscapeAnalysis("testSimpleDoubleSnippet", JavaConstant.forDouble(10.1), false);
84    }
85
86    public static double testSimpleDoubleSnippet() {
87        TestClassInt x = new TestClassInt();
88        UNSAFE.putDouble(x, fieldOffset1, 10.1);
89        return UNSAFE.getDouble(x, fieldOffset1);
90    }
91
92    @Test
93    public void testMergedDouble() {
94        testEscapeAnalysis("testMergedDoubleSnippet", null, false);
95        Assert.assertEquals(1, returnNodes.size());
96        Assert.assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
97        PhiNode phi = (PhiNode) returnNodes.get(0).result();
98        Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode);
99        Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode);
100    }
101
102    public static double testMergedDoubleSnippet(boolean a) {
103        TestClassInt x;
104        if (a) {
105            x = new TestClassInt(0, 0);
106            UNSAFE.putDouble(x, fieldOffset1, doubleField);
107        } else {
108            x = new TestClassInt();
109            UNSAFE.putDouble(x, fieldOffset1, doubleField2);
110        }
111        return UNSAFE.getDouble(x, fieldOffset1);
112    }
113
114    @Test
115    public void testMaterializedDouble() {
116        test("testMaterializedDoubleSnippet");
117    }
118
119    public static TestClassInt testMaterializedDoubleSnippet() {
120        TestClassInt x = new TestClassInt();
121        UNSAFE.putDouble(x, fieldOffset1, 10.1);
122        return x;
123    }
124
125    @Test
126    public void testDeoptDoubleVar() {
127        test("testDeoptDoubleVarSnippet");
128    }
129
130    public static double doubleField = 10.1e99;
131    public static double doubleField2;
132
133    public static TestClassInt testDeoptDoubleVarSnippet() {
134        TestClassInt x = new TestClassInt();
135        UNSAFE.putDouble(x, fieldOffset1, doubleField);
136        doubleField2 = 123;
137        try {
138            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
139        } catch (RuntimeException e) {
140            return x;
141        }
142        return x;
143    }
144
145    @Test
146    public void testDeoptDoubleConstant() {
147        test("testDeoptDoubleConstantSnippet");
148    }
149
150    public static TestClassInt testDeoptDoubleConstantSnippet() {
151        TestClassInt x = new TestClassInt();
152        UNSAFE.putDouble(x, fieldOffset1, 10.123);
153        doubleField2 = 123;
154        try {
155            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
156        } catch (RuntimeException e) {
157            return x;
158        }
159        return x;
160    }
161
162    @Test
163    public void testDeoptLongVar() {
164        test("testDeoptLongVarSnippet");
165    }
166
167    public static long longField = 0x133443218aaaffffL;
168    public static long longField2;
169
170    public static TestClassInt testDeoptLongVarSnippet() {
171        TestClassInt x = new TestClassInt();
172        UNSAFE.putLong(x, fieldOffset1, longField);
173        longField2 = 123;
174        try {
175            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
176        } catch (RuntimeException e) {
177            return x;
178        }
179        return x;
180    }
181
182    @Test
183    public void testDeoptLongConstant() {
184        test("testDeoptLongConstantSnippet");
185    }
186
187    public static TestClassInt testDeoptLongConstantSnippet() {
188        TestClassInt x = new TestClassInt();
189        UNSAFE.putLong(x, fieldOffset1, 0x2222222210123L);
190        longField2 = 123;
191        try {
192            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
193        } catch (RuntimeException e) {
194            return x;
195        }
196        return x;
197    }
198}
199