Bug 605192 - JM: make f.apply(x, obj) fast, part 2 (r=dvander)
authorLuke Wagner <lw@mozilla.com>
Wed, 20 Oct 2010 23:52:55 -0700
changeset 57715 fd21a9d4344aa3d9f188bbb7190133172b26e487
parent 57714 e77069ddab0064b2e3af06e0d37b90492f1b7d79
child 57716 8715628a75f886d927cfacf8a83b20692a92650a
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersdvander
bugs605192
milestone2.0b8pre
Bug 605192 - JM: make f.apply(x, obj) fast, part 2 (r=dvander)
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/methodjit/InvokeHelpers.cpp
--- a/js/src/jsinterp.h
+++ b/js/src/jsinterp.h
@@ -192,18 +192,18 @@ struct JSStackFrame
     /* Used for Invoke, Interpret, trace-jit LeaveTree, and method-jit stubs. */
     inline void initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun,
                               uint32 nactual, uint32 flags);
 
     /* Used for SessionInvoke. */
     inline void resetInvokeCallFrame();
 
     /* Called by method-jit stubs and serve as a specification for jit-code. */
-    inline void initCallFrameCallerHalf(JSContext *cx, uint32 nactual, uint32 flags);
-    inline void initCallFrameEarlyPrologue(JSFunction *fun, void *ncode);
+    inline void initCallFrameCallerHalf(JSContext *cx, uint32 flags, void *ncode);
+    inline void initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual);
     inline void initCallFrameLatePrologue();
 
     /* Used for eval. */
     inline void initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev,
                               uint32 flags);
     inline void initGlobalFrame(JSScript *script, JSObject &chain, uint32 flags);
 
     /* Used when activating generators. */
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -126,44 +126,39 @@ JSStackFrame::resetInvokeCallFrame()
     JS_ASSERT(exec.fun == calleeValue().toObject().getFunctionPrivate());
     JS_ASSERT(!hasImacropc());
     JS_ASSERT(!hasHookData());
     JS_ASSERT(annotation() == NULL);
     JS_ASSERT(!hasCallObj());
 }
 
 inline void
-JSStackFrame::initCallFrameCallerHalf(JSContext *cx, uint32 nactual, uint32 flagsArg)
+JSStackFrame::initCallFrameCallerHalf(JSContext *cx, uint32 flagsArg,
+                                      void *ncode)
 {
     JS_ASSERT((flagsArg & ~(JSFRAME_CONSTRUCTING |
                             JSFRAME_FUNCTION |
                             JSFRAME_OVERFLOW_ARGS |
                             JSFRAME_UNDERFLOW_ARGS)) == 0);
-    JSFrameRegs *regs = cx->regs;
 
-    /* Initialize the caller half of the stack frame members. */
     flags_ = JSFRAME_FUNCTION | flagsArg;
-    args.nactual = nactual;  /* only need to write if over/under-flow */
-    prev_ = regs->fp;
-    JS_ASSERT(!hasImacropc());
-    JS_ASSERT(!hasHookData());
-    JS_ASSERT(annotation() == NULL);
-
-    JS_ASSERT(!hasCallObj());
+    prev_ = cx->regs->fp;
+    ncode_ = ncode;
 }
 
 /*
  * The "early prologue" refers to the members that are stored for the benefit
  * of slow paths before initializing the rest of the members.
  */
 inline void
-JSStackFrame::initCallFrameEarlyPrologue(JSFunction *fun, void *ncode)
+JSStackFrame::initCallFrameEarlyPrologue(JSFunction *fun, uint32 nactual)
 {
     exec.fun = fun;
-    ncode_ = ncode;
+    if (flags_ & (JSFRAME_OVERFLOW_ARGS | JSFRAME_UNDERFLOW_ARGS))
+        args.nactual = nactual;
 }
 
 /*
  * The "late prologue" refers to the members that are stored after having
  * checked for stack overflow and formal/actual arg mismatch.
  */
 inline void
 JSStackFrame::initCallFrameLatePrologue()
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -269,20 +269,20 @@ stubs::FixupArity(VMFrame &f, uint32 nac
     /* Reserve enough space for a callee frame. */
     JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, (Value*) oldfp, nactual,
                                                                 fun, fun->script(), &flags,
                                                                 f.entryFp, &f.stackLimit);
     if (!newfp)
         THROWV(NULL);
 
     /* Reset the part of the stack frame set by the caller. */
-    newfp->initCallFrameCallerHalf(cx, nactual, flags);
+    newfp->initCallFrameCallerHalf(cx, flags, ncode);
 
     /* Reset the part of the stack frame set by the prologue up to now. */
-    newfp->initCallFrameEarlyPrologue(fun, ncode);
+    newfp->initCallFrameEarlyPrologue(fun, nactual);
 
     /* The caller takes care of assigning fp to regs. */
     return newfp;
 }
 
 void * JS_FASTCALL
 stubs::CompileFunction(VMFrame &f, uint32 nactual)
 {
@@ -301,17 +301,17 @@ stubs::CompileFunction(VMFrame &f, uint3
     JSFunction *fun = callee.getFunctionPrivate();
     JSScript *script = fun->script();
 
     /*
      * FixupArity/RemovePartialFrame expect to be called after the early
      * prologue. Pass the existing value for ncode, it has already been set
      * by the jit code calling into this stub.
      */
-    fp->initCallFrameEarlyPrologue(fun, fp->nativeReturnAddress());
+    fp->initCallFrameEarlyPrologue(fun, nactual);
 
     /* Empty script does nothing. */
     bool callingNew = fp->isConstructing();
     if (script->isEmpty()) {
         RemovePartialFrame(cx, fp);
         Value *vp = f.regs.sp - (nactual + 2);
         if (callingNew)
             vp[0] = vp[1];