# HG changeset patch # User Matthias Grimmer # Date 1450099232 -3600 # Node ID bfc98cc379346c7426426e9de9e9422649063ba5 # Parent b3569a53c24cbbb1820a8712b82f5f669993dddb# Parent cff4a9d3e72a05da1799ac973a3edcc28f74176a Merge diff -r b3569a53c24c -r bfc98cc37934 truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/package-info.java --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/package-info.java Mon Dec 14 14:20:08 2015 +0100 +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/package-info.java Mon Dec 14 14:20:32 2015 +0100 @@ -33,8 +33,17 @@ * This package provides inter-operability between different * {@link com.oracle.truffle.api.TruffleLanguage Truffle languages}. *

- * Languages can exchange primitive Java type wrapper objects (e.g., {@link java.lang.Integer}, - * {@link java.lang.Double}, {@link java.lang.String}, etc) as well as any type implementing + * Languages can exchange primitive Java type wrapper objects (e.g., + * {@link java.lang.Byte}, + * {@link java.lang.Short}, + * {@link java.lang.Integer}, + * {@link java.lang.Long}, + * {@link java.lang.Float}, + * {@link java.lang.Double}, + * {@link java.lang.Character}, + * {@link java.lang.Boolean}, + * and {@link java.lang.String}) + * as well as any type implementing * {@link com.oracle.truffle.api.interop.TruffleObject}. Foreign objects are precisely those * implementing {@link com.oracle.truffle.api.interop.TruffleObject}. *

diff -r b3569a53c24c -r bfc98cc37934 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameDescriptorTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameDescriptorTest.java Mon Dec 14 14:20:08 2015 +0100 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/FrameDescriptorTest.java Mon Dec 14 14:20:32 2015 +0100 @@ -22,16 +22,21 @@ */ package com.oracle.truffle.api; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.junit.Test; + import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotKind; import com.oracle.truffle.api.frame.FrameSlotTypeException; import com.oracle.truffle.api.frame.VirtualFrame; -import org.junit.Assert; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import org.junit.Test; public class FrameDescriptorTest { @@ -66,7 +71,7 @@ @Test public void nullDefaultValue() { - Assert.assertNull(new FrameDescriptor().getDefaultValue()); + assertNull(new FrameDescriptor().getDefaultValue()); } @Test @@ -82,11 +87,10 @@ assertEquals(d.getSlots().get(1).getIndex(), 1); FrameDescriptor copy = d.copy(); - - assertEquals(copy.getSlots().get(1).getIndex(), 1); - - assertNull("Info isn't copied!", copy.getSlots().get(1).getInfo()); - assertEquals("Kind isn't copied!", copy.getSlots().get(1).getKind(), FrameSlotKind.Illegal); + assertEquals(2, copy.getSize()); + assertEquals(1, copy.getSlots().get(1).getIndex()); + assertEquals("Info is copied", "i2", copy.getSlots().get(1).getInfo()); + assertEquals("Kind isn't copied", FrameSlotKind.Illegal, copy.getSlots().get(1).getKind()); } @Test @@ -114,4 +118,68 @@ assertEquals("Kind is changed", firstCopy.getKind(), FrameSlotKind.Int); assertEquals("Kind is changed in original too!", first.getKind(), FrameSlotKind.Int); } + + @Test + public void version() { + FrameDescriptor d = new FrameDescriptor(); + s1 = d.addFrameSlot("v1", "i1", FrameSlotKind.Boolean); + s2 = d.addFrameSlot("v2", "i2", FrameSlotKind.Float); + + Assumption version; + version = d.getVersion(); + assertTrue(version.isValid()); + // add slot + s3 = d.addFrameSlot("v3", "i3", FrameSlotKind.Int); + assertEquals(3, d.getSize()); + assertFalse(version.isValid()); + version = d.getVersion(); + assertTrue(version.isValid()); + assertSame("1st slot", s1, d.getSlots().get(0)); + assertSame("2nd slot", s2, d.getSlots().get(1)); + assertSame("3rd slot", s3, d.getSlots().get(2)); + + // change kind + s3.setKind(FrameSlotKind.Object); + assertFalse(version.isValid()); + version = d.getVersion(); + assertTrue(version.isValid()); + + // remove slot + d.removeFrameSlot("v3"); + assertEquals(2, d.getSize()); + assertFalse(version.isValid()); + version = d.getVersion(); + assertTrue(version.isValid()); + } + + @Test + public void notInFrameAssumption() { + FrameDescriptor d = new FrameDescriptor(); + Assumption[] ass = new Assumption[]{d.getNotInFrameAssumption("v1"), d.getNotInFrameAssumption("v2"), d.getNotInFrameAssumption("v3")}; + assertTrue(ass[0].isValid()); + assertTrue(ass[1].isValid()); + assertTrue(ass[2].isValid()); + s1 = d.addFrameSlot("v1", "i1", FrameSlotKind.Boolean); + assertFalse(ass[0].isValid()); + assertTrue(ass[1].isValid()); + assertTrue(ass[2].isValid()); + s2 = d.addFrameSlot("v2", "i2", FrameSlotKind.Float); + assertFalse(ass[0].isValid()); + assertFalse(ass[1].isValid()); + assertTrue(ass[2].isValid()); + s3 = d.addFrameSlot("v3", "i3", FrameSlotKind.Int); + assertFalse(ass[0].isValid()); + assertFalse(ass[1].isValid()); + assertFalse(ass[2].isValid()); + + for (String identifier : new String[]{"v1", "v2", "v3"}) { + try { + d.getNotInFrameAssumption(identifier); + fail("expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // expected + } + } + d.getNotInFrameAssumption("v4"); + } } diff -r b3569a53c24c -r bfc98cc37934 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java Mon Dec 14 14:20:08 2015 +0100 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java Mon Dec 14 14:20:32 2015 +0100 @@ -24,6 +24,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; @@ -44,9 +45,17 @@ @DataPoint public static final Object O3 = new Object(); @DataPoint public static final Integer O4 = new Integer(1); @DataPoint public static final Integer O5 = null; + @DataPoint public static final TestBaseClass O6 = new TestBaseClass(); + @DataPoint public static final TestSubClass O7 = new TestSubClass(); private ValueProfile profile; + private static class TestBaseClass { + } + + private static class TestSubClass extends TestBaseClass { + } + @Before public void create() { profile = ValueProfile.createClassProfile(); @@ -57,7 +66,7 @@ assertThat(isGeneric(profile), is(false)); assertThat(isUninitialized(profile), is(true)); assertNull(getCachedClass(profile)); - profile.toString(); // test that it is not crashing + assertNotNull(profile.toString()); } @Theory @@ -65,9 +74,9 @@ Object result = profile.profile(value); assertThat(result, is(value)); - assertEquals(getCachedClass(profile), expectedClass(value)); + assertEquals(expectedClass(value), getCachedClass(profile)); assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing + assertNotNull(profile.toString()); } @Theory @@ -80,10 +89,10 @@ Object expectedClass = expectedClass(value0) == expectedClass(value1) ? expectedClass(value0) : Object.class; - assertEquals(getCachedClass(profile), expectedClass); + assertEquals(expectedClass, getCachedClass(profile)); assertThat(isUninitialized(profile), is(false)); assertThat(isGeneric(profile), is(expectedClass == Object.class)); - profile.toString(); // test that it is not crashing + assertNotNull(profile.toString()); } @Theory @@ -98,10 +107,10 @@ Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; - assertEquals(getCachedClass(profile), expectedClass); + assertEquals(expectedClass, getCachedClass(profile)); assertThat(isUninitialized(profile), is(false)); assertThat(isGeneric(profile), is(expectedClass == Object.class)); - profile.toString(); // test that it is not crashing + assertNotNull(profile.toString()); } private static Class expectedClass(Object value) { diff -r b3569a53c24c -r bfc98cc37934 truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Mon Dec 14 14:20:08 2015 +0100 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Mon Dec 14 14:20:32 2015 +0100 @@ -678,7 +678,13 @@ * should set the value to the field; the return value should be the actual value of the * field when the invoke method returns. * - * @param args arguments to pass when invoking the symbol + * @param args arguments to pass when invoking the symbol; either wrappers of Java primitive + * types (e.g. {@link java.lang.Byte}, {@link java.lang.Short}, + * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float}, + * {@link java.lang.Double}, {@link java.lang.Character}, + * {@link java.lang.Boolean}, and {@link java.lang.String}) or a + * {@link TruffleObject object created} by one of the languages) + * * @return symbol wrapper around the value returned by invoking the symbol, never * null * @throws IOException signals problem during execution diff -r b3569a53c24c -r bfc98cc37934 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Dec 14 14:20:08 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Mon Dec 14 14:20:32 2015 +0100 @@ -54,7 +54,7 @@ /** * Constructs new descriptor with specified {@link #getDefaultValue()}. - * + * * @param defaultValue to be returned from {@link #getDefaultValue()} */ public FrameDescriptor(Object defaultValue) { @@ -67,7 +67,7 @@ /** * Use {@link #FrameDescriptor()}. - * + * * @return new instance of the descriptor * @deprecated */ @@ -78,7 +78,7 @@ /** * Use {@link #FrameDescriptor(java.lang.Object) }. - * + * * @return new instance of the descriptor * @deprecated */ @@ -90,9 +90,9 @@ /** * Adds frame slot. Delegates to * {@link #addFrameSlot(java.lang.Object, java.lang.Object, com.oracle.truffle.api.frame.FrameSlotKind) - * addFrameSlot}(identifier, null, {@link FrameSlotKind#Illegal}). This is slow + * addFrameSlot}(identifier, null, {@link FrameSlotKind#Illegal}). This is a slow * operation that switches to interpreter mode. - * + * * @param identifier key for the slot * @return the newly created slot */ @@ -103,9 +103,9 @@ /** * Adds frame slot. Delegates to * {@link #addFrameSlot(java.lang.Object, java.lang.Object, com.oracle.truffle.api.frame.FrameSlotKind) - * addFrameSlot}(identifier, null, kind). This is slow operation that - * switches to interpreter mode. - * + * addFrameSlot}(identifier, null, kind). This is a slow operation + * that switches to interpreter mode. + * * @param identifier key for the slot * @param kind the kind of the new slot * @return the newly created slot @@ -115,9 +115,9 @@ } /** - * Adds new frame slot to {@link #getSlots()} list. This is slow operation that switches to + * Adds new frame slot to {@link #getSlots()} list. This is a slow operation that switches to * interpreter mode. - * + * * @param identifier key for the slot - it needs proper {@link #equals(java.lang.Object)} and * {@link Object#hashCode()} implementations * @param info additional {@link FrameSlot#getInfo() information for the slot} @@ -136,8 +136,8 @@ } /** - * Finds an existing slot. This is slow operation. - * + * Finds an existing slot. This is a slow operation. + * * @param identifier the key of the slot to search for * @return the slot or null */ @@ -147,8 +147,8 @@ } /** - * Finds an existing slot or creates new one. This is slow operation. - * + * Finds an existing slot or creates new one. This is a slow operation. + * * @param identifier the key of the slot to search for * @return the slot */ @@ -161,8 +161,8 @@ } /** - * Finds an existing slot or creates new one. This is slow operation. - * + * Finds an existing slot or creates new one. This is a slow operation. + * * @param identifier the key of the slot to search for * @param kind the kind for the newly created slot * @return the found or newly created slot @@ -176,8 +176,8 @@ } /** - * Finds an existing slot or creates new one. This is slow operation. - * + * Finds an existing slot or creates new one. This is a slow operation. + * * @param identifier the key of the slot to search for * @param info info for the newly created slot * @param kind the kind for the newly created slot @@ -193,8 +193,8 @@ /** * Removes a slot. If the identifier is found, its slot is removed from this descriptor. This is - * slow operation. - * + * a slow operation. + * * @param identifier identifies the slot to remove */ public void removeFrameSlot(Object identifier) { @@ -208,7 +208,7 @@ /** * Returns number of slots in the descriptor. - * + * * @return the same value as {@link #getSlots()}.{@link List#size()} would return */ public int getSize() { @@ -217,7 +217,7 @@ /** * Current set of slots in the descriptor. - * + * * @return unmodifiable list of {@link FrameSlot} */ public List getSlots() { @@ -234,16 +234,17 @@ } /** - * Deeper copy of the descriptor. Copies all slots in the descriptor, but only their identifiers - * - not their {@link FrameSlot#getInfo()} neither their {@link FrameSlot#getKind()}! - * + * Deeper copy of the descriptor. Copies all slots in the descriptor, but only their + * {@linkplain FrameSlot#getIdentifier() identifier} and {@linkplain FrameSlot#getInfo() info} + * but not their {@linkplain FrameSlot#getKind() kind}! + * * @return new instance of a descriptor with copies of values from this one */ public FrameDescriptor copy() { FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue); - for (int i = 0; i < this.getSlots().size(); i++) { - Object identifier = this.getSlots().get(i).getIdentifier(); - clonedFrameDescriptor.addFrameSlot(identifier); + for (int i = 0; i < slots.size(); i++) { + FrameSlot slot = slots.get(i); + clonedFrameDescriptor.addFrameSlot(slot.getIdentifier(), slot.getInfo(), FrameSlotKind.Illegal); } return clonedFrameDescriptor; } @@ -252,7 +253,7 @@ * Shallow copy of the descriptor. Re-uses the existing slots in new descriptor. As a result, if * you {@link FrameSlot#setKind(com.oracle.truffle.api.frame.FrameSlotKind) change kind} of one * of the slots it is changed in the original as well as in the shallow copy. - * + * * @return new instance of a descriptor with copies of values from this one */ public FrameDescriptor shallowCopy() { @@ -262,11 +263,21 @@ return clonedFrameDescriptor; } + /** + * Invalidates the current, and create a new version assumption. + */ void updateVersion() { version.invalidate(); version = createVersion(); } + /** + * Returns an assumption reflecting the frame's current version, which is updated every time a + * slot is added or removed, or an existing slot's kind is changed. This assumption is + * associated with compiled code that depends on the internal frame layout. + * + * @return an assumption invalidated when a slot is added or removed, or a slot kind changed. + */ public Assumption getVersion() { return version; } @@ -277,13 +288,21 @@ /** * Default value for the created slots. - * + * * @return value provided to {@link #FrameDescriptor(java.lang.Object)} */ public Object getDefaultValue() { return defaultValue; } + /** + * Make an assumption that no slot with the specified identifier is present in this frame + * descriptor. Invalidated when a frame slot with the identifier is added. + * + * @param identifier frame slot identifier + * @return an assumption that this frame descriptor does not contain a slot with the identifier + * @throws IllegalArgumentException if the frame descriptor contains a slot with the identifier + */ public Assumption getNotInFrameAssumption(Object identifier) { if (identifierToSlotMap.containsKey(identifier)) { throw new IllegalArgumentException("Cannot get not-in-frame assumption for existing frame slot!");