Bug 1107937 - Followup: bring RematerializedFrame::hasCallObj implementation in line with Interpreter and BaselineFrame's. (r=jandem)
authorShu-yu Guo <shu@rfrn.org>
Mon, 15 Dec 2014 18:21:09 -0800
changeset 219865 1ba50d816a99aab42065be86d4b7e76b983e36d1
parent 219864 610eedd26c687c608b584eecc512263d0a3c2c50
child 219866 f9821f355c912a4f66b4988344981663b3c4fc65
push id10419
push usercbook@mozilla.com
push dateTue, 16 Dec 2014 12:45:27 +0000
treeherderfx-team@ec87657146eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1107937
milestone37.0a1
Bug 1107937 - Followup: bring RematerializedFrame::hasCallObj implementation in line with Interpreter and BaselineFrame's. (r=jandem)
js/src/jit/JitFrameIterator.h
js/src/jit/JitFrames.cpp
js/src/jit/RematerializedFrame.cpp
js/src/jit/RematerializedFrame.h
--- a/js/src/jit/JitFrameIterator.h
+++ b/js/src/jit/JitFrameIterator.h
@@ -582,17 +582,17 @@ class InlineFrameIterator
     uint32_t numActualArgs_;
 
     struct Nop {
         void operator()(const Value &v) { }
     };
 
   private:
     void findNextFrame();
-    JSObject *computeScopeChain(Value scopeChainValue) const;
+    JSObject *computeScopeChain(Value scopeChainValue, bool *hasCallObj = nullptr) const;
 
   public:
     InlineFrameIterator(ThreadSafeContext *cx, const JitFrameIterator *iter);
     InlineFrameIterator(JSRuntime *rt, const JitFrameIterator *iter);
     InlineFrameIterator(ThreadSafeContext *cx, const InlineFrameIterator *iter);
 
     bool more() const {
         return frame_ && framesRead_ < frameCount_;
@@ -614,29 +614,29 @@ class InlineFrameIterator
         if (more())
             return numActualArgs_;
 
         return frame_->numActualArgs();
     }
 
     template <class ArgOp, class LocalOp>
     void readFrameArgsAndLocals(ThreadSafeContext *cx, ArgOp &argOp, LocalOp &localOp,
-                                JSObject **scopeChain, Value *rval,
+                                JSObject **scopeChain, bool *hasCallObj, Value *rval,
                                 ArgumentsObject **argsObj, Value *thisv,
                                 ReadFrameArgsBehavior behavior,
                                 MaybeReadFallback &fallback) const
     {
         SnapshotIterator s(si_);
 
         // Read frame slots common to both function and global frames.
         Value scopeChainValue;
         s.readCommonFrameSlots(&scopeChainValue, rval);
 
         if (scopeChain)
-            *scopeChain = computeScopeChain(scopeChainValue);
+            *scopeChain = computeScopeChain(scopeChainValue, hasCallObj);
 
         // Read arguments, which only function frames have.
         if (isFunctionFrame()) {
             unsigned nactual = numActualArgs();
             unsigned nformal = callee()->nargs();
 
             // Get the non overflown arguments, which are taken from the inlined
             // frame, because it will have the updated value when JSOP_SETARG is
@@ -695,17 +695,18 @@ class InlineFrameIterator
     }
 
     template <class Op>
     void unaliasedForEachActual(JSContext *cx, Op op,
                                 ReadFrameArgsBehavior behavior,
                                 MaybeReadFallback &fallback) const
     {
         Nop nop;
-        readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr, nullptr, behavior, fallback);
+        readFrameArgsAndLocals(cx, op, nop, nullptr, nullptr, nullptr,
+                               nullptr, nullptr, behavior, fallback);
     }
 
     JSScript *script() const {
         return script_;
     }
     jsbytecode *pc() const {
         return pc_;
     }
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -2340,20 +2340,23 @@ InlineFrameIterator::findNextFrame()
         MOZ_ASSERT(!si_.moreFrames());
         frameCount_ = i;
     }
 
     framesRead_++;
 }
 
 JSObject *
-InlineFrameIterator::computeScopeChain(Value scopeChainValue) const
+InlineFrameIterator::computeScopeChain(Value scopeChainValue, bool *hasCallObj) const
 {
-    if (scopeChainValue.isObject())
+    if (scopeChainValue.isObject()) {
+        if (hasCallObj)
+            *hasCallObj = isFunctionFrame() && callee()->isHeavyweight();
         return &scopeChainValue.toObject();
+    }
 
     // Note we can hit this case even for heavyweight functions, in case we
     // are walking the frame during the function prologue, before the scope
     // chain has been initialized.
     if (isFunctionFrame())
         return callee()->environment();
 
     // Ion does not handle scripts that are not compile-and-go.
--- a/js/src/jit/RematerializedFrame.cpp
+++ b/js/src/jit/RematerializedFrame.cpp
@@ -35,17 +35,17 @@ RematerializedFrame::RematerializedFrame
     top_(top),
     pc_(iter.pc()),
     frameNo_(iter.frameNo()),
     numActualArgs_(numActualArgs),
     script_(iter.script())
 {
     CopyValueToRematerializedFrame op(slots_);
     MaybeReadFallback fallback(MagicValue(JS_OPTIMIZED_OUT));
-    iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &returnValue_,
+    iter.readFrameArgsAndLocals(cx, op, op, &scopeChain_, &hasCallObj_, &returnValue_,
                                 &argsObj_, &thisValue_, ReadFrame_Actuals,
                                 fallback);
 }
 
 /* static */ RematerializedFrame *
 RematerializedFrame::New(JSContext *cx, uint8_t *top, InlineFrameIterator &iter)
 {
     unsigned numFormals = iter.isFunctionFrame() ? iter.callee()->nargs() : 0;
@@ -134,16 +134,17 @@ bool
 RematerializedFrame::initFunctionScopeObjects(JSContext *cx)
 {
     MOZ_ASSERT(isNonEvalFunctionFrame());
     MOZ_ASSERT(fun()->isHeavyweight());
     CallObject *callobj = CallObject::createForFunction(cx, this);
     if (!callobj)
         return false;
     pushOnScopeChain(*callobj);
+    hasCallObj_ = true;
     return true;
 }
 
 void
 RematerializedFrame::mark(JSTracer *trc)
 {
     gc::MarkScriptRoot(trc, &script_, "remat ion frame script");
     gc::MarkObjectRoot(trc, &scopeChain_, "remat ion frame scope chain");
--- a/js/src/jit/RematerializedFrame.h
+++ b/js/src/jit/RematerializedFrame.h
@@ -24,16 +24,19 @@ namespace jit {
 class RematerializedFrame
 {
     // See DebugScopes::updateLiveScopes.
     bool prevUpToDate_;
 
     // Propagated to the Baseline frame once this is popped.
     bool isDebuggee_;
 
+    // Has a call object been pushed?
+    bool hasCallObj_;
+
     // The fp of the top frame associated with this possibly inlined frame.
     uint8_t *top_;
 
     // The bytecode at the time of rematerialization.
     jsbytecode *pc_;
 
     size_t frameNo_;
     unsigned numActualArgs_;
@@ -102,19 +105,18 @@ class RematerializedFrame
 
     JSObject *scopeChain() const {
         return scopeChain_;
     }
     void pushOnScopeChain(ScopeObject &scope);
     bool initFunctionScopeObjects(JSContext *cx);
 
     bool hasCallObj() const {
-        return maybeFun() &&
-               fun()->isHeavyweight() &&
-               scopeChain()->is<CallObject>();
+        MOZ_ASSERT(fun()->isHeavyweight());
+        return hasCallObj_;
     }
     CallObject &callObj() const;
 
     bool hasArgsObj() const {
         return !!argsObj_;
     }
     ArgumentsObject &argsObj() const {
         MOZ_ASSERT(hasArgsObj());