37 import jdk.vm.ci.code.InstalledCode; |
36 import jdk.vm.ci.code.InstalledCode; |
38 import jdk.vm.ci.meta.ResolvedJavaMethod; |
37 import jdk.vm.ci.meta.ResolvedJavaMethod; |
39 |
38 |
40 public class UnsafeVirtualizationTest extends GraalCompilerTest { |
39 public class UnsafeVirtualizationTest extends GraalCompilerTest { |
41 |
40 |
42 public static class Base { |
|
43 /* |
|
44 * This padding ensure that the size of the Base class ends up as a multiple of 8, which |
|
45 * makes the first field of the subclass 8-byte aligned. |
|
46 */ |
|
47 double padding; |
|
48 } |
|
49 |
|
50 public static class A extends Base { |
|
51 int f1; |
|
52 int f2; |
|
53 } |
|
54 |
|
55 private static final long AF1Offset; |
|
56 private static final long AF2Offset; |
|
57 static { |
|
58 long o1 = -1; |
|
59 long o2 = -1; |
|
60 try { |
|
61 Field f1 = A.class.getDeclaredField("f1"); |
|
62 Field f2 = A.class.getDeclaredField("f2"); |
|
63 o1 = UNSAFE.objectFieldOffset(f1); |
|
64 o2 = UNSAFE.objectFieldOffset(f2); |
|
65 } catch (NoSuchFieldException | SecurityException e) { |
|
66 throw new AssertionError(e); |
|
67 } |
|
68 AF1Offset = o1; |
|
69 AF2Offset = o2; |
|
70 } |
|
71 |
|
72 public static int unsafeSnippet1(double i1) { |
41 public static int unsafeSnippet1(double i1) { |
73 A a = new A(); |
42 TestClassInt a = new TestClassInt(); |
74 UNSAFE.putDouble(a, AF1Offset, i1); |
43 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
75 return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset); |
44 return UNSAFE.getInt(a, TestClassInt.fieldOffset1) + UNSAFE.getInt(a, TestClassInt.fieldOffset2); |
76 } |
45 } |
77 |
46 |
78 public static long unsafeSnippet2a(int i1) { |
47 public static long unsafeSnippet2a(int i1) { |
79 A a = new A(); |
48 TestClassInt a = new TestClassInt(); |
80 UNSAFE.putDouble(a, AF1Offset, i1); |
49 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
81 a.f1 = i1; |
50 a.setFirstField(i1); |
82 return UNSAFE.getLong(a, AF1Offset); |
51 return UNSAFE.getLong(a, TestClassInt.fieldOffset1); |
83 } |
52 } |
84 |
53 |
85 public static long unsafeSnippet2b(int i1) { |
54 public static long unsafeSnippet2b(int i1) { |
86 A a = new A(); |
55 TestClassInt a = new TestClassInt(); |
87 UNSAFE.putDouble(a, AF1Offset, i1); |
56 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
88 a.f2 = i1; |
57 a.setSecondField(i1); |
89 return UNSAFE.getLong(a, AF1Offset); |
58 return UNSAFE.getLong(a, TestClassInt.fieldOffset1); |
90 } |
59 } |
91 |
60 |
92 public static long unsafeSnippet3a(int i1) { |
61 public static long unsafeSnippet3a(int i1) { |
93 A a = new A(); |
62 TestClassInt a = new TestClassInt(); |
94 UNSAFE.putDouble(a, AF1Offset, i1); |
63 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
95 UNSAFE.putInt(a, AF1Offset, i1); |
64 UNSAFE.putInt(a, TestClassInt.fieldOffset1, i1); |
96 return UNSAFE.getLong(a, AF1Offset); |
65 return UNSAFE.getLong(a, TestClassInt.fieldOffset1); |
97 } |
66 } |
98 |
67 |
99 public static long unsafeSnippet3b(int i1) { |
68 public static long unsafeSnippet3b(int i1) { |
100 A a = new A(); |
69 TestClassInt a = new TestClassInt(); |
101 UNSAFE.putDouble(a, AF1Offset, i1); |
70 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
102 UNSAFE.putInt(a, AF2Offset, i1); |
71 UNSAFE.putInt(a, TestClassInt.fieldOffset2, i1); |
103 return UNSAFE.getLong(a, AF1Offset); |
72 return UNSAFE.getLong(a, TestClassInt.fieldOffset1); |
104 } |
73 } |
105 |
74 |
106 public static int unsafeSnippet4(double i1) { |
75 public static int unsafeSnippet4(double i1) { |
107 A a = new A(); |
76 TestClassInt a = new TestClassInt(); |
108 UNSAFE.putDouble(a, AF1Offset, i1); |
77 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
109 UNSAFE.putDouble(a, AF1Offset, i1); |
78 UNSAFE.putDouble(a, TestClassInt.fieldOffset1, i1); |
110 return UNSAFE.getInt(a, AF1Offset) + UNSAFE.getInt(a, AF2Offset); |
79 return UNSAFE.getInt(a, TestClassInt.fieldOffset1) + UNSAFE.getInt(a, TestClassInt.fieldOffset2); |
111 } |
80 } |
112 |
81 |
113 @Test |
82 @Test |
114 public void testUnsafePEA01() { |
83 public void testUnsafePEA01() { |
115 testPartialEscapeReadElimination("unsafeSnippet1", false, 1.0); |
84 testPartialEscapeReadElimination("unsafeSnippet1", false, 1.0); |
139 testPartialEscapeReadElimination("unsafeSnippet4", false, 1.0); |
108 testPartialEscapeReadElimination("unsafeSnippet4", false, 1.0); |
140 testPartialEscapeReadElimination("unsafeSnippet4", true, 1.0); |
109 testPartialEscapeReadElimination("unsafeSnippet4", true, 1.0); |
141 } |
110 } |
142 |
111 |
143 public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) { |
112 public void testPartialEscapeReadElimination(String snippet, boolean canonicalizeBefore, Object... args) { |
144 assert AF1Offset % 8 == 0 : "First of the two int-fields must be 8-byte aligned"; |
113 assert TestClassInt.fieldOffset1 % 8 == 0 : "First of the two int-fields must be 8-byte aligned"; |
145 |
114 |
146 ResolvedJavaMethod method = getResolvedJavaMethod(snippet); |
115 ResolvedJavaMethod method = getResolvedJavaMethod(snippet); |
147 StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); |
116 StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); |
148 OptionValues options = graph.getOptions(); |
117 OptionValues options = graph.getOptions(); |
149 CoreProviders context = getDefaultHighTierContext(); |
118 CoreProviders context = getDefaultHighTierContext(); |