From f4eff2b9106e5f9b49b2578bc102963f45f21051 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Fri, 16 Feb 2018 15:17:45 +0100
Subject: [PATCH] look for deoptimizable promises in arguments, not in frame
 slots

---
 .../r/nodes/builtin/base/EnvFunctions.java    |  2 +-
 .../r/nodes/builtin/base/FrameFunctions.java  |  4 +--
 .../function/FunctionExpressionNode.java      |  3 +-
 .../r/nodes/function/PromiseHelperNode.java   | 30 +++++--------------
 4 files changed, 13 insertions(+), 26 deletions(-)

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
index 324249e38d..70e06d1a1a 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java
@@ -349,7 +349,7 @@ public class EnvFunctions {
             MaterializedFrame matFrame = callerFrame.execute(frame);
 
             matFrame = matFrame instanceof VirtualEvalFrame ? ((VirtualEvalFrame) matFrame).getOriginalFrame() : matFrame;
-            deoptFrameNode.deoptimizeFrame(matFrame);
+            deoptFrameNode.deoptimizeFrame(RArguments.getArguments(matFrame));
             return REnvironment.frameToEnvironment(matFrame);
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
index 9cc46a846c..418fd51854 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java
@@ -444,7 +444,7 @@ public class FrameFunctions {
             }
 
             // Deoptimize every promise which is now in this frame, as it might leave it's stack
-            deoptFrameNode.deoptimizeFrame(result.getFrame());
+            deoptFrameNode.deoptimizeFrame(RArguments.getArguments(result.getFrame()));
             return result;
         }
     }
@@ -465,7 +465,7 @@ public class FrameFunctions {
                 RPairList next = result;
                 for (int i = 1; i < depth; i++) {
                     MaterializedFrame mf = helper.getNumberedFrame(frame, i).materialize();
-                    deoptFrameNode.deoptimizeFrame(mf);
+                    deoptFrameNode.deoptimizeFrame(RArguments.getArguments(mf));
                     next.setCar(REnvironment.frameToEnvironment(mf));
                     if (i != depth - 1) {
                         RPairList pl = RDataFactory.createPairList();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
index f677a2ecfd..9c46ea23e7 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/FunctionExpressionNode.java
@@ -35,6 +35,7 @@ import com.oracle.truffle.r.nodes.function.opt.EagerEvalHelper;
 import com.oracle.truffle.r.nodes.function.visibility.SetVisibilityNode;
 import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation;
 import com.oracle.truffle.r.runtime.ArgumentsSignature;
+import com.oracle.truffle.r.runtime.RArguments;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor;
@@ -68,7 +69,7 @@ public final class FunctionExpressionNode extends RSourceSectionNode implements
         MaterializedFrame matFrame = frame.materialize();
         if (deoptFrameNode != null) {
             // Deoptimize every promise which is now in this frame, as it might leave it's stack
-            deoptFrameNode.deoptimizeFrame(matFrame);
+            deoptFrameNode.deoptimizeFrame(RArguments.getArguments(matFrame));
         }
         if (!initialized) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
index 71968032f2..1019494ed4 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseHelperNode.java
@@ -88,32 +88,18 @@ public final class PromiseHelperNode extends RBaseNode {
          * Guarantees, that all {@link RPromise}s in frame are deoptimized and thus are safe to
          * leave it's stack-branch.
          *
-         * @param frame The frame to check for {@link RPromise}s to deoptimize
+         * @param arguments The frame's arguments, which will be checked for {@link RPromise}s to deoptimize
          * @return Whether there was at least on {@link RPromise} which needed to be deoptimized.
          */
-        @TruffleBoundary
-        public boolean deoptimizeFrame(MaterializedFrame frame) {
+        public boolean deoptimizeFrame(Object[] arguments) {
             boolean deoptOne = false;
-            for (FrameSlot slot : frame.getFrameDescriptor().getSlots().toArray(new FrameSlot[0])) {
-                // We're only interested in RPromises
-                if (slot.getKind() != FrameSlotKind.Object || !(slot.getIdentifier() instanceof String)) {
-                    continue;
-                }
-
-                // Try to read it...
-                try {
-                    Object value = FrameSlotChangeMonitor.getObject(slot, frame);
-
-                    // If it's a promise, deoptimize it!
-                    if (value instanceof RPromise) {
-                        RPromise promise = (RPromise) value;
-                        if (!promise.isEvaluated()) {
-                            deoptOne |= deoptimize(promise);
-                        }
+            for (Object value : arguments) {
+                // If it's a promise, deoptimize it!
+                if (value instanceof RPromise) {
+                    RPromise promise = (RPromise) value;
+                    if (!promise.isEvaluated()) {
+                        deoptOne |= deoptimize(promise);
                     }
-                } catch (FrameSlotTypeException err) {
-                    // Should not happen after former check on FrameSlotKind!
-                    throw RInternalError.shouldNotReachHere();
                 }
             }
             return deoptOne;
-- 
GitLab