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 */ 23 package org.graalvm.compiler.core.test.ea; 24 25 import jdk.vm.ci.meta.JavaConstant; 26 27 import org.junit.Assert; 28 import org.junit.Test; 29 30 import org.graalvm.compiler.nodes.PhiNode; 31 import org.graalvm.compiler.nodes.ValuePhiNode; 32 import org.graalvm.compiler.nodes.java.LoadFieldNode; 33 34 public 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 }