Bug 980059 - Do some simple renaming and minor cleanups in prepration (r=jandem)
authorLuke Wagner <luke@mozilla.com>
Wed, 05 Mar 2014 17:15:32 -0600
changeset 189580 7f5a942d240f20efd9359dfea06fef4265870eb2
parent 189579 cb0eb74c0cc38d730db66ca9dbfd3b37329f5924
child 189581 88e543e9677c8f2e891c568d918769a2e022e8ad
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs980059
milestone30.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 980059 - Do some simple renaming and minor cleanups in prepration (r=jandem)
js/src/jscntxt.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/vm/Interpreter.cpp
js/src/vm/Interpreter.h
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -514,17 +514,17 @@ struct JSContext : public js::ExclusiveC
         return mainThread().activation()->isInterpreter();
     }
     bool currentlyRunningInJit() const {
         return mainThread().activation()->isJit();
     }
     js::StackFrame *interpreterFrame() const {
         return mainThread().activation()->asInterpreter()->current();
     }
-    js::FrameRegs &interpreterRegs() const {
+    js::InterpreterRegs &interpreterRegs() const {
         return mainThread().activation()->asInterpreter()->regs();
     }
 
     /*
      * Get the topmost script and optional pc on the stack. By default, this
      * function only returns a JSScript in the current compartment, returning
      * nullptr if the current script is in a different compartment. This
      * behavior can be overridden by passing ALLOW_CROSS_COMPARTMENT.
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1637,17 +1637,17 @@ const Class StarGeneratorObject::class_ 
  * Called from the JSOP_GENERATOR case in the interpreter, with fp referring
  * to the frame by which the generator function was activated.  Create a new
  * JSGenerator object, which contains its own StackFrame that we populate
  * from *fp.  We know that upon return, the JSOP_GENERATOR opcode will return
  * from the activation in fp, so we can steal away fp->callobj and fp->argsobj
  * if they are non-null.
  */
 JSObject *
-js_NewGenerator(JSContext *cx, const FrameRegs &stackRegs)
+js_NewGenerator(JSContext *cx, const InterpreterRegs &stackRegs)
 {
     JS_ASSERT(stackRegs.stackDepth() == 0);
     StackFrame *stackfp = stackRegs.fp();
 
     JS_ASSERT(stackfp->script()->isGenerator());
 
     Rooted<GlobalObject*> global(cx, &stackfp->global());
     RootedObject obj(cx);
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -238,21 +238,21 @@ enum JSGeneratorState
     JSGEN_CLOSING,  /* close method is doing asynchronous return */
     JSGEN_CLOSED    /* closed, cannot be started or closed again */
 };
 
 struct JSGenerator
 {
     js::HeapPtrObject   obj;
     JSGeneratorState    state;
-    js::FrameRegs       regs;
+    js::InterpreterRegs regs;
     JSGenerator         *prevGenerator;
     js::StackFrame      *fp;
     js::HeapValue       stackSnapshot[1];
 };
 
 extern JSObject *
-js_NewGenerator(JSContext *cx, const js::FrameRegs &regs);
+js_NewGenerator(JSContext *cx, const js::InterpreterRegs &regs);
 
 extern JSObject *
 js_InitIteratorClasses(JSContext *cx, js::HandleObject obj);
 
 #endif /* jsiter_h */
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -67,28 +67,28 @@ using JS::ForOfIterator;
  * influences performance. The MOZ_NEVER_INLINE is a temporary workaround until
  * we can remove the conservative scanner. See bug 849526 for more info.
  */
 #if defined(__clang__) && defined(JS_CPU_X86)
 static MOZ_NEVER_INLINE bool
 #else
 static bool
 #endif
-ToBooleanOp(const FrameRegs &regs)
+ToBooleanOp(const InterpreterRegs &regs)
 {
     return ToBoolean(regs.stackHandleAt(-1));
 }
 
 template <bool Eq>
 #if defined(__clang__) && defined(JS_CPU_X86)
 static MOZ_NEVER_INLINE bool
 #else
 static bool
 #endif
-LooseEqualityOp(JSContext *cx, FrameRegs &regs)
+LooseEqualityOp(JSContext *cx, InterpreterRegs &regs)
 {
     HandleValue rval = regs.stackHandleAt(-1);
     HandleValue lval = regs.stackHandleAt(-2);
     bool cond;
     if (!LooselyEqual(cx, lval, rval, &cond))
         return false;
     cond = (cond == Eq);
     regs.sp--;
@@ -889,43 +889,43 @@ js::UnwindScope(JSContext *cx, ScopeIter
           case ScopeIter::Call:
           case ScopeIter::StrictEvalScope:
             break;
         }
     }
 }
 
 static void
-ForcedReturn(JSContext *cx, ScopeIter &si, FrameRegs &regs)
+ForcedReturn(JSContext *cx, ScopeIter &si, InterpreterRegs &regs)
 {
     UnwindScope(cx, si, regs.fp()->script()->main());
     regs.setToEndOfScript();
 }
 
 static void
-ForcedReturn(JSContext *cx, FrameRegs &regs)
+ForcedReturn(JSContext *cx, InterpreterRegs &regs)
 {
     ScopeIter si(regs.fp(), regs.pc, cx);
     ForcedReturn(cx, si, regs);
 }
 
 void
-js::UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs)
+js::UnwindForUncatchableException(JSContext *cx, const InterpreterRegs &regs)
 {
     /* c.f. the regular (catchable) TryNoteIter loop in HandleError. */
     for (TryNoteIter tni(cx, regs); !tni.done(); ++tni) {
         JSTryNote *tn = *tni;
         if (tn->kind == JSTRY_ITER) {
             Value *sp = regs.spForStackDepth(tn->stackDepth);
             UnwindIteratorForUncatchableException(cx, &sp[-1].toObject());
         }
     }
 }
 
-TryNoteIter::TryNoteIter(JSContext *cx, const FrameRegs &regs)
+TryNoteIter::TryNoteIter(JSContext *cx, const InterpreterRegs &regs)
   : regs(regs),
     script(cx, regs.fp()->script()),
     pcOffset(regs.pc - script->main())
 {
     if (script->hasTrynotes()) {
         tn = script->trynotes()->vector;
         tnEnd = tn + script->trynotes()->length;
     } else {
@@ -983,17 +983,17 @@ enum HandleErrorContinuation
 {
     SuccessfulReturnContinuation,
     ErrorReturnContinuation,
     CatchContinuation,
     FinallyContinuation
 };
 
 static HandleErrorContinuation
-HandleError(JSContext *cx, FrameRegs &regs)
+HandleError(JSContext *cx, InterpreterRegs &regs)
 {
     JS_ASSERT(regs.fp()->script()->containsPC(regs.pc));
 
     ScopeIter si(regs.fp(), regs.pc, cx);
     bool ok = false;
 
   again:
     if (cx->isExceptionPending()) {
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -323,32 +323,32 @@ HasInstance(JSContext *cx, HandleObject 
 extern void
 UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc);
 
 /*
  * Unwind for an uncatchable exception. This means not running finalizers, etc;
  * just preserving the basic engine stack invariants.
  */
 extern void
-UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs);
+UnwindForUncatchableException(JSContext *cx, const InterpreterRegs &regs);
 
 extern bool
 OnUnknownMethod(JSContext *cx, HandleObject obj, Value idval, MutableHandleValue vp);
 
 class TryNoteIter
 {
-    const FrameRegs &regs;
+    const InterpreterRegs &regs;
     RootedScript script; /* TryNotIter is always stack allocated. */
     uint32_t pcOffset;
     JSTryNote *tn, *tnEnd;
 
     void settle();
 
   public:
-    explicit TryNoteIter(JSContext *cx, const FrameRegs &regs);
+    explicit TryNoteIter(JSContext *cx, const InterpreterRegs &regs);
     bool done() const;
     void operator++();
     JSTryNote *operator*() const { return tn; }
 };
 
 /************************************************************************/
 
 bool
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -278,17 +278,17 @@ InterpreterStack::getCallFrame(JSContext
     mozilla::PodCopy(argv, args.base(), 2 + args.length());
     SetValueRangeToUndefined(argv + 2 + args.length(), nmissing);
 
     *pargv = argv + 2;
     return reinterpret_cast<StackFrame *>(argv + 2 + nformal);
 }
 
 MOZ_ALWAYS_INLINE bool
-InterpreterStack::pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
+InterpreterStack::pushInlineFrame(JSContext *cx, InterpreterRegs &regs, const CallArgs &args,
                                   HandleScript script, InitialFrameFlags initial)
 {
     RootedFunction callee(cx, &args.callee().as<JSFunction>());
     JS_ASSERT(regs.sp == args.end());
     JS_ASSERT(callee->nonLazyScript() == script);
 
     script->ensureNonLazyCanonicalFunction(cx);
 
@@ -310,33 +310,33 @@ InterpreterStack::pushInlineFrame(JSCont
     /* Initialize frame, locals, regs. */
     fp->initCallFrame(cx, prev, prevpc, prevsp, *callee, script, argv, args.length(), flags);
 
     regs.prepareToRun(*fp, script);
     return true;
 }
 
 MOZ_ALWAYS_INLINE void
-InterpreterStack::popInlineFrame(FrameRegs &regs)
+InterpreterStack::popInlineFrame(InterpreterRegs &regs)
 {
     StackFrame *fp = regs.fp();
     regs.popInlineFrame();
     regs.sp[-1] = fp->returnValue();
     releaseFrame(fp);
     JS_ASSERT(regs.fp());
 }
 
 template <class Op>
 inline void
 ScriptFrameIter::unaliasedForEachActual(JSContext *cx, Op op)
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         interpFrame()->unaliasedForEachActual(op);
         return;
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isOptimizedJS()) {
             ionInlineFrames_.unaliasedForEachActual(cx, op, jit::ReadFrame_Actuals);
         } else {
             JS_ASSERT(data_.ionFrames_.isBaselineJS());
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -370,21 +370,21 @@ StackFrame::mark(JSTracer *trc)
     } else {
         gc::MarkScriptUnbarriered(trc, &exec.script, "script");
     }
     if (IS_GC_MARKING_TRACER(trc))
         script()->compartment()->zone()->active = true;
     gc::MarkValueUnbarriered(trc, returnValue().address(), "rval");
 }
 
-static void
-MarkLocals(StackFrame *frame, JSTracer *trc, unsigned start, unsigned end)
+void
+StackFrame::markValues(JSTracer *trc, unsigned start, unsigned end)
 {
     if (start < end)
-        gc::MarkValueRootRange(trc, end - start, frame->slots() + start, "vm_stack");
+        gc::MarkValueRootRange(trc, end - start, slots() + start, "vm_stack");
 }
 
 void
 StackFrame::markValues(JSTracer *trc, Value *sp, jsbytecode *pc)
 {
     JS_ASSERT(sp >= slots());
 
     NestedScopeObject *staticScope;
@@ -400,27 +400,27 @@ StackFrame::markValues(JSTracer *trc, Va
         StaticBlockObject &blockObj = staticScope->as<StaticBlockObject>();
         nlivefixed = blockObj.localOffset() + blockObj.numVariables();
     } else {
         nlivefixed = script()->nfixedvars();
     }
 
     if (nfixed == nlivefixed) {
         // All locals are live.
-        MarkLocals(this, trc, 0, sp - slots());
+        markValues(trc, 0, sp - slots());
     } else {
         // Mark operand stack.
-        MarkLocals(this, trc, nfixed, sp - slots());
+        markValues(trc, nfixed, sp - slots());
 
         // Clear dead locals.
         while (nfixed > nlivefixed)
             unaliasedLocal(--nfixed, DONT_CHECK_ALIASING).setUndefined();
 
         // Mark live locals.
-        MarkLocals(this, trc, 0, nlivefixed);
+        markValues(trc, 0, nlivefixed);
     }
 
     if (hasArgs()) {
         // Mark callee, |this| and arguments.
         unsigned argc = Max(numActualArgs(), numFormalArgs());
         gc::MarkValueRootRange(trc, argc + 2, argv_ - 2, "fp argv");
     } else {
         // Mark callee and |this|
@@ -449,17 +449,17 @@ js::MarkInterpreterActivations(JSRuntime
 
 }
 
 /*****************************************************************************/
 
 // Unlike the other methods of this calss, this method is defined here so that
 // we don't have to #include jsautooplen.h in vm/Stack.h.
 void
-FrameRegs::setToEndOfScript()
+InterpreterRegs::setToEndOfScript()
 {
     JSScript *script = fp()->script();
     sp = fp()->base();
     pc = script->codeEnd() - JSOP_RETRVAL_LENGTH;
     JS_ASSERT(*pc == JSOP_RETRVAL);
 }
 
 /*****************************************************************************/
@@ -515,17 +515,17 @@ ScriptFrameIter::popActivation()
 {
     ++data_.activations_;
     settleOnActivation();
 }
 
 void
 ScriptFrameIter::popInterpreterFrame()
 {
-    JS_ASSERT(data_.state_ == SCRIPTED);
+    JS_ASSERT(data_.state_ == INTERP);
 
     ++data_.interpFrames_;
 
     if (data_.interpFrames_.done())
         popActivation();
     else
         data_.pc_ = data_.interpFrames_.pc();
 }
@@ -607,17 +607,17 @@ ScriptFrameIter::settleOnActivation()
             if (data_.interpFrames_.done()) {
                 ++data_.activations_;
                 continue;
             }
         }
 
         JS_ASSERT(!data_.interpFrames_.frame()->runningInJit());
         data_.pc_ = data_.interpFrames_.pc();
-        data_.state_ = SCRIPTED;
+        data_.state_ = INTERP;
         return;
     }
 }
 
 ScriptFrameIter::Data::Data(JSContext *cx, PerThreadData *perThread, SavedOption savedOption,
                             ContextOption contextOption, JSPrincipals *principals)
   : perThread_(perThread),
     cx_(cx),
@@ -724,17 +724,17 @@ ScriptFrameIter::popJitFrame()
 #endif
 
 ScriptFrameIter &
 ScriptFrameIter::operator++()
 {
     switch (data_.state_) {
       case DONE:
         MOZ_ASSUME_UNREACHABLE("Unexpected state");
-      case SCRIPTED:
+      case INTERP:
         if (interpFrame()->isDebuggerFrame() && interpFrame()->evalInFramePrev()) {
             AbstractFramePtr eifPrev = interpFrame()->evalInFramePrev();
 
             // Eval-in-frame can cross contexts and works across saved frame
             // chains.
             ContextOption prevContextOption = data_.contextOption_;
             SavedOption prevSavedOption = data_.savedOption_;
             data_.contextOption_ = ALL_CONTEXTS;
@@ -795,30 +795,30 @@ ScriptFrameIter::copyDataAsAbstractFrame
 }
 
 JSCompartment *
 ScriptFrameIter::compartment() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
       case JIT:
         return data_.activations_.activation()->compartment();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 bool
 ScriptFrameIter::isFunctionFrame() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isFunctionFrame();
       case JIT:
 #ifdef JS_ION
         JS_ASSERT(data_.ionFrames_.isScripted());
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.isFunctionFrame();
         return ionInlineFrames_.isFunctionFrame();
 #else
@@ -829,17 +829,17 @@ ScriptFrameIter::isFunctionFrame() const
 }
 
 bool
 ScriptFrameIter::isGlobalFrame() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isGlobalFrame();
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.baselineFrame()->isGlobalFrame();
         JS_ASSERT(!script()->isForEval());
         return !script()->functionNonDelazifying();
 #else
@@ -850,17 +850,17 @@ ScriptFrameIter::isGlobalFrame() const
 }
 
 bool
 ScriptFrameIter::isEvalFrame() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isEvalFrame();
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.baselineFrame()->isEvalFrame();
         JS_ASSERT(!script()->isForEval());
         return false;
 #else
@@ -872,31 +872,31 @@ ScriptFrameIter::isEvalFrame() const
 
 bool
 ScriptFrameIter::isNonEvalFunctionFrame() const
 {
     JS_ASSERT(!done());
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isNonEvalFunctionFrame();
       case JIT:
         return !isEvalFrame() && isFunctionFrame();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 bool
 ScriptFrameIter::isGeneratorFrame() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isGeneratorFrame();
       case JIT:
         return false;
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 bool
@@ -909,17 +909,17 @@ ScriptFrameIter::isConstructing() const
 #ifdef JS_ION
         if (data_.ionFrames_.isOptimizedJS())
             return ionInlineFrames_.isConstructing();
         JS_ASSERT(data_.ionFrames_.isBaselineJS());
         return data_.ionFrames_.isConstructing();
 #else
         break;
 #endif        
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->isConstructing();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 AbstractFramePtr
 ScriptFrameIter::abstractFramePtr() const
 {
@@ -927,30 +927,30 @@ ScriptFrameIter::abstractFramePtr() cons
       case DONE:
         break;
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.baselineFrame();
 #endif
         break;
-      case SCRIPTED:
+      case INTERP:
         JS_ASSERT(interpFrame());
         return AbstractFramePtr(interpFrame());
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 void
 ScriptFrameIter::updatePcQuadratic()
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED: {
+      case INTERP: {
         StackFrame *frame = interpFrame();
         InterpreterActivation *activation = data_.activations_.activation()->asInterpreter();
 
         // Look for the current frame.
         data_.interpFrames_ = InterpreterFrameIterator(activation);
         while (data_.interpFrames_.frame() != frame)
             ++data_.interpFrames_;
 
@@ -988,17 +988,17 @@ ScriptFrameIter::updatePcQuadratic()
 }
 
 JSFunction *
 ScriptFrameIter::callee() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         JS_ASSERT(isFunctionFrame());
         return &interpFrame()->callee();
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.callee();
         JS_ASSERT(data_.ionFrames_.isOptimizedJS());
         return ionInlineFrames_.callee();
@@ -1010,17 +1010,17 @@ ScriptFrameIter::callee() const
 }
 
 Value
 ScriptFrameIter::calleev() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         JS_ASSERT(isFunctionFrame());
         return interpFrame()->calleev();
       case JIT:
 #ifdef JS_ION
         return ObjectValue(*callee());
 #else
         break;
 #endif
@@ -1029,40 +1029,46 @@ ScriptFrameIter::calleev() const
 }
 
 unsigned
 ScriptFrameIter::numActualArgs() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         JS_ASSERT(isFunctionFrame());
         return interpFrame()->numActualArgs();
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isOptimizedJS())
             return ionInlineFrames_.numActualArgs();
 
         JS_ASSERT(data_.ionFrames_.isBaselineJS());
         return data_.ionFrames_.numActualArgs();
 #else
         break;
 #endif
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
+unsigned
+ScriptFrameIter::numFormalArgs() const
+{
+    return script()->functionNonDelazifying()->nargs();
+}
+
 Value
 ScriptFrameIter::unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing) const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->unaliasedActual(i, checkAliasing);
       case JIT:
 #ifdef JS_ION
         JS_ASSERT(data_.ionFrames_.isBaselineJS());
         return data_.ionFrames_.baselineFrame()->unaliasedActual(i, checkAliasing);
 #else
         break;
 #endif
@@ -1079,17 +1085,17 @@ ScriptFrameIter::scopeChain() const
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isOptimizedJS())
             return ionInlineFrames_.scopeChain();
         return data_.ionFrames_.baselineFrame()->scopeChain();
 #else
         break;
 #endif
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->scopeChain();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 CallObject &
 ScriptFrameIter::callObj() const
 {
@@ -1102,17 +1108,17 @@ ScriptFrameIter::callObj() const
 }
 
 bool
 ScriptFrameIter::hasArgsObj() const
 {
     switch (data_.state_) {
       case DONE:
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->hasArgsObj();
       case JIT:
 #ifdef JS_ION
         JS_ASSERT(data_.ionFrames_.isBaselineJS());
         return data_.ionFrames_.baselineFrame()->hasArgsObj();
 #else
         break;
 #endif
@@ -1130,17 +1136,17 @@ ScriptFrameIter::argsObj() const
         break;
       case JIT:
 #ifdef JS_ION
         JS_ASSERT(data_.ionFrames_.isBaselineJS());
         return data_.ionFrames_.baselineFrame()->argsObj();
 #else
         break;
 #endif
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->argsObj();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 bool
 ScriptFrameIter::computeThis(JSContext *cx) const
 {
@@ -1161,17 +1167,17 @@ ScriptFrameIter::thisv() const
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isOptimizedJS())
             return ObjectValue(*ionInlineFrames_.thisObject());
         return data_.ionFrames_.baselineFrame()->thisValue();
 #else
         break;
 #endif
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->thisValue();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 Value
 ScriptFrameIter::returnValue() const
 {
@@ -1179,17 +1185,17 @@ ScriptFrameIter::returnValue() const
       case DONE:
         break;
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS())
             return data_.ionFrames_.baselineFrame()->returnValue();
 #endif
         break;
-      case SCRIPTED:
+      case INTERP:
         return interpFrame()->returnValue();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 void
 ScriptFrameIter::setReturnValue(const Value &v)
 {
@@ -1199,17 +1205,17 @@ ScriptFrameIter::setReturnValue(const Va
       case JIT:
 #ifdef JS_ION
         if (data_.ionFrames_.isBaselineJS()) {
             data_.ionFrames_.baselineFrame()->setReturnValue(v);
             return;
         }
 #endif
         break;
-      case SCRIPTED:
+      case INTERP:
         interpFrame()->setReturnValue(v);
         return;
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 size_t
 ScriptFrameIter::numFrameSlots() const
@@ -1224,17 +1230,17 @@ ScriptFrameIter::numFrameSlots() const
                 ionInlineFrames_.script()->nfixed();
         }
         jit::BaselineFrame *frame = data_.ionFrames_.baselineFrame();
         return frame->numValueSlots() - data_.ionFrames_.script()->nfixed();
 #else
         break;
 #endif
       }
-      case SCRIPTED:
+      case INTERP:
         JS_ASSERT(data_.interpFrames_.sp() >= interpFrame()->base());
         return data_.interpFrames_.sp() - interpFrame()->base();
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 Value
 ScriptFrameIter::frameSlotValue(size_t index) const
@@ -1250,17 +1256,17 @@ ScriptFrameIter::frameSlotValue(size_t i
             return si.maybeReadAllocByIndex(index);
         }
 
         index += data_.ionFrames_.script()->nfixed();
         return *data_.ionFrames_.baselineFrame()->valueSlot(index);
 #else
         break;
 #endif
-      case SCRIPTED:
+      case INTERP:
           return interpFrame()->base()[index];
     }
     MOZ_ASSUME_UNREACHABLE("Unexpected state");
 }
 
 #if defined(_MSC_VER)
 # pragma optimize("", on)
 #endif
@@ -1275,16 +1281,25 @@ js::SelfHostedFramesVisible()
         checked = true;
         char *env = getenv("MOZ_SHOW_ALL_JS_FRAMES");
         visible = !!env;
     }
     return visible;
 }
 #endif
 
+void
+NonBuiltinScriptFrameIter::settle()
+{
+    if (!SelfHostedFramesVisible()) {
+        while (!done() && script()->selfHosted())
+            ScriptFrameIter::operator++();
+    }
+}
+
 /*****************************************************************************/
 
 JSObject *
 AbstractFramePtr::evalPrevScopeChain(JSContext *cx) const
 {
     // Eval frames are not compiled by Ion, though their caller might be.
     AllFramesIter iter(cx);
     while (iter.isIon() || iter.abstractFramePtr() != *this)
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -18,28 +18,21 @@
 #endif
 #include "js/OldDebugAPI.h"
 
 struct JSCompartment;
 struct JSGenerator;
 
 namespace js {
 
+class ArgumentsObject;
+class InterpreterRegs;
+class ScopeObject;
+class ScriptFrameIter;
 class StackFrame;
-class FrameRegs;
-
-class InvokeFrameGuard;
-class ExecuteFrameGuard;
-class GeneratorFrameGuard;
-
-class ScriptFrameIter;
-class AllFramesIter;
-
-class ArgumentsObject;
-class ScopeObject;
 class StaticBlockObject;
 
 struct ScopeCoordinate;
 
 // VM stack layout
 //
 // A JSRuntime's stack consists of a linked list of activations. Every activation
 // contains a number of scripted frames that are either running in the interpreter
@@ -61,18 +54,18 @@ struct ScopeCoordinate;
 // The values after a StackFrame in memory are its locals followed by its
 // expression stack. StackFrame::argv_ points to the frame's arguments. Missing
 // formal arguments are padded with |undefined|, so the number of arguments is
 // always >= the number of formals.
 //
 // The top of an activation's current frame's expression stack is pointed to by the
 // activation's "current regs", which contains the stack pointer 'sp'. In the
 // interpreter, sp is adjusted as individual values are pushed and popped from
-// the stack and the FrameRegs struct (pointed to by the InterpreterActivation)
-// is a local var of js::Interpret.
+// the stack and the InterpreterRegs struct (pointed to by the
+// InterpreterActivation) is a local var of js::Interpret.
 
 enum MaybeCheckAliasing { CHECK_ALIASING = true, DONT_CHECK_ALIASING = false };
 
 /*****************************************************************************/
 
 #ifdef DEBUG
 extern void
 CheckLocalUnaliased(MaybeCheckAliasing checkAliasing, JSScript *script, uint32_t i);
@@ -362,34 +355,28 @@ class StackFrame
     static void staticAsserts() {
         JS_STATIC_ASSERT(offsetof(StackFrame, rval_) % sizeof(Value) == 0);
         JS_STATIC_ASSERT(sizeof(StackFrame) % sizeof(Value) == 0);
     }
 
     void writeBarrierPost();
 
     /*
-     * These utilities provide raw access to the values associated with a
-     * StackFrame (see "VM stack layout" comment). The utilities are private
-     * since they are not able to assert that only unaliased vars/formals are
-     * accessed. Normal code should prefer the StackFrame::unaliased* members
-     * (or FrameRegs::stackDepth for the usual "depth is at least" assertions).
+     * The utilities are private since they are not able to assert that only
+     * unaliased vars/formals are accessed. Normal code should prefer the
+     * StackFrame::unaliased* members (or InterpreterRegs::stackDepth for the
+     * usual "depth is at least" assertions).
      */
-  public:
     Value *slots() const { return (Value *)(this + 1); }
     Value *base() const { return slots() + script()->nfixed(); }
-    Value *argv() const { return argv_; }
 
-  private:
-    friend class FrameRegs;
+    friend class InterpreterRegs;
     friend class InterpreterStack;
     friend class ScriptFrameIter;
-    friend class CallObject;
-    friend class ClonedBlockObject;
-    friend class ArgumentsObject;
+    friend class jit::BaselineFrame;
 
     /*
      * Frame initialization, called by InterpreterStack operations after acquiring
      * the raw memory for the frame:
      */
 
     /* Used for Invoke and Interpret. */
     void initCallFrame(JSContext *cx, StackFrame *prev, jsbytecode *prevpc, Value *prevsp, JSFunction &callee,
@@ -533,16 +520,19 @@ class StackFrame
     inline Value &unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING);
     template <class Op> inline void unaliasedForEachActual(Op op);
 
     bool copyRawFrameSlots(AutoValueVector *v);
 
     unsigned numFormalArgs() const { JS_ASSERT(hasArgs()); return fun()->nargs(); }
     unsigned numActualArgs() const { JS_ASSERT(hasArgs()); return u.nactual; }
 
+    /* Watch out, this exposes a pointer to the unaliased formal arg array. */
+    Value *argv() const { return argv_; }
+
     /*
      * Arguments object
      *
      * If a non-eval function has script->needsArgsObj, an arguments object is
      * created in the prologue and stored in the local variable for the
      * 'arguments' binding (script->argumentsLocal). Since this local is
      * mutable, the arguments object can be overwritten and we can "lose" the
      * arguments object. Thus, StackFrame keeps an explicit argsObj_ field so
@@ -930,16 +920,17 @@ class StackFrame
 
     void clearSuspended() {
         JS_ASSERT(isGeneratorFrame());
         flags_ &= ~SUSPENDED;
     }
 
   public:
     void mark(JSTracer *trc);
+    void markValues(JSTracer *trc, unsigned start, unsigned end);
     void markValues(JSTracer *trc, Value *sp, jsbytecode *pc);
 
     // Entered Baseline/Ion from the interpreter.
     bool runningInJit() const {
         return !!(flags_ & RUNNING_IN_JIT);
     }
     void setRunningInJit() {
         flags_ |= RUNNING_IN_JIT;
@@ -966,17 +957,17 @@ InitialFrameFlagsFromConstructing(bool b
 static inline bool
 InitialFrameFlagsAreConstructing(InitialFrameFlags initial)
 {
     return !!(initial & INITIAL_CONSTRUCT);
 }
 
 /*****************************************************************************/
 
-class FrameRegs
+class InterpreterRegs
 {
   public:
     Value *sp;
     jsbytecode *pc;
   private:
     StackFrame *fp_;
   public:
     StackFrame *fp() const { return fp_; }
@@ -987,17 +978,17 @@ class FrameRegs
     }
 
     Value *spForStackDepth(unsigned depth) const {
         JS_ASSERT(fp_->script()->nfixed() + depth <= fp_->script()->nslots());
         return fp_->base() + depth;
     }
 
     /* For generators. */
-    void rebaseFromTo(const FrameRegs &from, StackFrame &to) {
+    void rebaseFromTo(const InterpreterRegs &from, StackFrame &to) {
         fp_ = &to;
         sp = to.slots() + (from.sp - from.fp_->slots());
         pc = from.pc;
         JS_ASSERT(fp_);
     }
 
     void popInlineFrame() {
         pc = fp_->prevpc();
@@ -1062,20 +1053,20 @@ class InterpreterStack
                                  HandleObject scopeChain, ExecuteType type,
                                  AbstractFramePtr evalInFrame);
 
     // Called to invoke a function.
     StackFrame *pushInvokeFrame(JSContext *cx, const CallArgs &args, InitialFrameFlags initial);
 
     // The interpreter can push light-weight, "inline" frames without entering a
     // new InterpreterActivation or recursively calling Interpret.
-    bool pushInlineFrame(JSContext *cx, FrameRegs &regs, const CallArgs &args,
+    bool pushInlineFrame(JSContext *cx, InterpreterRegs &regs, const CallArgs &args,
                          HandleScript script, InitialFrameFlags initial);
 
-    void popInlineFrame(FrameRegs &regs);
+    void popInlineFrame(InterpreterRegs &regs);
 
     inline void purge(JSRuntime *rt);
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
         return allocator_.sizeOfExcludingThis(mallocSizeOf);
     }
 };
 
@@ -1220,17 +1211,17 @@ static_assert(EnableInterruptsPseudoOpco
 class InterpreterFrameIterator;
 class RunState;
 
 class InterpreterActivation : public Activation
 {
     friend class js::InterpreterFrameIterator;
 
     RunState &state_;
-    FrameRegs regs_;
+    InterpreterRegs regs_;
     StackFrame *entryFrame_;
     size_t opMask_; // For debugger interrupts, see js::Interpret.
 
 #ifdef DEBUG
     size_t oldFrameCount_;
 #endif
 
   public:
@@ -1239,17 +1230,17 @@ class InterpreterActivation : public Act
 
     inline bool pushInlineFrame(const CallArgs &args, HandleScript script,
                                 InitialFrameFlags initial);
     inline void popInlineFrame(StackFrame *frame);
 
     StackFrame *current() const {
         return regs_.fp();
     }
-    FrameRegs &regs() {
+    InterpreterRegs &regs() {
         return regs_;
     }
     StackFrame *entryFrame() const {
         return entryFrame_;
     }
     size_t opMask() const {
         return opMask_;
     }
@@ -1409,45 +1400,25 @@ class InterpreterFrameIterator
 
     InterpreterFrameIterator &operator++();
 
     bool done() const {
         return fp_ == nullptr;
     }
 };
 
-/*
- * Iterate through the callstack (following fp->prev) of the given context.
- * Each element of said callstack can either be the execution of a script
- * (scripted function call, global code, eval code, debugger code) or the
- * invocation of a (C++) native. Example usage:
- *
- *   for (Stackiter i(cx); !i.done(); ++i) {
- *     if (i.isScript()) {
- *       ... i.fp() ... i.sp() ... i.pc()
- *     } else {
- *       JS_ASSERT(i.isNativeCall());
- *       ... i.args();
- *     }
- *   }
- *
- * The SavedOption parameter additionally lets the iterator continue through
- * breaks in the callstack (from JS_SaveFrameChain). The default is to stop.
- */
 class ScriptFrameIter
 {
   public:
     enum SavedOption { STOP_AT_SAVED, GO_THROUGH_SAVED };
     enum ContextOption { CURRENT_CONTEXT, ALL_CONTEXTS };
-    enum State { DONE, SCRIPTED, JIT };
+    enum State { DONE, INTERP, JIT };
 
-    /*
-     * Unlike ScriptFrameIter itself, ScriptFrameIter::Data can be allocated on
-     * the heap, so this structure should not contain any GC things.
-     */
+    // Unlike ScriptFrameIter itself, ScriptFrameIter::Data can be allocated on
+    // the heap, so this structure should not contain any GC things.
     struct Data
     {
         PerThreadData * perThread_;
         JSContext *     cx_;
         SavedOption     savedOption_;
         ContextOption   contextOption_;
         JSPrincipals *  principals_;
 
@@ -1462,110 +1433,54 @@ class ScriptFrameIter
         jit::IonFrameIterator ionFrames_;
 #endif
 
         Data(JSContext *cx, PerThreadData *perThread, SavedOption savedOption,
              ContextOption contextOption, JSPrincipals *principals);
         Data(const Data &other);
     };
 
-    friend class ::JSBrokenFrameIterator;
-  private:
-    Data data_;
-#ifdef JS_ION
-    jit::InlineFrameIterator ionInlineFrames_;
-#endif
-
-    void popActivation();
-    void popInterpreterFrame();
-#ifdef JS_ION
-    void nextJitFrame();
-    void popJitFrame();
-#endif
-    void settleOnActivation();
-
-  public:
     ScriptFrameIter(JSContext *cx, SavedOption = STOP_AT_SAVED);
     ScriptFrameIter(JSContext *cx, ContextOption, SavedOption, JSPrincipals* = nullptr);
     ScriptFrameIter(const ScriptFrameIter &iter);
     ScriptFrameIter(const Data &data);
     ScriptFrameIter(AbstractFramePtr frame);
 
     bool done() const { return data_.state_ == DONE; }
-    ScriptFrameIter &operator++();
 
-    Data *copyData() const;
-    AbstractFramePtr copyDataAsAbstractFramePtr() const;
+    // -------------------------------------------------------
+    // The following functions can only be called when !done()
+    // -------------------------------------------------------
+
+    ScriptFrameIter &operator++();
 
     JSCompartment *compartment() const;
+    Activation *activation() const { return data_.activations_.activation(); }
 
-    JSScript *script() const {
-        JS_ASSERT(!done());
-        if (data_.state_ == SCRIPTED)
-            return interpFrame()->script();
-#ifdef JS_ION
-        JS_ASSERT(data_.state_ == JIT);
-        if (data_.ionFrames_.isOptimizedJS())
-            return ionInlineFrames_.script();
-        return data_.ionFrames_.script();
-#else
-        return nullptr;
-#endif
-    }
-    bool isJit() const {
-        JS_ASSERT(!done());
-        return data_.state_ == JIT;
-    }
-
-    bool isIon() const {
-#ifdef JS_ION
-        return isJit() && data_.ionFrames_.isOptimizedJS();
-#else
-        return false;
-#endif
-    }
-
-    bool isBaseline() const {
-#ifdef JS_ION
-        return isJit() && data_.ionFrames_.isBaselineJS();
-#else
-        return false;
-#endif
-    }
+    bool isInterp() const { JS_ASSERT(!done()); return data_.state_ == INTERP;  }
+    bool isJit() const { JS_ASSERT(!done()); return data_.state_ == JIT; }
+    inline bool isIon() const;
+    inline bool isBaseline() const;
 
     bool isFunctionFrame() const;
     bool isGlobalFrame() const;
     bool isEvalFrame() const;
     bool isNonEvalFunctionFrame() const;
     bool isGeneratorFrame() const;
     bool isConstructing() const;
-
     bool hasArgs() const { return isNonEvalFunctionFrame(); }
 
-    AbstractFramePtr abstractFramePtr() const;
-
-    /*
-     * When entering IonMonkey, the top interpreter frame (pushed by the caller)
-     * is kept on the stack as bookkeeping (with runningInIon() set). The
-     * contents of the frame are ignored by Ion code (and GC) and thus
-     * immediately become garbage and must not be touched directly.
-     */
-    StackFrame *interpFrame() const {
-        JS_ASSERT(data_.state_ == SCRIPTED);
-        return data_.interpFrames_.frame();
-    }
-
-    Activation *activation() const { return data_.activations_.activation(); }
+    inline JSScript *script() const;
 
     jsbytecode *pc() const { JS_ASSERT(!done()); return data_.pc_; }
     void        updatePcQuadratic();
     JSFunction *callee() const;
     Value       calleev() const;
     unsigned    numActualArgs() const;
-    unsigned    numFormalArgs() const { return script()->functionNonDelazifying()->nargs(); }
+    unsigned    numFormalArgs() const;
     Value       unaliasedActual(unsigned i, MaybeCheckAliasing = CHECK_ALIASING) const;
     template <class Op> inline void unaliasedForEachActual(JSContext *cx, Op op);
 
     JSObject   *scopeChain() const;
     CallObject &callObj() const;
 
     bool        hasArgsObj() const;
     ArgumentsObject &argsObj() const;
@@ -1579,61 +1494,139 @@ class ScriptFrameIter
 
     JSFunction *maybeCallee() const {
         return isFunctionFrame() ? callee() : nullptr;
     }
 
     // These are only valid for the top frame.
     size_t      numFrameSlots() const;
     Value       frameSlotValue(size_t index) const;
+
+    // --------------------------------------------------------------------------
+    // The following functions can only be called when isInterp() or isBaseline()
+    // --------------------------------------------------------------------------
+
+    AbstractFramePtr abstractFramePtr() const;
+    AbstractFramePtr copyDataAsAbstractFramePtr() const;
+    Data *copyData() const;
+
+    // This can only be called when isInterp():
+    inline StackFrame *interpFrame() const;
+
+  private:
+    Data data_;
+#ifdef JS_ION
+    jit::InlineFrameIterator ionInlineFrames_;
+#endif
+
+    void popActivation();
+    void popInterpreterFrame();
+#ifdef JS_ION
+    void nextJitFrame();
+    void popJitFrame();
+#endif
+    void settleOnActivation();
+
+    friend class ::JSBrokenFrameIterator;
 };
 
 #ifdef DEBUG
 bool SelfHostedFramesVisible();
 #else
 static inline bool
 SelfHostedFramesVisible()
 {
     return false;
 }
 #endif
 
 /* A filtering of the ScriptFrameIter to only stop at non-self-hosted scripts. */
 class NonBuiltinScriptFrameIter : public ScriptFrameIter
 {
-    void settle() {
-        if (!SelfHostedFramesVisible()) {
-            while (!done() && script()->selfHosted())
-                ScriptFrameIter::operator++();
-        }
-    }
+    void settle();
 
   public:
-    NonBuiltinScriptFrameIter(JSContext *cx, ScriptFrameIter::SavedOption opt = ScriptFrameIter::STOP_AT_SAVED)
-      : ScriptFrameIter(cx, opt) { settle(); }
+    NonBuiltinScriptFrameIter(JSContext *cx,
+                              ScriptFrameIter::SavedOption opt = ScriptFrameIter::STOP_AT_SAVED)
+      : ScriptFrameIter(cx, opt)
+    {
+        settle();
+    }
 
     NonBuiltinScriptFrameIter(JSContext *cx,
                               ScriptFrameIter::ContextOption contextOption,
                               ScriptFrameIter::SavedOption savedOption,
                               JSPrincipals *principals = nullptr)
-      : ScriptFrameIter(cx, contextOption, savedOption, principals) { settle(); }
+      : ScriptFrameIter(cx, contextOption, savedOption, principals)
+    {
+        settle();
+    }
 
     NonBuiltinScriptFrameIter(const ScriptFrameIter::Data &data)
       : ScriptFrameIter(data)
     {}
 
-    NonBuiltinScriptFrameIter &operator++() { ScriptFrameIter::operator++(); settle(); return *this; }
+    NonBuiltinScriptFrameIter &operator++() {
+        ScriptFrameIter::operator++();
+        settle();
+        return *this;
+    }
 };
 
 /*
  * Blindly iterate over all frames in the current thread's stack. These frames
  * can be from different contexts and compartments, so beware.
  */
 class AllFramesIter : public ScriptFrameIter
 {
   public:
     AllFramesIter(JSContext *cx)
       : ScriptFrameIter(cx, ScriptFrameIter::ALL_CONTEXTS, ScriptFrameIter::GO_THROUGH_SAVED)
     {}
 };
 
+/* Popular inline definitions. */
+
+inline JSScript *
+ScriptFrameIter::script() const
+{
+    JS_ASSERT(!done());
+    if (data_.state_ == INTERP)
+        return interpFrame()->script();
+#ifdef JS_ION
+    JS_ASSERT(data_.state_ == JIT);
+    if (data_.ionFrames_.isOptimizedJS())
+        return ionInlineFrames_.script();
+    return data_.ionFrames_.script();
+#else
+    return nullptr;
+#endif
+}
+
+inline bool
+ScriptFrameIter::isIon() const
+{
+#ifdef JS_ION
+    return isJit() && data_.ionFrames_.isOptimizedJS();
+#else
+    return false;
+#endif
+}
+
+inline bool
+ScriptFrameIter::isBaseline() const
+{
+#ifdef JS_ION
+    return isJit() && data_.ionFrames_.isBaselineJS();
+#else
+    return false;
+#endif
+}
+
+inline StackFrame *
+ScriptFrameIter::interpFrame() const
+{
+    JS_ASSERT(data_.state_ == INTERP);
+    return data_.interpFrames_.frame();
+}
+
 }  /* namespace js */
 #endif /* vm_Stack_h */