[JAEGER] Merge from tracemonkey.
authorDavid Mandelin <dmandelin@mozilla.com>
Thu, 19 Aug 2010 17:30:04 -0700
changeset 53466 a6f55b452f916635e8cc51be5a4418f41d08c410
parent 53465 22c103069d7c105adc3457093fbc5482e5557df8 (current diff)
parent 51120 76ede469d9a3a8afbf1bf9d240be06b9c3a22bf2 (diff)
child 53467 8a0513a5c024cdcaa92742f25861a8ce1fa7ac6f
push idunknown
push userunknown
push dateunknown
milestone2.0b5pre
[JAEGER] Merge from tracemonkey.
js/src/jscntxtinlines.h
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsrecursion.cpp
js/src/jstracer.cpp
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -392,23 +392,23 @@ FrameRegsIter::FrameRegsIter(JSContext *
     curpc = cx->regs->pc;
     return;
 }
 
 inline Value *
 FrameRegsIter::contiguousDownFrameSP(JSStackFrame *up)
 {
     JS_ASSERT(up->argv);
-    Value *sp = up->argv + up->argc;
+    Value *sp = up->argv + up->numActualArgs();
 #ifdef DEBUG
     JS_ASSERT(sp <= up->argEnd());
     JS_ASSERT(sp >= (up->down->hasScript() ? up->down->base() : up->down->slots()));
     if (up->hasFunction()) {
         uint16 nargs = up->getFunction()->nargs;
-        uintN argc = up->argc;
+        uintN argc = up->numActualArgs();
         uintN missing = argc < nargs ? nargs - argc : 0;
         JS_ASSERT(sp == up->argEnd() - missing);
     } else {
         JS_ASSERT(sp == up->argEnd());
     }
 #endif
     return sp;
 }
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -294,17 +294,17 @@ InitExnPrivate(JSContext *cx, JSObject *
     valueCount = 0;
     for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
         if (fp->hasFunction() && fp->argv) {
             Value v = NullValue();
             if (checkAccess &&
                 !checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) {
                 break;
             }
-            valueCount += fp->argc;
+            valueCount += fp->numActualArgs();
         }
         ++stackDepth;
     }
     JS_RestoreExceptionState(cx, state);
     JS_SetErrorReporter(cx, older);
     fpstop = fp;
 
     size = offsetof(JSExnPrivate, stackElems);
@@ -336,19 +336,19 @@ InitExnPrivate(JSContext *cx, JSObject *
     for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) {
         if (!fp->hasFunction()) {
             elem->funName = NULL;
             elem->argc = 0;
         } else {
             elem->funName = fp->getFunction()->atom
                             ? ATOM_TO_STRING(fp->getFunction()->atom)
                             : cx->runtime->emptyString;
-            elem->argc = fp->argc;
-            memcpy(values, fp->argv, fp->argc * sizeof(jsval));
-            values += fp->argc;
+            elem->argc = fp->numActualArgs();
+            memcpy(values, fp->argv, elem->argc * sizeof(jsval));
+            values += elem->argc;
         }
         elem->ulineno = 0;
         elem->filename = NULL;
         if (fp->hasScript()) {
             elem->filename = fp->getScript()->filename;
             if (fp->pc(cx))
                 elem->ulineno = js_FramePCToLineNumber(cx, fp);
         }
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -132,17 +132,17 @@ js_GetArgsProperty(JSContext *cx, JSStac
         }
         return obj->getProperty(cx, id, vp);
     }
 
     vp->setUndefined();
     if (JSID_IS_INT(id)) {
         uint32 arg = uint32(JSID_TO_INT(id));
         JSObject *argsobj = fp->maybeArgsObj();
-        if (arg < fp->argc) {
+        if (arg < fp->numActualArgs()) {
             if (argsobj) {
                 if (argsobj->getArgsElement(arg).isMagic(JS_ARGS_HOLE))
                     return argsobj->getProperty(cx, id, vp);
             }
             *vp = fp->argv[arg];
         } else {
             /*
              * Per ECMA-262 Ed. 3, 10.1.8, last bulleted item, do not share
@@ -158,17 +158,17 @@ js_GetArgsProperty(JSContext *cx, JSStac
              */
             if (argsobj)
                 return argsobj->getProperty(cx, id, vp);
         }
     } else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
         JSObject *argsobj = fp->maybeArgsObj();
         if (argsobj && argsobj->isArgsLengthOverridden())
             return argsobj->getProperty(cx, id, vp);
-        vp->setInt32(fp->argc);
+        vp->setInt32(fp->numActualArgs());
     }
     return true;
 }
 
 static JSObject *
 NewArguments(JSContext *cx, JSObject *parent, uint32 argc, JSObject *callee)
 {
     JSObject *proto;
@@ -221,32 +221,33 @@ js_GetArgsObject(JSContext *cx, JSStackF
         fp = fp->down;
 
     /* Create an arguments object for fp only if it lacks one. */
     if (fp->hasArgsObj())
         return fp->getArgsObj();
 
     /* Compute the arguments object's parent slot from fp's scope chain. */
     JSObject *global = fp->getScopeChain()->getGlobal();
-    JSObject *argsobj = NewArguments(cx, global, fp->argc, &fp->argv[-2].toObject());
+    JSObject *argsobj = NewArguments(cx, global, fp->numActualArgs(), &fp->argv[-2].toObject());
     if (!argsobj)
         return argsobj;
 
     /*
      * Strict mode functions have arguments which copy the initial parameter
      * values.  It is the caller's responsibility to get the arguments object
      * before any parameters are modified!  (The emitter ensures this by
      * synthesizing an arguments access at the start of any strict mode
      * function which contains an assignment to a parameter or which calls
      * eval.)  Non-strict mode arguments use the frame pointer to retrieve
      * up-to-date parameter values.
      */
     if (argsobj->isStrictArguments()) {
-        JS_ASSERT_IF(fp->argc > 0, argsobj->dslots[-1].toPrivateUint32() >= fp->argc);
-        memcpy(argsobj->dslots, fp->argv, fp->argc * sizeof(Value));
+        JS_ASSERT_IF(fp->numActualArgs() > 0,
+                     argsobj->dslots[-1].toPrivateUint32() >= fp->numActualArgs());
+        memcpy(argsobj->dslots, fp->argv, fp->numActualArgs() * sizeof(Value));
     } else {
         argsobj->setPrivate(fp);
     }
 
     fp->setArgsObj(argsobj);
     return argsobj;
 }
 
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -535,17 +535,17 @@ InvokeCommon(JSContext *cx, JSFunction *
     SetValueRangeToUndefined(fp->slots(), nvars);
 
     /* Initialize frame. */
     fp->setThisValue(args.thisv());
     fp->setCallObj(NULL);
     fp->setArgsObj(NULL);
     fp->setScript(script);
     fp->setFunction(fun);
-    fp->argc = args.argc();
+    fp->setNumActualArgs(args.argc());
     fp->argv = args.argv();
     fp->setAnnotation(NULL);
     fp->setScopeChain(NULL);
     fp->setBlockChain(NULL);
     fp->flags = flags;
     JS_ASSERT(!fp->hasIMacroPC());
 
     if (flags & JSINVOKE_CONSTRUCT)
@@ -609,27 +609,28 @@ InvokeCommon(JSContext *cx, JSFunction *
     JS_ASSERT_IF(!args.thisv().isPrimitive(), IsSaneThisObject(args.thisv().toObject()));
 
     /* Call the hook if present after we fully initialized the frame. */
     JSInterpreterHook hook = cx->debugHooks->callHook;
     void *hookData = NULL;
     if (hook)
         hookData = hook(cx, fp, JS_TRUE, 0, cx->debugHooks->callHookData);
 
-    DTrace::enterJSFun(cx, fp, fun, fp->down, fp->argc, fp->argv);
+    DTrace::enterJSFun(cx, fp, fun, fp->down, fp->numActualArgs(), fp->argv);
 
     /* Call the function, either a native method or an interpreted script. */
     JSBool ok;
     if (native) {
 #ifdef DEBUG_NOT_THROWING
         JSBool alreadyThrowing = cx->throwing;
 #endif
         /* Primitive |this| should not be passed to slow natives. */
         JSObject *thisp = fun ? fp->getThisObject(cx) : fp->getThisValue().toObjectOrNull();
-        ok = callJSNative(cx, native, thisp, fp->argc, fp->argv, fp->addressReturnValue());
+        ok = callJSNative(cx, native, thisp, fp->numActualArgs(), fp->argv, 
+		                  fp->addressReturnValue());
 
         JS_ASSERT(cx->fp == fp);
         JS_RUNTIME_METER(cx->runtime, nativeCalls);
 #ifdef DEBUG_NOT_THROWING
         if (ok && !alreadyThrowing)
             ASSERT_NOT_THROWING(cx);
 #endif
     } else {
@@ -873,17 +874,17 @@ Execute(JSContext *cx, JSObject *chain, 
     JSObject *initialVarObj;
     if (down) {
         /* Propagate arg state for eval and the debugger API. */
         fp->setCallObj(down->maybeCallObj());
         fp->setArgsObj(NULL);
         fp->setFunction((script->staticLevel > 0) ? down->maybeFunction() : NULL);
         fp->setThisValue(down->getThisValue());
         fp->flags = flags;
-        fp->argc = down->argc;
+        fp->setNumActualArgs(down->numActualArgs());
         fp->argv = down->argv;
         fp->setAnnotation(down->maybeAnnotation());
         fp->setScopeChain(chain);
 
         /*
          * We want to call |down->varobj()|, but this requires knowing the
          * CallStackSegment of |down|. If |down == cx->fp|, the callstack is
          * simply the context's active callstack, so we can use
@@ -894,17 +895,17 @@ Execute(JSContext *cx, JSObject *chain, 
                         ? down->varobj(cx)
                         : down->varobj(cx->containingSegment(down));
     } else {
         fp->setCallObj(NULL);
         fp->setArgsObj(NULL);
         fp->setFunction(NULL);
         fp->setThisValue(UndefinedValue());  /* Make GC-safe until initialized below. */
         fp->flags = flags;
-        fp->argc = 0;
+        fp->setNumActualArgs(0);
         fp->argv = NULL;
         fp->setAnnotation(NULL);
 
         JSObject *innerizedChain = chain;
         OBJ_TO_INNER_OBJECT(cx, innerizedChain);
         if (!innerizedChain)
             return false;
         fp->setScopeChain(innerizedChain);
@@ -1403,23 +1404,23 @@ js::GetUpvar(JSContext *cx, uintN closur
     JS_ASSERT(targetLevel < UpvarCookie::UPVAR_LEVEL_LIMIT);
 
     JSStackFrame *fp = cx->findFrameAtLevel(targetLevel);
     uintN slot = cookie.slot();
     Value *vp;
 
     if (!fp->hasFunction() || (fp->flags & JSFRAME_EVAL)) {
         vp = fp->slots() + fp->getFixedCount();
-    } else if (slot < fp->getArgumentCount()) {
+    } else if (slot < fp->numFormalArgs()) {
         vp = fp->argv;
     } else if (slot == UpvarCookie::CALLEE_SLOT) {
         vp = &fp->argv[-2];
         slot = 0;
     } else {
-        slot -= fp->getArgumentCount();
+        slot -= fp->numFormalArgs();
         JS_ASSERT(slot < fp->getSlotCount());
         vp = fp->slots();
     }
 
     return vp[slot];
 }
 
 #ifdef DEBUG
@@ -3039,17 +3040,17 @@ BEGIN_CASE(JSOP_ENDITER)
         goto error;
 }
 END_CASE(JSOP_ENDITER)
 
 BEGIN_CASE(JSOP_FORARG)
 {
     JS_ASSERT(regs.sp - 1 >= fp->base());
     uintN slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->getArgumentCount());
+    JS_ASSERT(slot < fp->numFormalArgs());
     JS_ASSERT(regs.sp[-1].isObject());
     if (!IteratorNext(cx, &regs.sp[-1].toObject(), &fp->argv[slot]))
         goto error;
 }
 END_CASE(JSOP_FORARG)
 
 BEGIN_CASE(JSOP_FORLOCAL)
 {
@@ -3972,17 +3973,17 @@ BEGIN_CASE(JSOP_ARGDEC)
 BEGIN_CASE(JSOP_INCARG)
     incr =  1; incr2 =  1; goto do_arg_incop;
 BEGIN_CASE(JSOP_ARGINC)
     incr =  1; incr2 =  0;
 
   do_arg_incop:
     // If we initialize in the declaration, MSVC complains that the labels skip init.
     slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->getArgumentCount());
+    JS_ASSERT(slot < fp->numFormalArgs());
     METER_SLOT_OP(op, slot);
     vp = fp->argv + slot;
     goto do_int_fast_incop;
 
 BEGIN_CASE(JSOP_DECLOCAL)
     incr = -1; incr2 = -1; goto do_local_incop;
 BEGIN_CASE(JSOP_LOCALDEC)
     incr = -1; incr2 =  0; goto do_local_incop;
@@ -4048,17 +4049,17 @@ BEGIN_CASE(JSOP_GETTHISPROP)
     i = 0;
     PUSH_NULL();
     goto do_getprop_with_obj;
 
 BEGIN_CASE(JSOP_GETARGPROP)
 {
     i = ARGNO_LEN;
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->getArgumentCount());
+    JS_ASSERT(slot < fp->numFormalArgs());
     PUSH_COPY(fp->argv[slot]);
     goto do_getprop_body;
 }
 
 BEGIN_CASE(JSOP_GETLOCALPROP)
 {
     i = SLOTNO_LEN;
     uint32 slot = GET_SLOTNO(regs.pc);
@@ -4717,17 +4718,17 @@ BEGIN_CASE(JSOP_APPLY)
                     goto error;
             }
 
             /* Initialize stack frame. */
             newfp->setCallObj(NULL);
             newfp->setArgsObj(NULL);
             newfp->setScript(newscript);
             newfp->setFunction(fun);
-            newfp->argc = argc;
+            newfp->setNumActualArgs(argc);
             newfp->argv = vp + 2;
             newfp->clearReturnValue();
             newfp->setAnnotation(NULL);
             newfp->setScopeChain(obj->getParent());
             newfp->flags = flags;
             newfp->setBlockChain(NULL);
             JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags));
             JS_ASSERT_IF(!vp[1].isPrimitive(), IsSaneThisObject(vp[1].toObject()));
@@ -4770,17 +4771,17 @@ BEGIN_CASE(JSOP_APPLY)
                 CHECK_INTERRUPT_HANDLER();
             } else {
                 fp->setHookData(NULL);
             }
 
             inlineCallCount++;
             JS_RUNTIME_METER(rt, inlineCalls);
 
-            DTrace::enterJSFun(cx, fp, fun, fp->down, fp->argc, fp->argv);
+            DTrace::enterJSFun(cx, fp, fun, fp->down, fp->numActualArgs(), fp->argv);
 
 #ifdef JS_TRACER
             if (TraceRecorder *tr = TRACE_RECORDER(cx)) {
                 AbortableRecordingStatus status = tr->record_EnterFrame(inlineCallCount);
                 RESTORE_INTERP_VARS();
                 if (StatusAbortsRecorderIfActive(status)) {
                     if (TRACE_RECORDER(cx)) {
                         JS_ASSERT(TRACE_RECORDER(cx) == tr);
@@ -5268,28 +5269,28 @@ BEGIN_CASE(JSOP_ARGCNT)
     PUSH_COPY(rval);
 }
 END_CASE(JSOP_ARGCNT)
 
 BEGIN_CASE(JSOP_GETARG)
 BEGIN_CASE(JSOP_CALLARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->getArgumentCount());
+    JS_ASSERT(slot < fp->numFormalArgs());
     METER_SLOT_OP(op, slot);
     PUSH_COPY(fp->argv[slot]);
     if (op == JSOP_CALLARG)
         PUSH_NULL();
 }
 END_CASE(JSOP_GETARG)
 
 BEGIN_CASE(JSOP_SETARG)
 {
     uint32 slot = GET_ARGNO(regs.pc);
-    JS_ASSERT(slot < fp->getArgumentCount());
+    JS_ASSERT(slot < fp->numFormalArgs());
     METER_SLOT_OP(op, slot);
     fp->argv[slot] = regs.sp[-1];
 }
 END_SET_CASE(JSOP_SETARG)
 
 BEGIN_CASE(JSOP_GETLOCAL)
 {
     uint32 slot = GET_SLOTNO(regs.pc);
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -403,17 +403,17 @@ struct JSStackFrame
         JS_ASSERT(hasFunction());
         return fun;
     }
 
     JSFunction* maybeFunction() const {
         return fun;
     }
 
-    size_t getArgumentCount() const {
+    size_t numFormalArgs() const {
         return getFunction()->nargs;
     }
 
     void setFunction(JSFunction *f) {
         fun = f;
     }
 
     /* This-value accessors */
@@ -447,16 +447,30 @@ struct JSStackFrame
     js::Value* addressReturnValue() {
         return &rval;
     }
 
     static size_t offsetReturnValue() {
         return offsetof(JSStackFrame, rval);
     }
 
+    /* Argument count accessors */
+
+    size_t numActualArgs() const {
+        return argc;
+    }
+
+    void setNumActualArgs(size_t n) {
+        argc = n;
+    }
+
+    static size_t offsetNumActualArgs() {
+        return offsetof(JSStackFrame, argc);
+    }
+
     /* Other accessors */
 
     void putActivationObjects(JSContext *cx) {
         /*
          * The order of calls here is important as js_PutCallObject needs to
          * access argsobj.
          */
         if (hasCallObj()) {
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -1136,18 +1136,18 @@ JS_REQUIRES_STACK JSObject *
 js_NewGenerator(JSContext *cx)
 {
     JSObject *obj = NewBuiltinClassInstance(cx, &js_GeneratorClass);
     if (!obj)
         return NULL;
 
     /* Load and compute stack slot counts. */
     JSStackFrame *fp = cx->fp;
-    uintN argc = fp->argc;
-    uintN nargs = JS_MAX(argc, fp->getArgumentCount());
+    uintN argc = fp->numActualArgs();
+    uintN nargs = JS_MAX(argc, fp->numFormalArgs());
     uintN vplen = 2 + nargs;
 
     /* Compute JSGenerator size. */
     uintN nbytes = sizeof(JSGenerator) +
                    (-1 + /* one Value included in JSGenerator */
                     vplen +
                     VALUES_PER_STACK_FRAME +
                     fp->getSlotCount()) * sizeof(Value);
@@ -1180,17 +1180,17 @@ js_NewGenerator(JSContext *cx)
     newfp->setArgsObj(fp->maybeArgsObj());
     if (fp->hasArgsObj()) {      /* Steal args object. */
         fp->getArgsObj()->setPrivate(newfp);
         fp->setArgsObj(NULL);
     }
     newfp->setScript(fp->getScript());
     newfp->setFunction(fp->getFunction());
     newfp->setThisValue(fp->getThisValue());
-    newfp->argc = fp->argc;
+    newfp->setNumActualArgs(fp->numActualArgs());
     newfp->argv = vp + 2;
     newfp->setReturnValue(fp->getReturnValue());
     newfp->setAnnotation(NULL);
     newfp->setScopeChain(fp->maybeScopeChain());
     JS_ASSERT(!fp->hasBlockChain());
     newfp->setBlockChain(NULL);
     newfp->flags = fp->flags | JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR;
     JS_ASSERT(!newfp->hasIMacroPC());
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -6394,17 +6394,18 @@ js_DumpStackFrame(JSContext *cx, JSStack
         fprintf(stderr, "  sp:    %p = slots + %u\n", (void *) sp, (unsigned) (sp - fp->slots()));
         if (sp - fp->slots() < 10000) { // sanity
             for (Value *p = fp->slots(); p < sp; p++) {
                 fprintf(stderr, "    %p: ", (void *) p);
                 dumpValue(*p);
                 fputc('\n', stderr);
             }
         }
-        fprintf(stderr, "  argv:  %p (argc: %u)\n", (void *) fp->argv, (unsigned) fp->argc);
+        fprintf(stderr, "  argv:  %p (argc: %u)\n",
+                (void *) fp->argv, (unsigned) fp->numActualArgs());
         MaybeDumpObject("callobj", fp->maybeCallObj());
         MaybeDumpObject("argsobj", fp->maybeArgsObj());
         MaybeDumpValue("this", fp->getThisValue());
         fprintf(stderr, "  rval: ");
         dumpValue(fp->getReturnValue());
         fputc('\n', stderr);
 
         fprintf(stderr, "  flags:");
--- a/js/src/jsrecursion.cpp
+++ b/js/src/jsrecursion.cpp
@@ -252,20 +252,20 @@ TraceRecorder::upRecursion()
     fi->pc = (jsbytecode*)return_pc;
     fi->imacpc = NULL;
 
     /*
      * Need to compute this from the down frame, since the stack could have
      * moved on this one.
      */
     fi->spdist = DownFrameSP(cx) - cx->fp->down->slots();
-    JS_ASSERT(cx->fp->argc == cx->fp->down->argc);
-    fi->set_argc(uint16(cx->fp->argc), false);
+    JS_ASSERT(cx->fp->numActualArgs() == cx->fp->down->numActualArgs());
+    fi->set_argc(uint16(cx->fp->numActualArgs()), false);
     fi->callerHeight = downPostSlots;
-    fi->callerArgc = cx->fp->down->argc;
+    fi->callerArgc = cx->fp->down->numActualArgs();
 
     if (anchor && anchor->exitType == RECURSIVE_MISMATCH_EXIT) {
         /*
          * Case 0: Anchoring off a RECURSIVE_MISMATCH guard. Guard on this FrameInfo.
          * This is always safe because this point is only reached on simple "call myself"
          * recursive functions.
          */
 #if defined DEBUG
@@ -385,17 +385,17 @@ public:
  * SLURP_FAIL means that the interpreter frame has been popped, the return
  * value has been written to the native stack, but there was a type mismatch
  * while unboxing the interpreter slots.
  */
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
 {
     /* Missing - no go */
-    if (cx->fp->argc != cx->fp->getArgumentCount())
+    if (cx->fp->numActualArgs() != cx->fp->numFormalArgs())
         RETURN_STOP_A("argc != nargs");
 
     LIns* argv_ins;
     unsigned frameDepth;
     unsigned downPostSlots;
 
     FrameRegsIter i(cx);
     LIns* fp_ins =
@@ -445,20 +445,20 @@ TraceRecorder::slurpDownFrames(jsbytecod
                                              ACCSET_OTHER),
                                 "savedPC"),
                         INS_CONSTPTR(return_pc)),
               RECURSIVE_SLURP_MISMATCH_EXIT);
 
         /* fp->down->argc should be == argc. */
         guard(true,
               lir->ins2(LIR_eqi,
-                        addName(lir->insLoad(LIR_ldi, fp_ins, offsetof(JSStackFrame, argc),
+                        addName(lir->insLoad(LIR_ldi, fp_ins, JSStackFrame::offsetNumActualArgs(),
                                              ACCSET_OTHER),
                                 "argc"),
-                        INS_CONST(cx->fp->argc)),
+                        INS_CONST(cx->fp->numActualArgs())),
               MISMATCH_EXIT);
 
         /* Pop the interpreter frame. */
         LIns* args[] = { lirbuf->state, cx_ins };
         guard(false, lir->insEqI_0(lir->insCall(&js_PopInterpFrame_ci, args)), MISMATCH_EXIT);
 
         /* Compute slots for the down frame. */
         downPostSlots = NativeStackSlots(cx, 1) - NativeStackSlots(cx, 0);
@@ -586,17 +586,17 @@ TraceRecorder::slurpDownFrames(jsbytecod
 
     JSStackFrame *const fp = i.fp();
 
     /* callee */
     slurpSlot(argv_ins, -2 * ptrdiff_t(sizeof(Value)), &fp->argv[-2], &info);
     /* this */
     slurpSlot(argv_ins, -1 * ptrdiff_t(sizeof(Value)), &fp->argv[-1], &info);
     /* args[0..n] */
-    for (unsigned i = 0; i < JS_MAX(fp->argc, fp->getArgumentCount()); i++)
+    for (unsigned i = 0; i < JS_MAX(fp->numActualArgs(), fp->numFormalArgs()); i++)
         slurpSlot(argv_ins, i * sizeof(Value), &fp->argv[i], &info);
     /* argsobj */
     slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetArgsObj(), fp->addressArgsObj(), &info);
     /* scopeChain */
     slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetScopeChain(), fp->addressScopeChain(), &info);
     /* vars */
     LIns* slots_ins = addName(lir->ins2(LIR_addp, fp_ins, INS_CONSTWORD(sizeof(JSStackFrame))),
                               "slots");
@@ -609,17 +609,17 @@ TraceRecorder::slurpDownFrames(jsbytecod
                                         slots_ins,
                                         INS_CONSTWORD(nfixed * sizeof(Value))),
                               "stackBase");
 
     size_t limit = size_t(i.sp() - fp->base());
     if (anchor && anchor->exitType == RECURSIVE_SLURP_FAIL_EXIT)
         limit--;
     else
-        limit -= fp->getArgumentCount() + 2;
+        limit -= fp->numFormalArgs() + 2;
     for (size_t i = 0; i < limit; i++)
         slurpSlot(stack_ins, i * sizeof(Value), &stack[i], &info);
 
     JS_ASSERT(info.curSlot == downPostSlots);
 
     /* Jump back to the start */
     exit = copy(exit);
     exit->exitType = UNSTABLE_LOOP_EXIT;
@@ -676,17 +676,18 @@ TraceRecorder::downRecursion()
     JSScript *script = fp->getScript();
     if ((jsbytecode*)fragment->ip < script->code ||
         (jsbytecode*)fragment->ip >= script->code + script->length) {
         RETURN_STOP_A("inner recursive call must compile first");
     }
 
     /* Adjust the stack by the budget the down-frame needs. */
     int slots = NativeStackSlots(cx, 1) - NativeStackSlots(cx, 0);
-    JS_ASSERT(unsigned(slots) == NativeStackSlots(cx, 1) - fp->argc - 2 - fp->getFixedCount() - 2);
+    JS_ASSERT(unsigned(slots) ==
+              NativeStackSlots(cx, 1) - fp->numActualArgs() - 2 - fp->getFixedCount() - 2);
 
     /* Guard that there is enough stack space. */
     JS_ASSERT(tree->maxNativeStackSlots >= tree->nativeStackBase / sizeof(double));
     int guardSlots = slots + tree->maxNativeStackSlots -
                      tree->nativeStackBase / sizeof(double);
     LIns* sp_top = lir->ins2(LIR_addp, lirbuf->sp, lir->insImmWord(guardSlots * sizeof(double)));
     guard(true, lir->ins2(LIR_ltp, sp_top, eos_ins), OOM_EXIT);
 
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -1090,17 +1090,17 @@ Tracker::set(const void* v, LIns* i)
     if (!p)
         p = addTrackerPage(v);
     p->map[getTrackerPageOffset(v)] = i;
 }
 
 static inline jsuint
 argSlots(JSStackFrame* fp)
 {
-    return JS_MAX(fp->argc, fp->getArgumentCount());
+    return JS_MAX(fp->numActualArgs(), fp->numFormalArgs());
 }
 
 static inline bool
 hasInt32Repr(const Value &v)
 {
     if (!v.isNumber())
         return false;
     if (v.isInt32())
@@ -1834,17 +1834,17 @@ VisitFrameSlots(Visitor &visitor, JSCont
     }
 
     visitor.setStackSlotKind("stack");
     Value *base = fp->base();
     JS_ASSERT(sp >= base && sp <= fp->slots() + fp->getSlotCount());
     if (!visitor.visitStackSlots(base, size_t(sp - base), fp))
         return false;
     if (up) {
-        int missing = up->getArgumentCount() - up->argc;
+        int missing = up->numFormalArgs() - up->numActualArgs();
         if (missing > 0) {
             visitor.setStackSlotKind("missing");
             if (!visitor.visitStackSlots(sp, size_t(missing), fp))
                 return false;
         }
     }
     return true;
 }
@@ -2007,17 +2007,17 @@ NativeStackSlots(JSContext *cx, unsigned
                 slots += 2/*callee,this*/ + argSlots(fp);
 #ifdef DEBUG
             CountSlotsVisitor visitor;
             VisitStackSlots(visitor, cx, callDepth);
             JS_ASSERT(visitor.count() == slots && !visitor.stopped());
 #endif
             return slots;
         }
-        int missing = fp->getArgumentCount() - fp->argc;
+        int missing = fp->numFormalArgs() - fp->numActualArgs();
         if (missing > 0)
             slots += missing;
     }
     JS_NOT_REACHED("NativeStackSlots");
 }
 
 class CaptureTypesVisitor : public SlotVisitorBase
 {
@@ -3373,20 +3373,22 @@ GetClosureArg(JSContext* cx, JSObject* c
     return GetFromClosure<ArgClosureTraits>(cx, callee, cv, result);
 }
 
 struct VarClosureTraits
 {
     // See documentation on ArgClosureTraits for what these functions
     // should be doing.
     // See also UpvarVarTraits.
-    static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) { return 4 + fp->argc + slot; }
+    static inline uint32 adj_slot(JSStackFrame* fp, uint32 slot) {
+        return 4 + fp->numActualArgs() + slot;
+    }
 
     static inline LIns* adj_slot_lir(LirWriter* lir, LIns* fp_ins, unsigned slot) {
-        LIns *argc_ins = lir->insLoad(LIR_ldi, fp_ins, offsetof(JSStackFrame, argc), ACCSET_OTHER);
+        LIns *argc_ins = lir->insLoad(LIR_ldi, fp_ins, JSStackFrame::offsetNumActualArgs(), ACCSET_OTHER);
         return lir->ins2(LIR_addi, lir->insImmI(4 + slot), argc_ins);
     }
 
     // See also UpvarVarTraits.
     static inline Value* slots(JSStackFrame* fp) { return fp->slots(); }
     static inline Value* slots(JSObject* obj) {
         // We know Call objects use dslots.
         return obj->dslots + slot_offset(obj);
@@ -3532,24 +3534,24 @@ TraceRecorder::importImpl(LIns* base, pt
         mark = JS_ARENA_MARK(&cx->tempPool);
         if (fp->getFunction()->hasLocalNames())
             localNames = js_GetLocalNameArray(cx, fp->getFunction(), &cx->tempPool);
         funName = fp->getFunction()->atom
                 ? js_AtomToPrintableString(cx, fp->getFunction()->atom)
                 : "<anonymous>";
     }
     if (!strcmp(prefix, "argv")) {
-        if (index < fp->getArgumentCount()) {
+        if (index < fp->numFormalArgs()) {
             JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[index]);
             JS_snprintf(name, sizeof name, "$%s.%s", funName, js_AtomToPrintableString(cx, atom));
         } else {
             JS_snprintf(name, sizeof name, "$%s.<arg%d>", funName, index);
         }
     } else if (!strcmp(prefix, "vars")) {
-        JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[fp->getArgumentCount() + index]);
+        JSAtom *atom = JS_LOCAL_NAME_TO_ATOM(localNames[fp->numFormalArgs() + index]);
         JS_snprintf(name, sizeof name, "$%s.%s", funName, js_AtomToPrintableString(cx, atom));
     } else {
         JS_snprintf(name, sizeof name, "$%s%d", prefix, index);
     }
 
     if (mark)
         JS_ARENA_RELEASE(&cx->tempPool, mark);
     addName(ins, name);
@@ -5703,17 +5705,17 @@ SynthesizeFrame(JSContext* cx, const Fra
         newfp = stack.getInlineFrame(cx, sp, 0, nslots);
     }
 
     /* Initialize the new stack frame. */
     newfp->setCallObj(NULL);
     newfp->setArgsObj(NULL);
     newfp->setScript(newscript);
     newfp->setFunction(fun);
-    newfp->argc = argc;
+    newfp->setNumActualArgs(argc);
     newfp->argv = argv;
 #ifdef DEBUG
     // Initialize argv[-1] to a known-bogus value so we'll catch it if
     // someone forgets to initialize it later.
     newfp->argv[-1].setMagic(JS_THIS_POISON);
 #endif
     newfp->clearReturnValue();
     newfp->setAnnotation(NULL);
@@ -5751,17 +5753,17 @@ SynthesizeFrame(JSContext* cx, const Fra
      * Duplicate native stack layout computation: see VisitFrameSlots header comment.
      *
      * FIXME - We must count stack slots from caller's operand stack up to (but
      * not including) callee's, including missing arguments. Could we shift
      * everything down to the caller's fp->slots (where vars start) and avoid
      * some of the complexity?
      */
     return (fi.spdist - newfp->down->getFixedCount()) +
-           ((fun->nargs > newfp->argc) ? fun->nargs - newfp->argc : 0) +
+          ((fun->nargs > newfp->numActualArgs()) ? fun->nargs - newfp->numActualArgs() : 0) +
            newscript->nfixed + SPECIAL_FRAME_SLOTS;
 }
 
 JS_REQUIRES_STACK static void
 SynthesizeSlowNativeFrame(TracerState& state, JSContext *cx, VMSideExit *exit)
 {
     /*
      * StackSpace::getInlineFrame calls js_ReportOutOfScriptQuota if there is
@@ -5778,17 +5780,17 @@ SynthesizeSlowNativeFrame(TracerState& s
     JS_ASSERT(!fun->isInterpreted() && !fun->isFastNative());
     JS_ASSERT(fun->u.n.extra == 0);
 #endif
 
     fp->setCallObj(NULL);
     fp->setArgsObj(NULL);
     fp->setScript(NULL);
     fp->setThisValue(state.nativeVp[1]);
-    fp->argc = state.nativeVpLen - 2;
+    fp->setNumActualArgs(state.nativeVpLen - 2);
     fp->argv = state.nativeVp + 2;
     fp->setFunction(GET_FUNCTION_PRIVATE(cx, fp->callee()));
     fp->clearReturnValue();
     fp->setAnnotation(NULL);
     fp->setScopeChain(cx->fp->getScopeChain());
     fp->setBlockChain(NULL);
     fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
     JS_ASSERT(!fp->hasIMacroPC());
@@ -5970,17 +5972,17 @@ AttemptToStabilizeTree(JSContext* cx, JS
     if (exit->exitType == RECURSIVE_UNLINKED_EXIT) {
         if (++exit->hitcount >= MAX_RECURSIVE_UNLINK_HITS) {
             Blacklist((jsbytecode*)from->ip);
             TrashTree(cx, from);
             return false;
         }
         if (exit->recursive_pc != cx->regs->pc)
             return false;
-        from = LookupLoop(tm, exit->recursive_pc, globalObj, globalShape, cx->fp->argc);
+        from = LookupLoop(tm, exit->recursive_pc, globalObj, globalShape, cx->fp->numActualArgs());
         if (!from)
             return false;
         /* use stale TI for RecordTree - since from might not have one anymore. */
     }
 
     JS_ASSERT(from == from->root);
 
     /* If this tree has been blacklisted, don't try to record a new one. */
@@ -6097,18 +6099,18 @@ AttemptToExtendTree(JSContext* cx, VMSid
             stackSlots = fullMap.length();
             ngslots = BuildGlobalTypeMapFromInnerTree(fullMap, e2);
             JS_ASSERT(ngslots >= e1->numGlobalSlots); // inner tree must have all globals
             JS_ASSERT(ngslots == fullMap.length() - stackSlots);
             typeMap = fullMap.data();
         }
         JS_ASSERT(ngslots >= anchor->numGlobalSlots);
         bool rv = TraceRecorder::startRecorder(cx, anchor, c, stackSlots, ngslots, typeMap,
-                                               exitedFrom, outer, cx->fp->argc, Record_Branch,
-                                               hits < maxHits);
+                                               exitedFrom, outer, cx->fp->numActualArgs(),
+                                               Record_Branch, hits < maxHits);
 #ifdef MOZ_TRACEVIS
         if (!rv && tvso)
             tvso->r = R_FAIL_EXTEND_START;
 #endif
         return rv;
     }
 #ifdef MOZ_TRACEVIS
     if (tvso) tvso->r = R_FAIL_EXTEND_COLD;
@@ -6146,17 +6148,17 @@ TraceRecorder::recordLoopEdge(JSContext*
     if (tm->needFlush) {
         ResetJIT(cx, FR_DEEP_BAIL);
         return MONITOR_NOT_RECORDING;
     }
 
     JS_ASSERT(r->fragment && !r->fragment->lastIns);
     TreeFragment* root = r->fragment->root;
     TreeFragment* first = LookupOrAddLoop(tm, cx->regs->pc, root->globalObj,
-                                        root->globalShape, cx->fp->argc);
+                                          root->globalShape, cx->fp->numActualArgs());
 
     /*
      * Make sure the shape of the global object still matches (this might flush
      * the JIT cache).
      */
     JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
     uint32 globalShape = -1;
     SlotList* globalSlots = NULL;
@@ -6174,17 +6176,17 @@ TraceRecorder::recordLoopEdge(JSContext*
     // Find a matching inner tree. If none can be found, compile one.
     TreeFragment* f = r->findNestedCompatiblePeer(first);
     if (!f || !f->code()) {
         AUDIT(noCompatInnerTrees);
 
         TreeFragment* outerFragment = root;
         jsbytecode* outer = (jsbytecode*) outerFragment->ip;
         uint32 outerArgc = outerFragment->argc;
-        JS_ASSERT(cx->fp->argc == first->argc);
+        JS_ASSERT(cx->fp->numActualArgs() == first->argc);
         AbortRecording(cx, "No compatible inner tree");
 
         return RecordingIfTrue(RecordTree(cx, first, outer, outerArgc, globalSlots, Record_Branch));
     }
 
     AbortableRecordingStatus status = r->attemptTreeCall(f, inlineCallCount);
     if (status == ARECORD_CONTINUE)
         return MONITOR_RECORDING;
@@ -7198,17 +7200,17 @@ MonitorLoopEdge(JSContext* cx, uintN& in
     if (JS_THREAD_DATA(cx)->interruptFlags) {
 #ifdef MOZ_TRACEVIS
         tvso.r = R_CALLBACK_PENDING;
 #endif
         return MONITOR_NOT_RECORDING;
     }
 
     jsbytecode* pc = cx->regs->pc;
-    uint32 argc = cx->fp->argc;
+    uint32 argc = cx->fp->numActualArgs();
 
     TreeFragment* f = LookupOrAddLoop(tm, pc, globalObj, globalShape, argc);
 
     /*
      * If we have no code in the anchor and no peers, we definitively won't be
      * able to activate any trees, so start compiling.
      */
     if (!f->code() && !f->peer) {
@@ -8059,17 +8061,17 @@ DeepBail(JSContext *cx)
      * |tm->storage| at a time.
      */
     state->deepBailSp = state->sp;
 }
 
 JS_REQUIRES_STACK Value&
 TraceRecorder::argval(unsigned n) const
 {
-    JS_ASSERT(n < cx->fp->getArgumentCount());
+    JS_ASSERT(n < cx->fp->numFormalArgs());
     return cx->fp->argv[n];
 }
 
 JS_REQUIRES_STACK Value&
 TraceRecorder::varval(unsigned n) const
 {
     JS_ASSERT(n < cx->fp->getSlotCount());
     return cx->fp->slots()[n];
@@ -8244,25 +8246,25 @@ TraceRecorder::callProp(JSObject* obj, J
 
     uintN slot = uint16(sprop->shortid);
 
     vp = NULL;
     uintN upvar_slot = SPROP_INVALID_SLOT;
     JSStackFrame* cfp = (JSStackFrame*) obj->getPrivate();
     if (cfp) {
         if (sprop->getterOp() == js_GetCallArg) {
-            JS_ASSERT(slot < cfp->getArgumentCount());
+            JS_ASSERT(slot < cfp->numFormalArgs());
             vp = &cfp->argv[slot];
             upvar_slot = slot;
             nr.v = *vp;
         } else if (sprop->getterOp() == js_GetCallVar ||
                    sprop->getterOp() == js_GetCallVarChecked) {
             JS_ASSERT(slot < cfp->getSlotCount());
             vp = &cfp->slots()[slot];
-            upvar_slot = cx->fp->getArgumentCount() + slot;
+            upvar_slot = cx->fp->numFormalArgs() + slot;
             nr.v = *vp;
         } else {
             RETURN_STOP("dynamic property of Call object");
         }
 
         // Now assert that our use of sprop->shortid was in fact kosher.
         JS_ASSERT(sprop->hasShortID());
 
@@ -10285,25 +10287,27 @@ TraceRecorder::clearCurrentFrameSlotsFro
 /*
  * If we have created an |arguments| object for the frame, we must copy the
  * argument values into the object as properties in case it is used after
  * this frame returns.
  */
 JS_REQUIRES_STACK void
 TraceRecorder::putActivationObjects()
 {
-    bool have_args = cx->fp->hasArgsObj() && !cx->fp->getArgsObj()->isStrictArguments() && cx->fp->argc > 0;
+    bool have_args = cx->fp->hasArgsObj() &&
+        !cx->fp->getArgsObj()->isStrictArguments() &&
+        cx->fp->numActualArgs() > 0;
     bool have_call = cx->fp->hasFunction() &&
         JSFUN_HEAVYWEIGHT_TEST(cx->fp->getFunction()->flags) &&
         cx->fp->getFunction()->countArgsAndVars();
 
     if (!have_args && !have_call)
         return;
 
-    int nargs = have_args ? argSlots(cx->fp) : cx->fp->getArgumentCount();
+    int nargs = have_args ? argSlots(cx->fp) : cx->fp->numFormalArgs();
 
     LIns* args_ins;
     if (nargs) {
         args_ins = lir->insAlloc(sizeof(Value) * nargs);
         for (int i = 0; i < nargs; ++i) {
             box_value_into(cx->fp->argv[i], get(&cx->fp->argv[i]), args_ins, i * sizeof(Value),
                            ACCSET_OTHER);
         }
@@ -10327,33 +10331,33 @@ TraceRecorder::putActivationObjects()
                                i * sizeof(Value), ACCSET_OTHER);
             }
         } else {
             slots_ins = INS_CONSTPTR(0);
         }
 
         LIns* scopeChain_ins = getFrameObjPtr(cx->fp->addressScopeChain());
         LIns* args[] = { slots_ins, INS_CONST(nslots), args_ins,
-                         INS_CONST(cx->fp->getArgumentCount()), scopeChain_ins, cx_ins };
+                         INS_CONST(cx->fp->numFormalArgs()), scopeChain_ins, cx_ins };
         lir->insCall(&js_PutCallObjectOnTrace_ci, args);
     }
 }
 
 static JS_REQUIRES_STACK inline bool
 IsTraceableRecursion(JSContext *cx)
 {
     JSStackFrame *fp = cx->fp;
     JSStackFrame *down = cx->fp->down;
     if (!down)
         return false;
     if (down->maybeScript() != fp->maybeScript())
         return false;
-    if (down->argc != fp->argc)
+    if (down->numActualArgs() != fp->numActualArgs())
         return false;
-    if (fp->argc != fp->getArgumentCount())
+    if (fp->numActualArgs() != fp->numFormalArgs())
         return false;
     if (fp->hasIMacroPC() || down->hasIMacroPC())
         return false;
     if ((fp->flags & JSFRAME_CONSTRUCTING) || (down->flags & JSFRAME_CONSTRUCTING))
         return false;
     if (fp->hasBlockChain() || down->hasBlockChain())
         return false;
     if (*fp->getScript()->code != JSOP_TRACE)
@@ -10388,18 +10392,18 @@ TraceRecorder::record_EnterFrame(uintN& 
     //  [fp1]*****               pop
     //  [fp1]*****[fp2]          call
     //  [fp1]*****[fp2]***       push
     //
     // Duplicate native stack layout computation: see VisitFrameSlots header comment.
     // This doesn't do layout arithmetic, but it must initialize in the tracker all the
     // slots defined as imported by VisitFrameSlots.
 
-    Value* vp = &fp->argv[fp->argc];
-    Value* vpstop = vp + ptrdiff_t(fp->getArgumentCount()) - ptrdiff_t(fp->argc);
+    Value* vp = &fp->argv[fp->numActualArgs()];
+    Value* vpstop = vp + ptrdiff_t(fp->numFormalArgs()) - ptrdiff_t(fp->numActualArgs());
     for (; vp < vpstop; ++vp) {
         nativeFrameTracker.set(vp, NULL);
         set(vp, void_ins);
     }
 
     nativeFrameTracker.set(fp->addressArgsObj(), NULL);
     setFrameObjPtr(fp->addressArgsObj(), INS_NULL());
     nativeFrameTracker.set(fp->addressScopeChain(), NULL);
@@ -10458,17 +10462,17 @@ TraceRecorder::record_EnterFrame(uintN& 
     /* Try inlining one level in case this recursion doesn't go too deep. */
     if (fp->getScript() == fp->down->getScript() &&
         fp->down->down && fp->down->down->getScript() == fp->getScript()) {
         RETURN_STOP_A("recursion started inlining");
     }
 
 #if 0
     TreeFragment* first = LookupLoop(&JS_TRACE_MONITOR(cx), cx->regs->pc, tree->globalObj,
-                                     tree->globalShape, fp->argc);
+                                     tree->globalShape, fp->numActualArgs());
     if (!first)
         return ARECORD_CONTINUE;
     TreeFragment* f = findNestedCompatiblePeer(first);
     if (!f) {
         /*
          * If there were no compatible peers, but there were peers at all, then it is probable that
          * an inner recursive function is type mismatching. Start a new recorder that must be
          * recursive.
@@ -10478,17 +10482,17 @@ TraceRecorder::record_EnterFrame(uintN& 
                 /* Since this recorder is about to die, save its values. */
                 if (++first->hits() <= HOTLOOP)
                     return ARECORD_STOP;
                 if (IsBlacklisted((jsbytecode*)f->ip))
                     RETURN_STOP_A("inner recursive tree is blacklisted");
                 JSContext* _cx = cx;
                 SlotList* globalSlots = tree->globalSlots;
                 AbortRecording(cx, "trying to compile inner recursive tree");
-                JS_ASSERT(_cx->fp->argc == first->argc);
+                JS_ASSERT(_cx->fp->numActualArgs() == first->argc);
                 RecordTree(_cx, first, NULL, 0, globalSlots, Record_EnterFrame);
                 break;
             }
         }
         return ARECORD_CONTINUE;
     } else if (f) {
         /*
          * Make sure the shape of the global object still matches (this might
@@ -10651,25 +10655,25 @@ TraceRecorder::record_JSOP_IFNE()
 {
     return ifop();
 }
 
 LIns*
 TraceRecorder::newArguments(LIns* callee_ins, bool strict)
 {
     LIns* global_ins = INS_CONSTOBJ(globalObj);
-    LIns* argc_ins = INS_CONST(cx->fp->argc);
+    LIns* argc_ins = INS_CONST(cx->fp->numActualArgs());
 
     LIns* args[] = { callee_ins, argc_ins, global_ins, cx_ins };
     LIns* call_ins = lir->insCall(&js_Arguments_ci, args);
     guard(false, lir->insEqP_0(call_ins), OOM_EXIT);
 
     if (strict) {
         JSStackFrame* fp = cx->fp;
-        uintN argc = fp->argc;
+        uintN argc = fp->numActualArgs();
         LIns* argsSlots_ins = NULL;
         for (uintN i = 0; i < argc; i++)
             stobj_set_dslot(call_ins, i, argsSlots_ins, fp->argv[i], get(&fp->argv[i]));
     }
 
     return call_ins;
 }
 
@@ -12684,34 +12688,34 @@ TraceRecorder::record_JSOP_GETELEM()
 
     if (obj->isArguments()) {
         unsigned depth;
         JSStackFrame *afp = guardArguments(obj, obj_ins, &depth);
         if (afp) {
             uintN int_idx = idx.toInt32();
             Value* vp = &afp->argv[int_idx];
             if (idx_ins->isImmD()) {
-                if (int_idx < 0 || int_idx >= afp->argc)
+                if (int_idx < 0 || int_idx >= afp->numActualArgs())
                     RETURN_STOP_A("cannot trace arguments with out of range index");
                 v_ins = get(vp);
             } else {
                 // If the index is not a constant expression, we generate LIR to load the value from
                 // the native stack area. The guard on js_ArgumentClass above ensures the up-to-date
                 // value has been written back to the native stack area.
                 idx_ins = makeNumberInt32(idx_ins);
-                if (int_idx < 0 || int_idx >= afp->argc)
+                if (int_idx < 0 || int_idx >= afp->numActualArgs())
                     RETURN_STOP_A("cannot trace arguments with out of range index");
 
                 VMSideExit *exit = snapshot(MISMATCH_EXIT);
                  guard(true,
                       addName(lir->ins2(LIR_gei, idx_ins, INS_CONST(0)),
                               "guard(upvar index >= 0)"),
                        exit);
                 guard(true,
-                      addName(lir->ins2(LIR_lti, idx_ins, INS_CONST(afp->argc)),
+                      addName(lir->ins2(LIR_lti, idx_ins, INS_CONST(afp->numActualArgs())),
                               "guard(upvar index in range)"),
                       exit);
 
                 JSValueType type = getCoercedType(*vp);
 
                 // Guard that the argument has the same type on trace as during recording.
                 LIns* typemap_ins;
                 if (depth == 0) {
@@ -12741,17 +12745,17 @@ TraceRecorder::record_JSOP_GETELEM()
                                                                    INS_CONST(sizeof(JSValueType)))));
                 LIns* type_ins = lir->insLoad(LIR_lduc2ui, typep_ins, 0, ACCSET_OTHER, LOAD_CONST);
                 guard(true,
                       addName(lir->ins2(LIR_eqi, type_ins, lir->insImmI(type)),
                               "guard(type-stable upvar)"),
                       BRANCH_EXIT);
 
                 // Read the value out of the native stack area.
-                guard(true, lir->ins2(LIR_ltui, idx_ins, INS_CONST(afp->argc)),
+                guard(true, lir->ins2(LIR_ltui, idx_ins, INS_CONST(afp->numActualArgs())),
                       snapshot(BRANCH_EXIT));
                 size_t stackOffset = nativespOffset(&afp->argv[0]);
                 LIns* args_addr_ins = lir->ins2(LIR_addp, lirbuf->sp, INS_CONSTWORD(stackOffset));
                 LIns* argi_addr_ins = lir->ins2(LIR_addp,
                                                 args_addr_ins,
                                                 lir->insUI2P(lir->ins2(LIR_muli,
                                                                        idx_ins,
                                                                        INS_CONST(sizeof(double)))));
@@ -13173,25 +13177,25 @@ TraceRecorder::upvar(JSScript* script, J
     uint32 level = script->staticLevel - cookie.level();
     uint32 cookieSlot = cookie.slot();
     JSStackFrame* fp = cx->findFrameAtLevel(level);
     const CallInfo* ci;
     int32 slot;
     if (!fp->hasFunction() || (fp->flags & JSFRAME_EVAL)) {
         ci = &GetUpvarStackOnTrace_ci;
         slot = cookieSlot;
-    } else if (cookieSlot < fp->getArgumentCount()) {
+    } else if (cookieSlot < fp->numFormalArgs()) {
         ci = &GetUpvarArgOnTrace_ci;
         slot = cookieSlot;
     } else if (cookieSlot == UpvarCookie::CALLEE_SLOT) {
         ci = &GetUpvarArgOnTrace_ci;
         slot = -2;
     } else {
         ci = &GetUpvarVarOnTrace_ci;
-        slot = cookieSlot - fp->getArgumentCount();
+        slot = cookieSlot - fp->numFormalArgs();
     }
 
     LIns* outp = lir->insAlloc(sizeof(double));
     LIns* args[] = {
         outp,
         INS_CONST(callDepth),
         INS_CONST(slot),
         INS_CONST(level),
@@ -13411,17 +13415,17 @@ TraceRecorder::interpretedFunctionCall(V
     fi->block = fp->maybeBlockChain();
     if (fp->hasBlockChain())
         tree->gcthings.addUnique(ObjectValue(*fp->getBlockChain()));
     fi->pc = cx->regs->pc;
     fi->imacpc = fp->maybeIMacroPC();
     fi->spdist = cx->regs->sp - fp->slots();
     fi->set_argc(uint16(argc), constructing);
     fi->callerHeight = stackSlots - (2 + argc);
-    fi->callerArgc = fp->argc;
+    fi->callerArgc = fp->numActualArgs();
 
     if (callDepth >= tree->maxCallDepth)
         tree->maxCallDepth = callDepth + 1;
 
     fi = traceMonitor->frameCache->memoize(fi);
     if (!fi)
         RETURN_STOP("out of memory");
     lir->insStore(INS_CONSTPTR(fi), lirbuf->rp, callDepth * sizeof(FrameInfo*), ACCSET_RSTACK);
@@ -13534,17 +13538,17 @@ TraceRecorder::record_JSOP_APPLY()
                                 stobj_get_fslot_uint32(aobj_ins, JSObject::JSSLOT_ARRAY_LENGTH),
                                 length),
                   BRANCH_EXIT);
         } else if (aobj->isArguments()) {
             unsigned depth;
             JSStackFrame *afp = guardArguments(aobj, aobj_ins, &depth);
             if (!afp)
                 RETURN_STOP_A("can't reach arguments object's frame");
-            length = afp->argc;
+            length = afp->numActualArgs();
         } else {
             RETURN_STOP_A("arguments parameter of apply is not a dense array or argments object");
         }
 
         if (length >= JS_ARRAY_LENGTH(apply_imacro_table))
             RETURN_STOP_A("too many arguments to apply");
 
         return InjectStatus(callImacro(apply_imacro_table[length]));
@@ -15261,17 +15265,17 @@ TraceRecorder::record_JSOP_NOP()
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_JSOP_ARGSUB()
 {
     JSStackFrame* const fp = cx->fp;
     if (!(fp->getFunction()->flags & JSFUN_HEAVYWEIGHT)) {
         uintN slot = GET_ARGNO(cx->regs->pc);
-        if (slot >= fp->argc)
+        if (slot >= fp->numActualArgs())
             RETURN_STOP_A("can't trace out-of-range arguments");
         stack(0, get(&cx->fp->argv[slot]));
         return ARECORD_CONTINUE;
     }
     RETURN_STOP_A("can't trace JSOP_ARGSUB hard case");
 }
 
 JS_REQUIRES_STACK LIns*
@@ -15301,17 +15305,17 @@ TraceRecorder::record_JSOP_ARGCNT()
         RETURN_STOP_A("can't trace JSOP_ARGCNT if arguments.length has been modified");
     LIns *a_ins = getFrameObjPtr(cx->fp->addressArgsObj());
     if (callDepth == 0) {
         LIns *br = lir->insBranch(LIR_jt, lir->insEqP_0(a_ins), NULL);
         guardArgsLengthNotAssigned(a_ins);
         LIns *label = lir->ins0(LIR_label);
         br->setTarget(label);
     }
-    stack(0, lir->insImmD(cx->fp->argc));
+    stack(0, lir->insImmD(cx->fp->numActualArgs()));
     return ARECORD_CONTINUE;
 }
 
 JS_REQUIRES_STACK AbortableRecordingStatus
 TraceRecorder::record_DefLocalFunSetSlot(uint32 slot, JSObject* obj)
 {
     JSFunction* fun = GET_FUNCTION_PRIVATE(cx, obj);