|
42 | 42 |
|
43 | 43 | import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertObjectLocation;
|
44 | 44 | import static com.oracle.truffle.object.basic.test.DOTestAsserts.assertPrimitiveLocation;
|
| 45 | +import static com.oracle.truffle.object.basic.test.DOTestAsserts.assumeExtLayout; |
45 | 46 | import static com.oracle.truffle.object.basic.test.DOTestAsserts.invokeGetter;
|
46 | 47 | import static org.junit.Assert.assertEquals;
|
47 | 48 | import static org.junit.Assert.assertFalse;
|
|
56 | 57 | import java.util.List;
|
57 | 58 | import java.util.Map;
|
58 | 59 |
|
| 60 | +import org.hamcrest.CoreMatchers; |
| 61 | +import org.hamcrest.MatcherAssert; |
59 | 62 | import org.junit.Test;
|
60 | 63 | import org.junit.runner.RunWith;
|
61 | 64 | import org.junit.runners.Parameterized;
|
|
67 | 70 | import com.oracle.truffle.api.object.DynamicObjectLibrary;
|
68 | 71 | import com.oracle.truffle.api.object.Shape;
|
69 | 72 | import com.oracle.truffle.api.test.AbstractParametrizedLibraryTest;
|
70 |
| -import com.oracle.truffle.tck.tests.TruffleTestAssumptions; |
71 | 73 |
|
72 | 74 | @SuppressWarnings("deprecation")
|
73 | 75 | @RunWith(Parameterized.class)
|
@@ -386,7 +388,7 @@ public void testChangeFlagsConstantToNonConstant() {
|
386 | 388 |
|
387 | 389 | @Test
|
388 | 390 | public void testTryMergeShapes() {
|
389 |
| - TruffleTestAssumptions.assumeEnterpriseRuntime(); |
| 391 | + assumeExtLayout(); |
390 | 392 |
|
391 | 393 | // Assume (MaxMergeDepth >= 5)
|
392 | 394 | Shape emptyShape = Shape.newBuilder().allowImplicitCastIntToDouble(true).build();
|
@@ -437,7 +439,7 @@ public void testTryMergeShapes() {
|
437 | 439 |
|
438 | 440 | @Test
|
439 | 441 | public void testTryMergeShapes2() {
|
440 |
| - TruffleTestAssumptions.assumeEnterpriseRuntime(); |
| 442 | + assumeExtLayout(); |
441 | 443 |
|
442 | 444 | // Assume (MaxMergeDepth >= 5 && MaxMergeDiff >= 2)
|
443 | 445 |
|
@@ -473,6 +475,25 @@ public void testTryMergeShapes2() {
|
473 | 475 | assertSame(b.getShape(), a.getShape());
|
474 | 476 | }
|
475 | 477 |
|
| 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 | + |
476 | 497 | /**
|
477 | 498 | * Tests that onPropertyTransition is called by replace and remove property transitions.
|
478 | 499 | */
|
@@ -510,6 +531,132 @@ public void testPropertyAssumptionInvalidation() {
|
510 | 531 | assertFalse(assumption.toString(), assumption.isValid());
|
511 | 532 | }
|
512 | 533 |
|
| 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 | + |
513 | 660 | static class TestDynamicObject extends DynamicObject {
|
514 | 661 | protected TestDynamicObject(Shape shape) {
|
515 | 662 | super(shape);
|
|
0 commit comments