Bug 1282518 - Propagate return values from RematerializedFrames to BaselineFrames. r=shu
authorJim Blandy <jimb@mozilla.com>
Fri, 22 Jul 2016 14:19:48 -0700
changeset 346866 737a34eee8e6d108eab6046d720f41505a35091d
parent 346865 0bae57fa83b7203b893a810da7907b8d160869b8
child 346867 e16a16e8146afab78e8a43b7a0334770520c8f86
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1282518
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1282518 - Propagate return values from RematerializedFrames to BaselineFrames. r=shu
js/src/jit-test/tests/debug/RematerializedFrame-retval.js
js/src/jit/BaselineBailouts.cpp
js/src/jit/RematerializedFrame.h
js/src/vm/Stack-inl.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/RematerializedFrame-retval.js
@@ -0,0 +1,39 @@
+// |jit-test| error: InternalError; --baseline-eager; --ion-eager
+// Make sure that return values we store in RematerializedFrames via resumption
+// values get propagated to the BaselineFrames we build from them.
+//
+// Test case from bug 1285939; there's another in bug 1282518, but this one
+// takes less time to run, when it doesn't crash.
+
+var lfLogBuffer = `
+function testResumptionVal(resumptionVal, turnOffDebugMode) {
+  var g = newGlobal();
+  var dbg = new Debugger;
+  setInterruptCallback(function () {
+    dbg.addDebuggee(g);
+    var frame = dbg.getNewestFrame();
+    frame.onStep = function () {
+      frame.onStep = undefined;
+      return resumptionVal;
+    };
+    return true;
+  });
+  try {
+    return g.eval("(" + function f() {
+      invokeInterruptCallback(function (interruptRv) {
+    f({ valueOf: function () { dbg.g(dbg); }});
+  });
+    } + ")();");
+  } finally {  }
+}
+assertEq(testResumptionVal({ return: "not 42" }), "not 42");
+`;
+loadFile(lfLogBuffer);
+function loadFile(lfVarx) {
+    try {
+         let m = parseModule(lfVarx);
+         m.declarationInstantiation();
+         m.evaluation();
+    } catch (lfVare) {}
+}
+
--- a/js/src/jit/BaselineBailouts.cpp
+++ b/js/src/jit/BaselineBailouts.cpp
@@ -1715,16 +1715,18 @@ CopyFromRematerializedFrame(JSContext* c
         frame->thisArgument() = rematFrame->thisArgument();
 
     for (unsigned i = 0; i < frame->numActualArgs(); i++)
         frame->argv()[i] = rematFrame->argv()[i];
 
     for (size_t i = 0; i < frame->script()->nfixed(); i++)
         *frame->valueSlot(i) = rematFrame->locals()[i];
 
+    frame->setReturnValue(rematFrame->returnValue());
+
     if (rematFrame->hasCachedSavedFrame())
         frame->setHasCachedSavedFrame();
 
     JitSpew(JitSpew_BaselineBailouts,
             "  Copied from rematerialized frame at (%p,%u)",
             fp, inlineDepth);
 
     // Propagate the debuggee frame flag. For the case where the Debugger did
--- a/js/src/jit/RematerializedFrame.h
+++ b/js/src/jit/RematerializedFrame.h
@@ -214,17 +214,21 @@ class RematerializedFrame
         MOZ_ASSERT(isFunctionFrame());
         if (callee()->isArrow())
             return callee()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
         if (isConstructing())
             return argv()[numActualArgs()];
         return UndefinedValue();
     }
 
-    Value returnValue() const {
+    void setReturnValue(const Value& value) {
+        returnValue_ = value;
+    }
+
+    Value& returnValue() {
         return returnValue_;
     }
 
     void mark(JSTracer* trc);
     void dump();
 };
 
 } // namespace jit
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -432,17 +432,21 @@ AbstractFramePtr::returnValue() const
 
 inline void
 AbstractFramePtr::setReturnValue(const Value& rval) const
 {
     if (isInterpreterFrame()) {
         asInterpreterFrame()->setReturnValue(rval);
         return;
     }
-    asBaselineFrame()->setReturnValue(rval);
+    if (isBaselineFrame()) {
+        asBaselineFrame()->setReturnValue(rval);
+        return;
+    }
+    asRematerializedFrame()->setReturnValue(rval);
 }
 
 inline JSObject*
 AbstractFramePtr::scopeChain() const
 {
     if (isInterpreterFrame())
         return asInterpreterFrame()->scopeChain();
     if (isBaselineFrame())