diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java index 8001e760664966b084c5d2bf830e1bbef491ca2d..18e449ccd9ec65ea6751cef97723f671cee3ba14 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java @@ -41,6 +41,7 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.RCloseable; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; @MessageResolution(receiverType = RFunction.class, language = TruffleRLanguage.class) public class RFunctionMR { @@ -54,8 +55,12 @@ public class RFunctionMR { @Resolve(message = "EXECUTE") public abstract static class RFunctionExecuteNode extends Node { private static final FrameDescriptor emptyFrameDescriptor = new FrameDescriptor("R interop frame"); - private final Object argsIdentifier = new Object(); - private final FrameSlot slot = emptyFrameDescriptor.addFrameSlot(argsIdentifier, FrameSlotKind.Object); + private static final Object argsIdentifier = new Object(); + private static final FrameSlot slot = emptyFrameDescriptor.addFrameSlot(argsIdentifier, FrameSlotKind.Object); + + static { + FrameSlotChangeMonitor.initializeFunctionFrameDescriptor("<function>", emptyFrameDescriptor); + } @Child private RCallBaseNode call = RCallNode.createExplicitCall(argsIdentifier); @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java index 87164398f9c4faa89ef1b5a24336595f8890893e..c986eecf12694fb6ff66f2febf017262bae6aa70 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java index ab139b59ceaa374eecaac5b3a7f81c9c00f0d010..2cb9365d10f83e6c89a11fba7878740f17dd0b86 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/BaseWriteVariableNode.java @@ -166,15 +166,16 @@ abstract class BaseWriteVariableNode extends WriteVariableNode { * @param frameSlot The frame slot of the value. * @param invalidateProfile The invalidation profile. */ - protected static Object handleActiveBinding(VirtualFrame execFrame, Frame lookupFrame, Object value, FrameSlot frameSlot, BranchProfile invalidateProfile) { - Object object = null; - if (FrameSlotChangeMonitor.isActiveBinding(frameSlot)) { - try { - object = lookupFrame.getObject(frameSlot); - } catch (FrameSlotTypeException e) { - // ignore - } - assert object != null && ActiveBinding.isActiveBinding(object); + protected static Object handleActiveBinding(VirtualFrame execFrame, Frame lookupFrame, Object value, FrameSlot frameSlot, BranchProfile invalidateProfile, + ConditionProfile isActiveBindingProfile) { + Object object; + try { + object = lookupFrame.getObject(frameSlot); + } catch (FrameSlotTypeException e) { + object = null; + } + + if (isActiveBindingProfile.profile(object != null && ActiveBinding.isActiveBinding(object))) { return ((ActiveBinding) object).writeValue(value); } else { FrameSlotChangeMonitor.setObjectAndInvalidate(lookupFrame, frameSlot, value, false, invalidateProfile); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java index e319aeab360e2bf3469ce972fed40924fcc6d6ca..8e953b84205f56107b7a2953ecfc76e6ec387434 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteLocalFrameVariableNode.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotKind; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -56,6 +57,7 @@ public abstract class WriteLocalFrameVariableNode extends BaseWriteVariableNode private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile(); private final BranchProfile invalidateProfile = BranchProfile.create(); + private final ConditionProfile isActiveBindingProfile = ConditionProfile.createBinaryProfile(); @CompilationFinal private Assumption containsNoActiveBinding; protected WriteLocalFrameVariableNode(Object name, Mode mode) { @@ -95,12 +97,12 @@ public abstract class WriteLocalFrameVariableNode extends BaseWriteVariableNode CompilerDirectives.transferToInterpreterAndInvalidate(); containsNoActiveBinding = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(frame.getFrameDescriptor()); } - if (containsNoActiveBinding != null && containsNoActiveBinding.isValid()) { + if (containsNoActiveBinding.isValid()) { Object newValue = shareObjectValue(frame, frameSlot, storedObjectProfile.profile(value), mode, false); FrameSlotChangeMonitor.setObjectAndInvalidate(frame, frameSlot, newValue, false, invalidateProfile); } else { // it's a local variable lookup; so use 'frame' for both, executing and looking up - return handleActiveBinding(frame, frame, value, frameSlot, invalidateProfile); + return handleActiveBinding(frame, frame, value, frameSlot, invalidateProfile, isActiveBindingProfile); } return value; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java index 7cd8ff8d00ca2cf280b5e0ca8696671cbe1da35b..bbc7d82a5b0ba896a54ac9f00fe83370596eb4a5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/WriteSuperFrameVariableNode.java @@ -73,6 +73,7 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode { private final ValueProfile storedObjectProfile = ValueProfile.createClassProfile(); private final BranchProfile invalidateProfile = BranchProfile.create(); private final ValueProfile enclosingFrameProfile = ValueProfile.createClassProfile(); + private final ConditionProfile isActiveBindingProfile = ConditionProfile.createBinaryProfile(); private final Mode mode; @CompilationFinal private Assumption containsNoActiveBinding; @@ -110,7 +111,7 @@ abstract class WriteSuperFrameVariableNode extends BaseWriteVariableNode { Object newValue = shareObjectValue(profiledFrame, frameSlot, storedObjectProfile.profile(value), mode, true); FrameSlotChangeMonitor.setObjectAndInvalidate(profiledFrame, frameSlot, newValue, true, invalidateProfile); } else { - handleActiveBinding(frame, profiledFrame, value, frameSlot, invalidateProfile); + handleActiveBinding(frame, profiledFrame, value, frameSlot, invalidateProfile, isActiveBindingProfile); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java index c5cf895eeb19867a13b975ae293018ffd56fc868..5e1b476097b7ad544331269c48dfe303268c9b88 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/variables/LocalReadVariableNode.java @@ -116,7 +116,7 @@ public final class LocalReadVariableNode extends Node { containsNoActiveBindingAssumption = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(profiledVariableFrame.getFrameDescriptor()); } // special treatment for active binding: call bound function - if (containsNoActiveBindingAssumption != null && !containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(result)) { + if (!containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(result)) { return ((ActiveBinding) result).readValue(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java index 119494163dd6870b7c87dc556c2965f9a33ba57a..dd4a98c59592abbfd8e0cba0283966ed148a55ff 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ClassHierarchyNode.java @@ -53,7 +53,6 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.env.frame.ActiveBinding; import com.oracle.truffle.r.runtime.nodes.RBaseNode; public abstract class ClassHierarchyNode extends UnaryNode { @@ -150,13 +149,6 @@ public abstract class ClassHierarchyNode extends UnaryNode { return obj instanceof RTypedValue; } - @TruffleBoundary - @Specialization - protected RStringVector getClassHrActiveBinding(ActiveBinding object) { - Object result = RContext.getEngine().evalFunction(object.getFunction(), REnvironment.baseEnv().getFrame(), RCaller.createInvalid(null), RDataFactory.createEmptyStringVector()); - return execute(result); - } - @Specialization(guards = "!isRTypedValue(object)") protected RStringVector getClassHrTruffleObject(@SuppressWarnings("unused") TruffleObject object) { return truffleObjectClassHeader; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java index 1211aea3fc2c3bd7186e9ad82f4f6f77c00ec8a4..0f4f3a09ad999efe14c1b044aad6d5cfe733f300 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java @@ -467,9 +467,6 @@ public final class FrameSlotChangeMonitor { @CompilationFinal private StableValue<Object> stableValue; private int invalidationCount; - // TODO @CompilationFinal ? - @CompilationFinal private boolean activeBinding; - FrameSlotInfoImpl(boolean isSingletonFrame, boolean isGlobalEnv, Object identifier) { if (isSingletonFrame) { stableValue = new StableValue<>(null, identifier.toString()); @@ -509,7 +506,6 @@ public final class FrameSlotChangeMonitor { if (stableValue != null && stableValue.getValue() != value) { invalidateStableValue(value, slot); } - activeBinding = ActiveBinding.isActiveBinding(value); } private void invalidateStableValue(Object value, FrameSlot slot) { @@ -528,10 +524,6 @@ public final class FrameSlotChangeMonitor { public StableValue<Object> getStableValue() { return stableValue; } - - public boolean isActiveBinding() { - return activeBinding; - } } /** @@ -658,13 +650,7 @@ public final class FrameSlotChangeMonitor { public static synchronized Assumption getContainsNoActiveBindingAssumption(FrameDescriptor descriptor) { CompilerAsserts.neverPartOfCompilation(); - final FrameDescriptorMetaData frameDescriptorMetaData = frameDescriptors.get(descriptor); - return frameDescriptorMetaData != null ? frameDescriptorMetaData.getContainsNoActiveBindingAssumption() : null; - } - - public static synchronized boolean isContainsNoActiveBindingAssumptionValid(FrameDescriptor descriptor) { - Assumption assumption = getContainsNoActiveBindingAssumption(descriptor); - return assumption != null ? assumption.isValid() : true; + return frameDescriptors.get(descriptor).getContainsNoActiveBindingAssumption(); } public static synchronized StableValue<Object> getStableValueAssumption(FrameDescriptor descriptor, FrameSlot frameSlot, Object value) { @@ -686,8 +672,4 @@ public final class FrameSlotChangeMonitor { public static boolean isValidFrameDescriptor(FrameDescriptor frameDesc) { return getMetaData(frameDesc) != null; } - - public static boolean isActiveBinding(FrameSlot slot) { - return ((FrameSlotInfoImpl) slot.getInfo()).isActiveBinding(); - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java index 44cf86ac904bd69f45284fa1c1571c16c130118d..2c62896ff5aa889a89b1eccd9b9dd37f237debb6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/REnvTruffleFrameAccess.java @@ -28,10 +28,7 @@ import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; -import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlot; @@ -58,8 +55,6 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess { */ private Set<String> lockedBindings; - @CompilationFinal private Assumption containsNoActiveBindingAssumption; - public REnvTruffleFrameAccess(MaterializedFrame frame) { this.frame = frame; } @@ -76,14 +71,9 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess { if (slot == null) { return null; } else { - Object value = frame.getValue(slot); - if (containsNoActiveBindingAssumption == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - containsNoActiveBindingAssumption = FrameSlotChangeMonitor.getContainsNoActiveBindingAssumption(fd); - } // special treatment for active binding: call bound function - if (containsNoActiveBindingAssumption != null && !containsNoActiveBindingAssumption.isValid() && ActiveBinding.isActiveBinding(value)) { + if (ActiveBinding.isActiveBinding(value)) { return ((ActiveBinding) value).readValue(); } return value; @@ -119,14 +109,14 @@ public final class REnvTruffleFrameAccess extends REnvFrameAccess { FrameSlotChangeMonitor.setDoubleAndInvalidate(frame, slot, (double) value, false, null); break; case Object: - if (FrameSlotChangeMonitor.isActiveBinding(slot)) { - Object object; - try { - object = frame.getObject(slot); - } catch (FrameSlotTypeException e) { - object = null; - } - assert (object != null && ActiveBinding.isActiveBinding(object)); + Object object; + try { + object = frame.getObject(slot); + } catch (FrameSlotTypeException e) { + object = null; + } + + if (object != null && ActiveBinding.isActiveBinding(object)) { ((ActiveBinding) object).writeValue(value); } else { FrameSlotChangeMonitor.setObjectAndInvalidate(frame, slot, value, false, null);