Skip to content

Commit e1e9a19

Browse files
committed
[GR-65415] Fixes for the extended dynamic object layout.
PullRequest: graal/21145
2 parents b8f4399 + 6efc1be commit e1e9a19

File tree

15 files changed

+322
-258
lines changed

15 files changed

+322
-258
lines changed

truffle/mx.truffle/mx_truffle.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,9 @@ def _truffle_gate_runner(args, tasks):
483483
with Task('Truffle Signature Tests', tasks, tags=TruffleGateTags.sigtest) as t:
484484
if t: sigtest(['--check', 'binary'])
485485
with Task('Truffle UnitTests', tasks, tags=TruffleGateTags.truffle_test) as t:
486-
if t: unittest(list(['--suite', 'truffle', '--enable-timing', '--verbose', '--max-class-failures=25']))
486+
if t:
487+
unittest(['--suite', 'truffle', '--enable-timing', '--verbose', '--max-class-failures=25'])
488+
unittest(['--suite', 'truffle', '--enable-timing', '-Dtruffle.object.LayoutFactory=com.oracle.truffle.api.object.CoreLayoutFactory', 'com.oracle.truffle.object'])
487489
if jdk.javaCompliance >= '22':
488490
with Task('Truffle NFI tests with Panama Backend', tasks, tags=TruffleGateTags.panama_test) as t:
489491
if t:

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/basic/test/DOTestAsserts.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
*/
4141
package com.oracle.truffle.object.basic.test;
4242

43+
import static org.hamcrest.CoreMatchers.either;
44+
import static org.hamcrest.CoreMatchers.endsWith;
45+
import static org.hamcrest.MatcherAssert.assertThat;
4346
import static org.junit.Assert.assertEquals;
4447
import static org.junit.Assert.assertTrue;
4548

@@ -141,6 +144,14 @@ public static Class<?> getLocationType(Location location) {
141144
}
142145
}
143146

147+
public static void assumeExtLayout() {
148+
Shape shape = Shape.newBuilder().build();
149+
assertThat("Unexpected Shape class name (the assertion may need to be updated if the code is refactored)",
150+
shape.getClass().getName(), either(endsWith("ShapeExt")).or(endsWith("ShapeBasic")));
151+
Assume.assumeTrue("Test is specific to the Extended Dynamic Object Layout",
152+
shape.getClass().getName().endsWith("ShapeExt"));
153+
}
154+
144155
public static Location assumeCoreLocation(Location location) {
145156
Assume.assumeTrue(isCoreLocation(location));
146157
return location;

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/ext/test/GR42603.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
*/
4141
package com.oracle.truffle.object.ext.test;
4242

43+
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assumeExtLayout;
44+
4345
import java.util.ArrayList;
4446
import java.util.List;
4547
import java.util.concurrent.ExecutionException;
@@ -54,7 +56,6 @@
5456
import com.oracle.truffle.api.object.DynamicObjectLibrary;
5557
import com.oracle.truffle.api.object.Shape;
5658
import com.oracle.truffle.object.ext.test.ObjectModelRegressionTest.TestDynamicObject;
57-
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
5859

5960
public class GR42603 {
6061

@@ -63,7 +64,7 @@ public class GR42603 {
6364

6465
@Test
6566
public void testReplacePropertyRace() throws Throwable {
66-
TruffleTestAssumptions.assumeEnterpriseRuntime();
67+
assumeExtLayout();
6768
for (int i = 0; i < 100; i++) {
6869
testConcurrentReplaceProperty();
6970
}

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/ext/test/GR52036.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.truffle.object.ext.test;
4242

43+
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assumeExtLayout;
4344
import static com.oracle.truffle.object.basic.test.DOTestAsserts.getTypeAssumption;
4445
import static com.oracle.truffle.object.basic.test.DOTestAsserts.getTypeAssumptionRecord;
4546
import static org.junit.Assert.assertFalse;
@@ -55,7 +56,6 @@
5556
import com.oracle.truffle.api.object.DynamicObject;
5657
import com.oracle.truffle.api.object.DynamicObjectLibrary;
5758
import com.oracle.truffle.api.object.Shape;
58-
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
5959

6060
public class GR52036 {
6161

@@ -70,7 +70,7 @@ public class GR52036 {
7070
@SuppressWarnings("try")
7171
@Test
7272
public void testGR52036Reproducer() throws Throwable {
73-
TruffleTestAssumptions.assumeEnterpriseRuntime();
73+
assumeExtLayout();
7474

7575
class ObjType1 extends DynamicObject {
7676
protected ObjType1(Shape shape) {

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/ext/test/ObjectModelRegressionTest.java

Lines changed: 150 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertObjectLocation;
4444
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertPrimitiveLocation;
45+
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assumeExtLayout;
4546
import static com.oracle.truffle.object.basic.test.DOTestAsserts.invokeGetter;
4647
import static org.junit.Assert.assertEquals;
4748
import static org.junit.Assert.assertFalse;
@@ -56,6 +57,8 @@
5657
import java.util.List;
5758
import java.util.Map;
5859

60+
import org.hamcrest.CoreMatchers;
61+
import org.hamcrest.MatcherAssert;
5962
import org.junit.Test;
6063
import org.junit.runner.RunWith;
6164
import org.junit.runners.Parameterized;
@@ -67,7 +70,6 @@
6770
import com.oracle.truffle.api.object.DynamicObjectLibrary;
6871
import com.oracle.truffle.api.object.Shape;
6972
import com.oracle.truffle.api.test.AbstractParametrizedLibraryTest;
70-
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
7173

7274
@SuppressWarnings("deprecation")
7375
@RunWith(Parameterized.class)
@@ -386,7 +388,7 @@ public void testChangeFlagsConstantToNonConstant() {
386388

387389
@Test
388390
public void testTryMergeShapes() {
389-
TruffleTestAssumptions.assumeEnterpriseRuntime();
391+
assumeExtLayout();
390392

391393
// Assume (MaxMergeDepth >= 5)
392394
Shape emptyShape = Shape.newBuilder().allowImplicitCastIntToDouble(true).build();
@@ -437,7 +439,7 @@ public void testTryMergeShapes() {
437439

438440
@Test
439441
public void testTryMergeShapes2() {
440-
TruffleTestAssumptions.assumeEnterpriseRuntime();
442+
assumeExtLayout();
441443

442444
// Assume (MaxMergeDepth >= 5 && MaxMergeDiff >= 2)
443445

@@ -473,6 +475,25 @@ public void testTryMergeShapes2() {
473475
assertSame(b.getShape(), a.getShape());
474476
}
475477

478+
@Test
479+
public void testBooleanLocationTypeAssumption() {
480+
assumeExtLayout();
481+
482+
Shape emptyShape = Shape.newBuilder().build();
483+
484+
DynamicObject obj = new TestDynamicObject(emptyShape);
485+
486+
DynamicObjectLibrary library = createLibrary(DynamicObjectLibrary.class, obj);
487+
488+
library.put(obj, "b1", true);
489+
library.put(obj, "b2", true);
490+
library.put(obj, "b2", false);
491+
492+
Shape shape = obj.getShape();
493+
MatcherAssert.assertThat(shape.getProperty("b1").getLocation().toString(), CoreMatchers.containsString("Boolean"));
494+
MatcherAssert.assertThat(shape.getProperty("b2").getLocation().toString(), CoreMatchers.containsString("Boolean"));
495+
}
496+
476497
/**
477498
* Tests that onPropertyTransition is called by replace and remove property transitions.
478499
*/
@@ -510,6 +531,132 @@ public void testPropertyAssumptionInvalidation() {
510531
assertFalse(assumption.toString(), assumption.isValid());
511532
}
512533

534+
/**
535+
* Tests that property assumptions are blocked after remove property transitions.
536+
*/
537+
@Test
538+
public void testPropertyAssumptionInvalidAfterRemove() {
539+
Shape emptyShape = Shape.newBuilder().propertyAssumptions(true).build();
540+
541+
DynamicObject h1 = new TestDynamicObject(emptyShape);
542+
DynamicObjectLibrary on = createLibrary(DynamicObjectLibrary.class, h1);
543+
DynamicObjectLibrary off = createLibrary(DynamicObjectLibrary.class, h1);
544+
545+
// initialize caches
546+
on.put(h1, "name", h1);
547+
on.put(h1, "alias", h1);
548+
off.removeKey(h1, "name");
549+
off.removeKey(h1, "alias");
550+
551+
DynamicObject h2 = new TestDynamicObject(emptyShape);
552+
// repeat on another object with cached transitions
553+
on.put(h2, "name", h2);
554+
on.put(h2, "alias", h2);
555+
556+
Assumption aliasAssumption = h2.getShape().getPropertyAssumption("alias");
557+
assertFalse("Property assumption for 'alias' should already be invalid: " + aliasAssumption, aliasAssumption.isValid());
558+
559+
on.put(h2, "alias", h2);
560+
off.removeKey(h2, "name");
561+
off.removeKey(h2, "alias");
562+
}
563+
564+
/**
565+
* Tests that property assumptions are blocked after replace property transitions.
566+
*/
567+
@Test
568+
public void testPropertyAssumptionInvalidAfterReplace1() {
569+
assumeExtLayout();
570+
571+
Shape emptyShape = Shape.newBuilder().propertyAssumptions(true).build();
572+
573+
int flag = 2;
574+
DynamicObject h1 = new TestDynamicObject(emptyShape);
575+
DynamicObjectLibrary on = createLibrary(DynamicObjectLibrary.class, h1);
576+
DynamicObjectLibrary off = createLibrary(DynamicObjectLibrary.class, h1);
577+
578+
// initialize caches
579+
on.put(h1, "name", h1);
580+
on.put(h1, "alias", h1);
581+
off.setPropertyFlags(h1, "name", flag);
582+
off.setPropertyFlags(h1, "alias", flag);
583+
584+
DynamicObject h2 = new TestDynamicObject(emptyShape);
585+
// repeat cached operations on another object
586+
on.put(h2, "name", h2);
587+
on.put(h2, "alias", h2);
588+
589+
Assumption aliasAssumption = h2.getShape().getPropertyAssumption("alias");
590+
assertFalse("Property assumption for 'alias' should already be invalid: " + aliasAssumption, aliasAssumption.isValid());
591+
592+
on.put(h2, "alias", h2);
593+
off.setPropertyFlags(h2, "name", flag);
594+
off.setPropertyFlags(h2, "alias", flag);
595+
596+
assertEquals(flag, h2.getShape().getProperty("name").getFlags());
597+
assertEquals(flag, h2.getShape().getProperty("alias").getFlags());
598+
}
599+
600+
/**
601+
* Tests that property assumptions are blocked after replace property transitions.
602+
*/
603+
@Test
604+
public void testPropertyAssumptionInvalidAfterReplace2() {
605+
assumeExtLayout();
606+
607+
Shape emptyShape = Shape.newBuilder().propertyAssumptions(true).build();
608+
609+
int flag = 2;
610+
DynamicObject h1 = new TestDynamicObject(emptyShape);
611+
DynamicObjectLibrary on = createLibrary(DynamicObjectLibrary.class, h1);
612+
DynamicObjectLibrary off = createLibrary(DynamicObjectLibrary.class, h1);
613+
614+
// initialize caches
615+
on.put(h1, "name", h1);
616+
on.put(h1, "alias", h1);
617+
off.putWithFlags(h1, "name", h1, flag);
618+
off.putWithFlags(h1, "alias", h1, flag);
619+
620+
DynamicObject h2 = new TestDynamicObject(emptyShape);
621+
// repeat cached operations on another object
622+
on.put(h2, "name", h2);
623+
on.put(h2, "alias", h2);
624+
625+
Assumption aliasAssumption = h2.getShape().getPropertyAssumption("alias");
626+
assertFalse("Property assumption for 'alias' should already be invalid: " + aliasAssumption, aliasAssumption.isValid());
627+
628+
on.put(h2, "alias", h2);
629+
off.putWithFlags(h2, "name", h2, flag);
630+
off.putWithFlags(h2, "alias", h2, flag);
631+
632+
assertEquals(flag, h2.getShape().getProperty("name").getFlags());
633+
assertEquals(flag, h2.getShape().getProperty("alias").getFlags());
634+
}
635+
636+
/**
637+
* Tests that property assumptions are invalid after value type transitions.
638+
*/
639+
@Test
640+
public void testPropertyAssumptionInvalidAfterTypeTransition() {
641+
Shape emptyShape = Shape.newBuilder().propertyAssumptions(true).build();
642+
643+
DynamicObject h1 = new TestDynamicObject(emptyShape);
644+
DynamicObjectLibrary lib = createLibrary(DynamicObjectLibrary.class, h1);
645+
646+
// initialize caches
647+
lib.put(h1, "name", 42);
648+
lib.put(h1, "alias", 43);
649+
650+
Assumption aliasAssumption = h1.getShape().getPropertyAssumption("alias");
651+
652+
DynamicObject h2 = new TestDynamicObject(emptyShape);
653+
// repeat cached operations on another object
654+
lib.put(h2, "name", 42);
655+
lib.put(h2, "alias", h1);
656+
657+
assertFalse("Property assumption for 'alias' should be invalid: " + aliasAssumption, aliasAssumption.isValid());
658+
}
659+
513660
static class TestDynamicObject extends DynamicObject {
514661
protected TestDynamicObject(Shape shape) {
515662
super(shape);

truffle/src/com.oracle.truffle.api.object.test/src/com/oracle/truffle/object/ext/test/PolymorphicPrimitivesTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertObjectLocation;
4444
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertPrimitiveLocation;
45+
import static com.oracle.truffle.object.basic.test.DOTestAsserts.assumeExtLayout;
4546
import static org.junit.Assert.assertEquals;
4647
import static org.junit.Assert.assertSame;
4748
import static org.junit.Assert.assertTrue;
@@ -61,7 +62,6 @@
6162
import com.oracle.truffle.api.object.Shape;
6263
import com.oracle.truffle.api.test.AbstractParametrizedLibraryTest;
6364
import com.oracle.truffle.object.ext.test.ObjectModelRegressionTest.TestDynamicObject;
64-
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
6565

6666
@SuppressWarnings("deprecation")
6767
@RunWith(Parameterized.class)
@@ -86,7 +86,7 @@ private static DynamicObject newInstance(Shape emptyShape) {
8686

8787
@Before
8888
public void before() {
89-
TruffleTestAssumptions.assumeEnterpriseRuntime();
89+
assumeExtLayout();
9090
}
9191

9292
@Test

0 commit comments

Comments
 (0)