changeset 21901:19340125f182

Truffle: model property replace as direct transition
author Andreas Woess <andreas.woess@oracle.com>
date Wed, 10 Jun 2015 20:06:13 +0200
parents cb051c368c80
children e9b787f8134f
files graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/ShapeBasic.java graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java graal/com.oracle.truffle.object/src/com/oracle/truffle/object/Transition.java
diffstat 3 files changed, 56 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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;
+    }
 }
--- 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;
--- 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() {
         }