# HG changeset patch # User Andreas Woess # Date 1433959573 -7200 # Node ID 19340125f18255e65657cb4ba150bc353d5c1814 # Parent cb051c368c801b6d873096a4fb3c2bc7af93c5a6 Truffle: model property replace as direct transition diff -r cb051c368c80 -r 19340125f182 graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java --- a/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java Wed Jun 10 20:05:52 2015 +0200 +++ b/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java Wed Jun 10 20:06:13 2015 +0200 @@ -39,4 +39,20 @@ protected ShapeImpl createShape(Layout layout, Object sharedData, ShapeImpl parent, ObjectType objectType, PropertyMap propertyMap, Transition transition, Allocator allocator, int id) { return new ShapeBasic(layout, sharedData, parent, objectType, propertyMap, transition, allocator, id); } + + @Override + public ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { + assert oldProperty.getKey().equals(newProperty.getKey()); + onPropertyTransition(oldProperty); + + Transition replacePropertyTransition = new Transition.DirectReplacePropertyTransition(oldProperty, newProperty); + ShapeImpl cachedShape = queryTransition(replacePropertyTransition); + if (cachedShape != null) { + return cachedShape; + } + PropertyMap newPropertyMap = this.getPropertyMap().replaceCopy(oldProperty, newProperty); + ShapeImpl newShape = createShape(getLayout(), getSharedData(), this, getObjectType(), newPropertyMap, replacePropertyTransition, allocator(), getId()); + addDirectTransition(replacePropertyTransition, newShape); + return newShape; + } } diff -r cb051c368c80 -r 19340125f182 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Wed Jun 10 20:05:52 2015 +0200 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Wed Jun 10 20:06:13 2015 +0200 @@ -39,6 +39,7 @@ import com.oracle.truffle.object.Locations.DualLocation; import com.oracle.truffle.object.Locations.ValueLocation; import com.oracle.truffle.object.Transition.AddPropertyTransition; +import com.oracle.truffle.object.Transition.DirectReplacePropertyTransition; import com.oracle.truffle.object.Transition.ObjectTypeTransition; import com.oracle.truffle.object.Transition.PropertyTransition; import com.oracle.truffle.object.Transition.RemovePropertyTransition; @@ -311,7 +312,7 @@ return propertyMap; } - private ShapeImpl queryTransition(Transition transition) { + protected final ShapeImpl queryTransition(Transition transition) { ShapeImpl cachedShape = this.getTransitionMapForRead().get(transition); if (cachedShape != null) { // Shape already exists? shapeCacheHitCount.inc(); @@ -674,6 +675,8 @@ return changeType(((ObjectTypeTransition) transition).getObjectType()); } else if (transition instanceof ReservePrimitiveArrayTransition) { return reservePrimitiveExtensionArray(); + } else if (transition instanceof DirectReplacePropertyTransition) { + return replaceProperty(((DirectReplacePropertyTransition) transition).getPropertyBefore(), ((DirectReplacePropertyTransition) transition).getPropertyAfter()); } else { throw new UnsupportedOperationException(); } @@ -688,8 +691,10 @@ * Duplicate shape exchanging existing property with new property. */ @Override - public final ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { - Transition replacePropertyTransition = new Transition.ReplacePropertyTransition(oldProperty, newProperty); + public ShapeImpl replaceProperty(Property oldProperty, Property newProperty) { + assert oldProperty.getKey().equals(newProperty.getKey()); + + Transition replacePropertyTransition = new Transition.IndirectReplacePropertyTransition(oldProperty, newProperty); ShapeImpl cachedShape = queryTransition(replacePropertyTransition); if (cachedShape != null) { return cachedShape; diff -r cb051c368c80 -r 19340125f182 graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java Wed Jun 10 20:05:52 2015 +0200 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java Wed Jun 10 20:06:13 2015 +0200 @@ -133,10 +133,10 @@ } } - public static final class ReplacePropertyTransition extends PropertyTransition { + public abstract static class AbstractReplacePropertyTransition extends PropertyTransition { private final Property after; - public ReplacePropertyTransition(Property before, Property after) { + public AbstractReplacePropertyTransition(Property before, Property after) { super(before); this.after = after; } @@ -150,11 +150,41 @@ } @Override + public boolean equals(Object obj) { + return super.equals(obj) && this.after.equals(((AbstractReplacePropertyTransition) obj).after); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + after.hashCode(); + return result; + } + } + + public static final class IndirectReplacePropertyTransition extends AbstractReplacePropertyTransition { + public IndirectReplacePropertyTransition(Property before, Property after) { + super(before, after); + } + + @Override public boolean isDirect() { return false; } } + public static final class DirectReplacePropertyTransition extends AbstractReplacePropertyTransition { + public DirectReplacePropertyTransition(Property before, Property after) { + super(before, after); + } + + @Override + public boolean isDirect() { + return true; + } + } + public static final class ReservePrimitiveArrayTransition extends Transition { public ReservePrimitiveArrayTransition() { }