changeset 21944:16725287d5af

Truffle: fix delete/removeProperty regression
author Andreas Woess <andreas.woess@oracle.com>
date Tue, 16 Jun 2015 19:27:51 +0200
parents 1adad389c232
children 179c3a0bac32
files graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java
diffstat 3 files changed, 31 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java	Tue Jun 16 19:26:49 2015 +0200
+++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java	Tue Jun 16 19:27:51 2015 +0200
@@ -165,23 +165,21 @@
         assert toShape.isRelated(ancestor);
         assert toShape.isValid();
         assert ancestor.isValid();
-        for (; toShape != ancestor; toShape = toShape.getParent()) {
-            Transition transitionFromParent = toShape.getTransitionFromParent();
-            if (transitionFromParent instanceof Transition.AddPropertyTransition) {
-                Property toProperty = ((Transition.AddPropertyTransition) transitionFromParent).getProperty();
-                Property fromProperty = fromShape.getProperty(toProperty.getKey());
+        PropertyMap ancestorMap = ((ShapeImpl) ancestor).getPropertyMap();
+        PropertyMap fromMap = fromShape.getPropertyMap();
+        for (PropertyMap toMap = toShape.getPropertyMap(); !toMap.isEmpty() && toMap != ancestorMap; toMap = toMap.getParentMap()) {
+            Property toProperty = toMap.getLastProperty();
+            Property fromProperty = fromMap.get(toProperty.getKey());
 
-                // copy only if property has a location and it's not the same as the source location
-                if (toProperty.getLocation() != null && !(toProperty.getLocation() instanceof ValueLocation) && !toProperty.getLocation().equals(fromProperty.getLocation())) {
-                    toProperty.setInternal(this, fromProperty.get(fromObject, false));
-                    assert toShape.isValid();
-                }
+            // copy only if property has a location and it's not the same as the source location
+            if (toProperty.getLocation() != null && !(toProperty.getLocation() instanceof ValueLocation) && !toProperty.getLocation().equals(fromProperty.getLocation())) {
+                toProperty.setInternal(this, fromProperty.get(fromObject, false));
+                assert toShape.isValid();
+            }
 
-                if (fromShape.getTransitionFromParent() instanceof Transition.AddPropertyTransition &&
-                                ((Transition.AddPropertyTransition) fromShape.getTransitionFromParent()).getProperty() == fromProperty) {
-                    // no property is looked up twice, so we can skip over to parent
-                    fromShape = fromShape.getParent();
-                }
+            if (fromProperty == fromMap.getLastProperty()) {
+                // no property is looked up twice, so we can skip over to parent
+                fromMap = fromMap.getParentMap();
             }
         }
     }
--- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java	Tue Jun 16 19:26:49 2015 +0200
+++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/PropertyMap.java	Tue Jun 16 19:27:51 2015 +0200
@@ -350,4 +350,9 @@
     public Property getLastProperty() {
         return cdr;
     }
+
+    @Override
+    public String toString() {
+        return values().toString();
+    }
 }
--- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java	Tue Jun 16 19:26:49 2015 +0200
+++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java	Tue Jun 16 19:27:51 2015 +0200
@@ -620,12 +620,15 @@
             return cachedShape;
         }
 
-        ShapeImpl shape = getShapeFromProperty(prop);
+        ShapeImpl shape = getShapeFromProperty(prop.getKey());
         if (shape != null) {
             List<Transition> transitionList = new ArrayList<>();
             ShapeImpl current = this;
             while (current != shape) {
-                transitionList.add(current.getTransitionFromParent());
+                if (!(current.getTransitionFromParent() instanceof Transition.DirectReplacePropertyTransition) ||
+                                !((Transition.DirectReplacePropertyTransition) current.getTransitionFromParent()).getPropertyBefore().getKey().equals(prop.getKey())) {
+                    transitionList.add(current.getTransitionFromParent());
+                }
                 current = current.parent;
             }
             ShapeImpl newShape = shape.parent;
@@ -655,7 +658,14 @@
         } else if (transition instanceof ReservePrimitiveArrayTransition) {
             return reservePrimitiveExtensionArray();
         } else if (transition instanceof DirectReplacePropertyTransition) {
-            return replaceProperty(((DirectReplacePropertyTransition) transition).getPropertyBefore(), ((DirectReplacePropertyTransition) transition).getPropertyAfter());
+            Property oldProperty = ((DirectReplacePropertyTransition) transition).getPropertyBefore();
+            Property newProperty = ((DirectReplacePropertyTransition) transition).getPropertyAfter();
+            if (append) {
+                assert oldProperty.getLocation() instanceof DualLocation && newProperty.getLocation() instanceof DualLocation;
+                oldProperty = getProperty(oldProperty.getKey());
+                newProperty = newProperty.relocate(((DualLocation) oldProperty.getLocation()).changeType(((DualLocation) newProperty.getLocation()).getType()));
+            }
+            return replaceProperty(oldProperty, newProperty);
         } else {
             throw new UnsupportedOperationException();
         }