# HG changeset patch # User Andreas Woess # Date 1417700553 -3600 # Node ID a9a14b31f3b3a7662660fa024ff4d8bbd0fb9ca4 # Parent 8bf798e8cf113d5760766a2f1c77c1bf4ebdf83c OM: lazy initialization of leaf assumption diff -r 8bf798e8cf11 -r a9a14b31f3b3 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 Thu Dec 04 18:08:22 2014 +0100 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/ShapeImpl.java Thu Dec 04 14:42:33 2014 +0100 @@ -29,6 +29,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.object.*; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.object.LocationImpl.InternalLongLocation; import com.oracle.truffle.object.Locations.ConstantLocation; import com.oracle.truffle.object.Locations.DeclaredDualLocation; @@ -78,7 +79,7 @@ protected Property[] propertyArray; protected final Assumption validAssumption; - protected final Assumption leafAssumption; + @CompilationFinal protected volatile Assumption leafAssumption; /** * Shape transition map; lazily initialized. @@ -125,7 +126,6 @@ } this.validAssumption = createValidAssumption(); - this.leafAssumption = createLeafAssumption(); this.id = id; shapeCount.inc(); @@ -530,8 +530,9 @@ getTransitionMapForWrite().put(new Transition.PropertyTypeTransition(before, after), successorShape); } - private static Assumption createValidAssumption() { - return Truffle.getRuntime().createAssumption("valid shape"); + @Override + public final boolean isValid() { + return getValidAssumption().isValid(); } @Override @@ -539,27 +540,47 @@ return validAssumption; } + private static Assumption createValidAssumption() { + return Truffle.getRuntime().createAssumption("valid shape"); + } + + public final void invalidateValidAssumption() { + getValidAssumption().invalidate(); + } + @Override - public final boolean isValid() { - return getValidAssumption().isValid(); + public final boolean isLeaf() { + return leafAssumption == null || leafAssumption.isValid(); + } + + @Override + public final Assumption getLeafAssumption() { + if (leafAssumption == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + synchronized (getMutex()) { + if (leafAssumption == null) { + leafAssumption = isLeafHelper() ? createLeafAssumption() : NeverValidAssumption.INSTANCE; + } + } + } + return leafAssumption; + } + + private boolean isLeafHelper() { + return getTransitionMapForRead().isEmpty(); } private static Assumption createLeafAssumption() { return Truffle.getRuntime().createAssumption("leaf shape"); } - @Override - public final Assumption getLeafAssumption() { - return leafAssumption; - } - - @Override - public final boolean isLeaf() { - return getLeafAssumption().isValid(); - } - private void invalidateLeafAssumption() { - getLeafAssumption().invalidate(); + Assumption assumption = leafAssumption; + if (assumption != null) { + assumption.invalidate(); + } else { + leafAssumption = NeverValidAssumption.INSTANCE; + } } @Override