src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/UnsafeVirtualizationTest.java
changeset 59095 03fbcd06b4c0
parent 58877 aec7bf35d6f5
equal deleted inserted replaced
59094:5d4c3724e4c7 59095:03fbcd06b4c0
    22  */
    22  */
    23 
    23 
    24 
    24 
    25 package org.graalvm.compiler.core.test;
    25 package org.graalvm.compiler.core.test;
    26 
    26 
    27 import java.lang.reflect.Field;
    27 import org.graalvm.compiler.core.test.ea.EATestBase.TestClassInt;
    28 
       
    29 import org.graalvm.compiler.nodes.StructuredGraph;
    28 import org.graalvm.compiler.nodes.StructuredGraph;
    30 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
    29 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
    31 import org.graalvm.compiler.nodes.spi.CoreProviders;
    30 import org.graalvm.compiler.nodes.spi.CoreProviders;
    32 import org.graalvm.compiler.options.OptionValues;
    31 import org.graalvm.compiler.options.OptionValues;
    33 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
    32 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
    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();