UnsafeEATest.java revision 13386:5f8ac59b3d63
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    private static final long byteArrayBaseOffset;
42    private static final long intArrayBaseOffset;
43    private static final long longArrayBaseOffset;
44
45    static {
46        try {
47            long localFieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("x"));
48            // Make the fields 8 byte aligned (Required for testing setLong on Architectures which
49            // does not support unaligned memory access
50            if (localFieldOffset1 % 8 == 0) {
51                fieldOffset1 = localFieldOffset1;
52                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
53            } else {
54                fieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y"));
55                fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("z"));
56            }
57            assert fieldOffset2 == fieldOffset1 + 4;
58            byteArrayBaseOffset = UNSAFE.arrayBaseOffset(byte[].class);
59            intArrayBaseOffset = UNSAFE.arrayBaseOffset(int[].class);
60            longArrayBaseOffset = UNSAFE.arrayBaseOffset(long[].class);
61        } catch (Exception e) {
62            throw new RuntimeException(e);
63        }
64    }
65
66    @Test
67    public void testSimpleInt() {
68        testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false);
69    }
70
71    public static int testSimpleIntSnippet() {
72        TestClassInt x = new TestClassInt();
73        UNSAFE.putInt(x, fieldOffset1, 101);
74        return UNSAFE.getInt(x, fieldOffset1);
75    }
76
77    @Test
78    public void testMaterializedInt() {
79        test("testMaterializedIntSnippet");
80    }
81
82    public static TestClassInt testMaterializedIntSnippet() {
83        TestClassInt x = new TestClassInt();
84        UNSAFE.putInt(x, fieldOffset1, 101);
85        return x;
86    }
87
88    @Test
89    public void testSimpleDouble() {
90        testEscapeAnalysis("testSimpleDoubleSnippet", JavaConstant.forDouble(10.1), false);
91    }
92
93    public static double testSimpleDoubleSnippet() {
94        TestClassInt x = new TestClassInt();
95        UNSAFE.putDouble(x, fieldOffset1, 10.1);
96        return UNSAFE.getDouble(x, fieldOffset1);
97    }
98
99    @Test
100    public void testMergedDouble() {
101        testEscapeAnalysis("testMergedDoubleSnippet", null, false);
102        Assert.assertEquals(1, returnNodes.size());
103        Assert.assertTrue(returnNodes.get(0).result() instanceof ValuePhiNode);
104        PhiNode phi = (PhiNode) returnNodes.get(0).result();
105        Assert.assertTrue(phi.valueAt(0) instanceof LoadFieldNode);
106        Assert.assertTrue(phi.valueAt(1) instanceof LoadFieldNode);
107    }
108
109    public static double testMergedDoubleSnippet(boolean a) {
110        TestClassInt x;
111        if (a) {
112            x = new TestClassInt(0, 0);
113            UNSAFE.putDouble(x, fieldOffset1, doubleField);
114        } else {
115            x = new TestClassInt();
116            UNSAFE.putDouble(x, fieldOffset1, doubleField2);
117        }
118        return UNSAFE.getDouble(x, fieldOffset1);
119    }
120
121    @Test
122    public void testMaterializedDouble() {
123        test("testMaterializedDoubleSnippet");
124    }
125
126    public static TestClassInt testMaterializedDoubleSnippet() {
127        TestClassInt x = new TestClassInt();
128        UNSAFE.putDouble(x, fieldOffset1, 10.1);
129        return x;
130    }
131
132    @Test
133    public void testDeoptDoubleVar() {
134        test("testDeoptDoubleVarSnippet");
135    }
136
137    public static double doubleField = 10.1e99;
138    public static double doubleField2;
139
140    public static TestClassInt testDeoptDoubleVarSnippet() {
141        TestClassInt x = new TestClassInt();
142        UNSAFE.putDouble(x, fieldOffset1, doubleField);
143        doubleField2 = 123;
144        try {
145            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
146        } catch (RuntimeException e) {
147            return x;
148        }
149        return x;
150    }
151
152    @Test
153    public void testDeoptDoubleConstant() {
154        test("testDeoptDoubleConstantSnippet");
155    }
156
157    public static TestClassInt testDeoptDoubleConstantSnippet() {
158        TestClassInt x = new TestClassInt();
159        UNSAFE.putDouble(x, fieldOffset1, 10.123);
160        doubleField2 = 123;
161        try {
162            doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero;
163        } catch (RuntimeException e) {
164            return x;
165        }
166        return x;
167    }
168
169    @Test
170    public void testDeoptLongVar() {
171        test("testDeoptLongVarSnippet");
172    }
173
174    public static long longField = 0x133443218aaaffffL;
175    public static long longField2;
176
177    public static TestClassInt testDeoptLongVarSnippet() {
178        TestClassInt x = new TestClassInt();
179        UNSAFE.putLong(x, fieldOffset1, longField);
180        longField2 = 123;
181        try {
182            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
183        } catch (RuntimeException e) {
184            return x;
185        }
186        return x;
187    }
188
189    @Test
190    public void testDeoptLongConstant() {
191        test("testDeoptLongConstantSnippet");
192    }
193
194    public static TestClassInt testDeoptLongConstantSnippet() {
195        TestClassInt x = new TestClassInt();
196        UNSAFE.putLong(x, fieldOffset1, 0x2222222210123L);
197        longField2 = 123;
198        try {
199            longField = UNSAFE.getLong(x, fieldOffset1) / zero;
200        } catch (RuntimeException e) {
201            return x;
202        }
203        return x;
204    }
205
206    public static int testWriteIntToByteArraySnippet() {
207        byte[] array = new byte[4];
208        UNSAFE.putInt(array, byteArrayBaseOffset, 0x01020304);
209        return array[0];
210    }
211
212    @Test
213    public void testWriteIntToByteArray() {
214        test("testWriteIntToByteArraySnippet");
215    }
216
217    public static byte testWriteSignedExtendedByteToByteArraySnippet(byte b) {
218        byte[] array = new byte[4];
219        array[0] = 0x01;
220        array[1] = 0x02;
221        array[2] = 0x03;
222        array[3] = 0x04;
223        UNSAFE.putInt(array, byteArrayBaseOffset, b);
224        return array[3];
225    }
226
227    @Test
228    public void testWriteSignedExtendedByteToByteArray() {
229        test("testWriteSignedExtendedByteToByteArraySnippet", (byte) 0);
230    }
231
232    public static int testWriteLongToIntArraySnippet() {
233        int[] array = new int[2];
234        UNSAFE.putLong(array, intArrayBaseOffset, 0x0102030405060708L);
235        return array[0];
236    }
237
238    @Test
239    public void testWriteLongToIntArray() {
240        test("testWriteLongToIntArraySnippet");
241    }
242
243    public static int testWriteByteToIntArraySnippet() {
244        int[] array = new int[1];
245        array[0] = 0x01020304;
246        UNSAFE.putByte(array, intArrayBaseOffset, (byte) 0x05);
247        return array[0];
248    }
249
250    @Test
251    public void testWriteByteToIntArray() {
252        test("testWriteByteToIntArraySnippet");
253    }
254
255    public static long testWriteIntToLongArraySnippet() {
256        long[] array = new long[1];
257        array[0] = 0x0102030405060708L;
258        UNSAFE.putInt(array, longArrayBaseOffset, 0x04030201);
259        return array[0];
260    }
261
262    @Test
263    public void testWriteIntToLongArray() {
264        test("testWriteIntToLongArraySnippet");
265    }
266
267    public static float testWriteFloatToIntArraySnippet() {
268        float[] array = new float[1];
269        UNSAFE.putInt(array, intArrayBaseOffset, Float.floatToRawIntBits(0.5f));
270        return array[0];
271    }
272
273    @Test
274    public void testWriteFloatToIntArray() {
275        test("testWriteFloatToIntArraySnippet");
276    }
277
278}
279