46 |
46 |
47 public class UnsafeEATest extends EATestBase { |
47 public class UnsafeEATest extends EATestBase { |
48 |
48 |
49 public static int zero = 0; |
49 public static int zero = 0; |
50 |
50 |
51 private static final long fieldOffset1; |
|
52 private static final long fieldOffset2; |
|
53 |
|
54 static { |
|
55 try { |
|
56 long localFieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("x")); |
|
57 // Make the fields 8 byte aligned (Required for testing setLong on Architectures which |
|
58 // does not support unaligned memory access |
|
59 if (localFieldOffset1 % 8 == 0) { |
|
60 fieldOffset1 = localFieldOffset1; |
|
61 fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y")); |
|
62 } else { |
|
63 fieldOffset1 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("y")); |
|
64 fieldOffset2 = UNSAFE.objectFieldOffset(TestClassInt.class.getField("z")); |
|
65 } |
|
66 assert fieldOffset2 == fieldOffset1 + 4; |
|
67 } catch (Exception e) { |
|
68 throw new RuntimeException(e); |
|
69 } |
|
70 } |
|
71 |
|
72 @Override |
51 @Override |
73 protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) { |
52 protected void testEscapeAnalysis(String snippet, JavaConstant expectedConstantResult, boolean iterativeEscapeAnalysis) { |
74 // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been |
53 // Exercise both a graph containing UnsafeAccessNodes and one which has been possibly been |
75 // canonicalized into AccessFieldNodes. |
54 // canonicalized into AccessFieldNodes. |
76 testingUnsafe = true; |
55 testingUnsafe = true; |
132 testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false); |
111 testEscapeAnalysis("testSimpleIntSnippet", JavaConstant.forInt(101), false); |
133 } |
112 } |
134 |
113 |
135 public static int testSimpleIntSnippet() { |
114 public static int testSimpleIntSnippet() { |
136 TestClassInt x = new TestClassInt(); |
115 TestClassInt x = new TestClassInt(); |
137 UNSAFE.putInt(x, fieldOffset1, 101); |
116 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 101); |
138 return UNSAFE.getInt(x, fieldOffset1); |
117 return UNSAFE.getInt(x, TestClassInt.fieldOffset1); |
139 } |
118 } |
140 |
119 |
141 @Test |
120 @Test |
142 public void testMaterializedInt() { |
121 public void testMaterializedInt() { |
143 test("testMaterializedIntSnippet"); |
122 test("testMaterializedIntSnippet"); |
144 } |
123 } |
145 |
124 |
146 public static TestClassInt testMaterializedIntSnippet() { |
125 public static TestClassInt testMaterializedIntSnippet() { |
147 TestClassInt x = new TestClassInt(); |
126 TestClassInt x = new TestClassInt(); |
148 UNSAFE.putInt(x, fieldOffset1, 101); |
127 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 101); |
149 return x; |
128 return x; |
150 } |
129 } |
151 |
130 |
152 @Test |
131 @Test |
153 public void testSimpleDouble() { |
132 public void testSimpleDouble() { |
154 testEscapeAnalysis("testSimpleDoubleSnippet", JavaConstant.forDouble(10.1), false); |
133 testEscapeAnalysis("testSimpleDoubleSnippet", JavaConstant.forDouble(10.1), false); |
155 } |
134 } |
156 |
135 |
157 public static double testSimpleDoubleSnippet() { |
136 public static double testSimpleDoubleSnippet() { |
158 TestClassInt x = new TestClassInt(); |
137 TestClassInt x = new TestClassInt(); |
159 UNSAFE.putDouble(x, fieldOffset1, 10.1); |
138 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1); |
160 return UNSAFE.getDouble(x, fieldOffset1); |
139 return UNSAFE.getDouble(x, TestClassInt.fieldOffset1); |
161 } |
140 } |
162 |
141 |
163 @Test |
142 @Test |
164 public void testSimpleDoubleOverwriteWithInt() { |
143 public void testSimpleDoubleOverwriteWithInt() { |
165 testEscapeAnalysis("testSimpleDoubleOverwriteWithIntSnippet", JavaConstant.forInt(10), false); |
144 testEscapeAnalysis("testSimpleDoubleOverwriteWithIntSnippet", JavaConstant.forInt(10), false); |
166 } |
145 } |
167 |
146 |
168 public static int testSimpleDoubleOverwriteWithIntSnippet() { |
147 public static int testSimpleDoubleOverwriteWithIntSnippet() { |
169 TestClassInt x = new TestClassInt(); |
148 TestClassInt x = new TestClassInt(); |
170 UNSAFE.putDouble(x, fieldOffset1, 10.1); |
149 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1); |
171 UNSAFE.putInt(x, fieldOffset1, 10); |
150 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10); |
172 return UNSAFE.getInt(x, fieldOffset1); |
151 return UNSAFE.getInt(x, TestClassInt.fieldOffset1); |
173 } |
152 } |
174 |
153 |
175 @Test |
154 @Test |
176 public void testSimpleDoubleOverwriteWithSecondInt() { |
155 public void testSimpleDoubleOverwriteWithSecondInt() { |
177 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
156 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
181 testEscapeAnalysis("testSimpleDoubleOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false); |
160 testEscapeAnalysis("testSimpleDoubleOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false); |
182 } |
161 } |
183 |
162 |
184 public static int testSimpleDoubleOverwriteWithSecondIntSnippet() { |
163 public static int testSimpleDoubleOverwriteWithSecondIntSnippet() { |
185 TestClassInt x = new TestClassInt(); |
164 TestClassInt x = new TestClassInt(); |
186 UNSAFE.putDouble(x, fieldOffset1, 10.1); |
165 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1); |
187 UNSAFE.putInt(x, fieldOffset1, 10); |
166 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10); |
188 return UNSAFE.getInt(x, fieldOffset2); |
167 return UNSAFE.getInt(x, TestClassInt.fieldOffset2); |
189 } |
168 } |
190 |
169 |
191 @Test |
170 @Test |
192 public void testSimpleDoubleOverwriteWithFirstInt() { |
171 public void testSimpleDoubleOverwriteWithFirstInt() { |
193 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
172 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
197 testEscapeAnalysis("testSimpleDoubleOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false); |
176 testEscapeAnalysis("testSimpleDoubleOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false); |
198 } |
177 } |
199 |
178 |
200 public static int testSimpleDoubleOverwriteWithFirstIntSnippet() { |
179 public static int testSimpleDoubleOverwriteWithFirstIntSnippet() { |
201 TestClassInt x = new TestClassInt(); |
180 TestClassInt x = new TestClassInt(); |
202 UNSAFE.putDouble(x, fieldOffset1, 10.1); |
181 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1); |
203 UNSAFE.putInt(x, fieldOffset2, 10); |
182 UNSAFE.putInt(x, TestClassInt.fieldOffset2, 10); |
204 return UNSAFE.getInt(x, fieldOffset1); |
183 return UNSAFE.getInt(x, TestClassInt.fieldOffset1); |
205 } |
184 } |
206 |
185 |
207 @Test |
186 @Test |
208 public void testSimpleLongOverwriteWithSecondInt() { |
187 public void testSimpleLongOverwriteWithSecondInt() { |
209 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
188 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
213 testEscapeAnalysis("testSimpleLongOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false); |
192 testEscapeAnalysis("testSimpleLongOverwriteWithSecondIntSnippet", JavaConstant.forInt(value), false); |
214 } |
193 } |
215 |
194 |
216 public static int testSimpleLongOverwriteWithSecondIntSnippet() { |
195 public static int testSimpleLongOverwriteWithSecondIntSnippet() { |
217 TestClassInt x = new TestClassInt(); |
196 TestClassInt x = new TestClassInt(); |
218 UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L); |
197 UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x1122334455667788L); |
219 UNSAFE.putInt(x, fieldOffset1, 10); |
198 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 10); |
220 return UNSAFE.getInt(x, fieldOffset2); |
199 return UNSAFE.getInt(x, TestClassInt.fieldOffset2); |
221 } |
200 } |
222 |
201 |
223 @Test |
202 @Test |
224 public void testSimpleLongOverwriteWithFirstInt() { |
203 public void testSimpleLongOverwriteWithFirstInt() { |
225 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
204 ByteBuffer bb = ByteBuffer.allocate(8).order(getTarget().arch.getByteOrder()); |
229 testEscapeAnalysis("testSimpleLongOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false); |
208 testEscapeAnalysis("testSimpleLongOverwriteWithFirstIntSnippet", JavaConstant.forInt(value), false); |
230 } |
209 } |
231 |
210 |
232 public static int testSimpleLongOverwriteWithFirstIntSnippet() { |
211 public static int testSimpleLongOverwriteWithFirstIntSnippet() { |
233 TestClassInt x = new TestClassInt(); |
212 TestClassInt x = new TestClassInt(); |
234 UNSAFE.putLong(x, fieldOffset1, 0x1122334455667788L); |
213 UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x1122334455667788L); |
235 UNSAFE.putInt(x, fieldOffset2, 10); |
214 UNSAFE.putInt(x, TestClassInt.fieldOffset2, 10); |
236 return UNSAFE.getInt(x, fieldOffset1); |
215 return UNSAFE.getInt(x, TestClassInt.fieldOffset1); |
237 } |
216 } |
238 |
217 |
239 @Test |
218 @Test |
240 public void testMergedDouble() { |
219 public void testMergedDouble() { |
241 testEscapeAnalysis("testMergedDoubleSnippet", null, false); |
220 testEscapeAnalysis("testMergedDoubleSnippet", null, false); |
248 |
227 |
249 public static double testMergedDoubleSnippet(boolean a) { |
228 public static double testMergedDoubleSnippet(boolean a) { |
250 TestClassInt x; |
229 TestClassInt x; |
251 if (a) { |
230 if (a) { |
252 x = new TestClassInt(0, 0); |
231 x = new TestClassInt(0, 0); |
253 UNSAFE.putDouble(x, fieldOffset1, doubleField); |
232 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField); |
254 } else { |
233 } else { |
255 x = new TestClassInt(); |
234 x = new TestClassInt(); |
256 UNSAFE.putDouble(x, fieldOffset1, doubleField2); |
235 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField2); |
257 } |
236 } |
258 return UNSAFE.getDouble(x, fieldOffset1); |
237 return UNSAFE.getDouble(x, TestClassInt.fieldOffset1); |
259 } |
238 } |
260 |
239 |
261 static class ExtendedTestClassInt extends TestClassInt { |
240 static class ExtendedTestClassInt extends TestClassInt { |
262 public long l; |
241 public long l; |
263 } |
242 } |
269 |
248 |
270 public static TestClassInt testMergedVirtualObjectsSnippet(int value) { |
249 public static TestClassInt testMergedVirtualObjectsSnippet(int value) { |
271 TestClassInt x; |
250 TestClassInt x; |
272 if (value == 1) { |
251 if (value == 1) { |
273 x = new TestClassInt(); |
252 x = new TestClassInt(); |
274 UNSAFE.putDouble(x, fieldOffset1, 10); |
253 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10); |
275 } else { |
254 } else { |
276 x = new TestClassInt(); |
255 x = new TestClassInt(); |
277 UNSAFE.putInt(x, fieldOffset1, 0); |
256 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 0); |
278 } |
257 } |
279 UNSAFE.putInt(x, fieldOffset1, 0); |
258 UNSAFE.putInt(x, TestClassInt.fieldOffset1, 0); |
280 if (value == 2) { |
259 if (value == 2) { |
281 UNSAFE.putInt(x, fieldOffset2, 0); |
260 UNSAFE.putInt(x, TestClassInt.fieldOffset2, 0); |
282 } |
261 } |
283 GraalDirectives.deoptimizeAndInvalidate(); |
262 GraalDirectives.deoptimizeAndInvalidate(); |
284 return x; |
263 return x; |
285 } |
264 } |
286 |
265 |
303 public static double doubleField = 10.1e99; |
282 public static double doubleField = 10.1e99; |
304 public static double doubleField2; |
283 public static double doubleField2; |
305 |
284 |
306 public static TestClassInt testDeoptDoubleVarSnippet() { |
285 public static TestClassInt testDeoptDoubleVarSnippet() { |
307 TestClassInt x = new TestClassInt(); |
286 TestClassInt x = new TestClassInt(); |
308 UNSAFE.putDouble(x, fieldOffset1, doubleField); |
287 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, doubleField); |
309 doubleField2 = 123; |
288 doubleField2 = 123; |
310 try { |
289 try { |
311 doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero; |
290 doubleField = ((int) UNSAFE.getDouble(x, TestClassInt.fieldOffset1)) / zero; |
312 } catch (RuntimeException e) { |
291 } catch (RuntimeException e) { |
313 return x; |
292 return x; |
314 } |
293 } |
315 return x; |
294 return x; |
316 } |
295 } |
320 test("testDeoptDoubleConstantSnippet"); |
299 test("testDeoptDoubleConstantSnippet"); |
321 } |
300 } |
322 |
301 |
323 public static TestClassInt testDeoptDoubleConstantSnippet() { |
302 public static TestClassInt testDeoptDoubleConstantSnippet() { |
324 TestClassInt x = new TestClassInt(); |
303 TestClassInt x = new TestClassInt(); |
325 UNSAFE.putDouble(x, fieldOffset1, 10.123); |
304 UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.123); |
326 doubleField2 = 123; |
305 doubleField2 = 123; |
327 try { |
306 try { |
328 doubleField = ((int) UNSAFE.getDouble(x, fieldOffset1)) / zero; |
307 doubleField = ((int) UNSAFE.getDouble(x, TestClassInt.fieldOffset1)) / zero; |
329 } catch (RuntimeException e) { |
308 } catch (RuntimeException e) { |
330 return x; |
309 return x; |
331 } |
310 } |
332 return x; |
311 return x; |
333 } |
312 } |
340 public static long longField = 0x133443218aaaffffL; |
319 public static long longField = 0x133443218aaaffffL; |
341 public static long longField2; |
320 public static long longField2; |
342 |
321 |
343 public static TestClassInt testDeoptLongVarSnippet() { |
322 public static TestClassInt testDeoptLongVarSnippet() { |
344 TestClassInt x = new TestClassInt(); |
323 TestClassInt x = new TestClassInt(); |
345 UNSAFE.putLong(x, fieldOffset1, longField); |
324 UNSAFE.putLong(x, TestClassInt.fieldOffset1, longField); |
346 longField2 = 123; |
325 longField2 = 123; |
347 try { |
326 try { |
348 longField = UNSAFE.getLong(x, fieldOffset1) / zero; |
327 longField = UNSAFE.getLong(x, TestClassInt.fieldOffset1) / zero; |
349 } catch (RuntimeException e) { |
328 } catch (RuntimeException e) { |
350 return x; |
329 return x; |
351 } |
330 } |
352 return x; |
331 return x; |
353 } |
332 } |
357 test("testDeoptLongConstantSnippet"); |
336 test("testDeoptLongConstantSnippet"); |
358 } |
337 } |
359 |
338 |
360 public static TestClassInt testDeoptLongConstantSnippet() { |
339 public static TestClassInt testDeoptLongConstantSnippet() { |
361 TestClassInt x = new TestClassInt(); |
340 TestClassInt x = new TestClassInt(); |
362 UNSAFE.putLong(x, fieldOffset1, 0x2222222210123L); |
341 UNSAFE.putLong(x, TestClassInt.fieldOffset1, 0x2222222210123L); |
363 longField2 = 123; |
342 longField2 = 123; |
364 try { |
343 try { |
365 longField = UNSAFE.getLong(x, fieldOffset1) / zero; |
344 longField = UNSAFE.getLong(x, TestClassInt.fieldOffset1) / zero; |
366 } catch (RuntimeException e) { |
345 } catch (RuntimeException e) { |
367 return x; |
346 return x; |
368 } |
347 } |
369 return x; |
348 return x; |
370 } |
349 } |