src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ea/UnsafeEATest.java
changeset 59095 03fbcd06b4c0
parent 58877 aec7bf35d6f5
equal deleted inserted replaced
59094:5d4c3724e4c7 59095:03fbcd06b4c0
    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 
   289         test("testMaterializedDoubleSnippet");
   268         test("testMaterializedDoubleSnippet");
   290     }
   269     }
   291 
   270 
   292     public static TestClassInt testMaterializedDoubleSnippet() {
   271     public static TestClassInt testMaterializedDoubleSnippet() {
   293         TestClassInt x = new TestClassInt();
   272         TestClassInt x = new TestClassInt();
   294         UNSAFE.putDouble(x, fieldOffset1, 10.1);
   273         UNSAFE.putDouble(x, TestClassInt.fieldOffset1, 10.1);
   295         return x;
   274         return x;
   296     }
   275     }
   297 
   276 
   298     @Test
   277     @Test
   299     public void testDeoptDoubleVar() {
   278     public void testDeoptDoubleVar() {
   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     }