Mercurial > hg > truffle
changeset 22338:15c9dda91e50
SL: simplify write property cache node
author | Andreas Woess <andreas.woess@oracle.com> |
---|---|
date | Fri, 30 Oct 2015 19:11:36 +0100 |
parents | 4f3eda22dbe9 |
children | 559087369317 |
files | truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyCacheNode.java |
diffstat | 2 files changed, 63 insertions(+), 93 deletions(-) [+] |
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java Mon Nov 02 16:34:22 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyCacheNode.java Fri Oct 30 19:11:36 2015 +0100 @@ -73,11 +73,10 @@ * We use a separate long specialization to avoid boxing for long. */ @Specialization(limit = "CACHE_LIMIT", guards = {"longLocation != null", "shape.check(receiver)"}, assumptions = "shape.getValidAssumption()") - @SuppressWarnings("unused") protected long doCachedLong(DynamicObject receiver, // @Cached("receiver.getShape()") Shape shape, // @Cached("getLongLocation(shape)") LongLocation longLocation) { - return longLocation.getLong(receiver, true); + return longLocation.getLong(receiver, shape); } protected LongLocation getLongLocation(Shape shape) {
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyCacheNode.java Mon Nov 02 16:34:22 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyCacheNode.java Fri Oct 30 19:11:36 2015 +0100 @@ -42,9 +42,9 @@ import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.InvalidAssumptionException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.FinalLocationException; @@ -52,8 +52,11 @@ import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Property; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.utilities.AlwaysValidAssumption; +import com.oracle.truffle.api.utilities.NeverValidAssumption; public abstract class SLWritePropertyCacheNode extends Node { + protected static final int CACHE_LIMIT = 3; protected final String propertyName; @@ -63,105 +66,73 @@ public abstract void executeObject(DynamicObject receiver, Object value); - @Specialization(guards = "location.isValid(receiver, value)", assumptions = "location.getAssumptions()") - public void writeCached(DynamicObject receiver, Object value, // - @Cached("createCachedWrite(receiver, value)") CachedWriteLocation location) { - if (location.writeUnchecked(receiver, value)) { - // write successful - } else { + @Specialization(guards = {"location != null", "shape.check(receiver)", "location.canSet(receiver, value)"}, assumptions = {"shape.getValidAssumption()"}, limit = "CACHE_LIMIT") + public void writeExistingPropertyCached(DynamicObject receiver, Object value, // + @Cached("lookupLocation(receiver, value)") Location location, // + @Cached("receiver.getShape()") Shape shape, // + @Cached("ensureValid(receiver)") Assumption validAssumption) { + try { + validAssumption.check(); + } catch (InvalidAssumptionException e) { executeObject(receiver, value); + return; } - } - - @Specialization(contains = "writeCached") - @TruffleBoundary - public void writeGeneric(DynamicObject receiver, Object value, // - @Cached("new(createCachedWrite(receiver, value))") LRUCachedWriteLocation lru) { - CachedWriteLocation location = lru.location; - if (!location.isValid(receiver, value) || !location.areAssumptionsValid()) { - location = createCachedWrite(receiver, value); - lru.location = location; - } - if (location.writeUnchecked(receiver, value)) { - // write successful - } else { - executeObject(receiver, value); + try { + location.set(receiver, value, shape); + } catch (IncompatibleLocationException | FinalLocationException e) { + throw new IllegalStateException(e); } } - protected CachedWriteLocation createCachedWrite(DynamicObject receiver, Object value) { - while (receiver.updateShape()) { - // multiple shape updates might be needed. - } - - Shape oldShape = receiver.getShape(); - Shape newShape; - Property property = oldShape.getProperty(propertyName); - - if (property != null && property.getLocation().canSet(receiver, value)) { - newShape = oldShape; - } else { - receiver.define(propertyName, value, 0); - newShape = receiver.getShape(); - property = newShape.getProperty(propertyName); - } - - if (!oldShape.check(receiver)) { - return createCachedWrite(receiver, value); + @Specialization(guards = {"existing == null", "shapeBefore.check(receiver)", "shapeAfter != null", "newLocation.canSet(receiver, value)"}, assumptions = {"shapeBefore.getValidAssumption()", + "shapeAfter.getValidAssumption()"}, limit = "CACHE_LIMIT") + public void writeNewPropertyCached(DynamicObject receiver, Object value, // + @Cached("lookupLocation(receiver, value)") @SuppressWarnings("unused") Location existing, // + @Cached("receiver.getShape()") Shape shapeBefore, // + @Cached("defineProperty(receiver, value)") Shape shapeAfter, // + @Cached("getLocation(shapeAfter)") Location newLocation, // + @Cached("ensureValid(receiver)") Assumption validAssumption) { + try { + validAssumption.check(); + } catch (InvalidAssumptionException e) { + executeObject(receiver, value); + return; } - - return new CachedWriteLocation(oldShape, newShape, property.getLocation()); - - } - - protected static final class CachedWriteLocation { - - private final Shape oldShape; - private final Shape newShape; - private final Location location; - private final Assumption validLocation = Truffle.getRuntime().createAssumption(); - - public CachedWriteLocation(Shape oldShape, Shape newShape, Location location) { - this.oldShape = oldShape; - this.newShape = newShape; - this.location = location; - } - - public boolean areAssumptionsValid() { - return validLocation.isValid() && oldShape.getValidAssumption().isValid() && newShape.getValidAssumption().isValid(); - } - - public Assumption[] getAssumptions() { - return new Assumption[]{oldShape.getValidAssumption(), newShape.getValidAssumption(), validLocation}; - } - - public boolean isValid(DynamicObject receiver, Object value) { - return oldShape.check(receiver) && location.canSet(receiver, value); - } - - public boolean writeUnchecked(DynamicObject receiver, Object value) { - try { - if (oldShape == newShape) { - location.set(receiver, value, oldShape); - } else { - location.set(receiver, value, oldShape, newShape); - } - return true; - } catch (IncompatibleLocationException | FinalLocationException e) { - validLocation.invalidate(); - return false; - } + try { + newLocation.set(receiver, value, shapeBefore, shapeAfter); + } catch (IncompatibleLocationException e) { + throw new IllegalStateException(e); } } - protected static final class LRUCachedWriteLocation { - - private CachedWriteLocation location; - - public LRUCachedWriteLocation(CachedWriteLocation location) { - this.location = location; - } - + @Specialization(contains = {"writeExistingPropertyCached", "writeNewPropertyCached"}) + @TruffleBoundary + public void writeUncached(DynamicObject receiver, Object value) { + receiver.define(propertyName, value); } + protected final Location lookupLocation(DynamicObject object, Object value) { + final Shape oldShape = object.getShape(); + final Property property = oldShape.getProperty(propertyName); + + if (property != null && property.getLocation().canSet(object, value)) { + return property.getLocation(); + } else { + return null; + } + } + + protected final Shape defineProperty(DynamicObject receiver, Object value) { + Shape oldShape = receiver.getShape(); + Shape newShape = oldShape.defineProperty(propertyName, value, 0); + return newShape; + } + + protected final Location getLocation(Shape newShape) { + return newShape.getProperty(propertyName).getLocation(); + } + + protected static Assumption ensureValid(DynamicObject receiver) { + return receiver.updateShape() ? NeverValidAssumption.INSTANCE : AlwaysValidAssumption.INSTANCE; + } }