Resolve the merge conflict from bug 674998 correctly by removing InvokeSessionGuard completely, r=luke
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 07 Sep 2011 11:34:15 -0400
changeset 76645 787ebf02a8c170a63c0565c49c105062dc44becf
parent 76644 0c7303e897c565ac2ed2783adb3c338c33265841
child 76646 e095afa62bf5869861e8ea6b23a243d0d32259a5
child 76677 6a20f4ecc59eb5b72496895ca8fb6814b4a66bf2
push id21128
push usereakhgari@mozilla.com
push dateWed, 07 Sep 2011 15:34:26 +0000
treeherdermozilla-central@787ebf02a8c1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs674998
milestone9.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
Resolve the merge conflict from bug 674998 correctly by removing InvokeSessionGuard completely, r=luke
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -679,116 +679,16 @@ js::InvokeKernel(JSContext *cx, const Ca
     }
 
     args.rval() = fp->returnValue();
     JS_ASSERT_IF(ok && construct, !args.rval().isPrimitive());
     return ok;
 }
 
 bool
-InvokeSessionGuard::start(JSContext *cx, const Value &calleev, const Value &thisv, uintN argc)
-{
-#ifdef JS_TRACER
-    if (TRACE_RECORDER(cx))
-        AbortRecording(cx, "attempt to reenter VM while recording");
-    LeaveTrace(cx);
-#endif
-
-    /* Always push arguments, regardless of optimized/normal invoke. */
-    ContextStack &stack = cx->stack;
-    if (!stack.pushInvokeArgs(cx, argc, &args_))
-        return false;
-
-    /* Callees may clobber 'this' or 'callee'. */
-    savedCallee_ = args_.calleev() = calleev;
-    savedThis_ = args_.thisv() = thisv;
-
-    /* If anyone (through jsdbgapi) finds this frame, make it safe. */
-    MakeRangeGCSafe(args_.argv(), args_.argc());
-
-    do {
-        /* Hoist dynamic checks from scripted Invoke. */
-        if (!calleev.isObject())
-            break;
-        JSObject &callee = calleev.toObject();
-        if (callee.getClass() != &FunctionClass)
-            break;
-        JSFunction *fun = callee.getFunctionPrivate();
-        if (fun->isNative())
-            break;
-        script_ = fun->script();
-        if (!script_->ensureRanAnalysis(cx, fun, callee.getParent()))
-            return false;
-        if (FunctionNeedsPrologue(cx, fun) || script_->isEmpty())
-            break;
-
-        /*
-         * The frame will remain pushed even when the callee isn't active which
-         * will affect the observable current global, so avoid any change.
-         */
-        if (callee.getGlobal() != GetGlobalForScopeChain(cx))
-            break;
-
-        /* Push the stack frame once for the session. */
-        if (!stack.pushInvokeFrame(cx, args_, INITIAL_NONE, &ifg_))
-            return false;
-
-        /*
-         * Update the 'this' type of the callee according to the value given,
-         * along with the types of any missing arguments. These will be the
-         * same across all calls.
-         */
-        TypeScript::SetThis(cx, script_, thisv);
-        for (unsigned i = argc; i < fun->nargs; i++)
-            TypeScript::SetArgument(cx, script_, i, types::Type::UndefinedType());
-
-        StackFrame *fp = ifg_.fp();
-#ifdef JS_METHODJIT
-        /* Hoist dynamic checks from RunScript. */
-        mjit::CompileStatus status = mjit::CanMethodJIT(cx, script_, false,
-                                                        mjit::CompileRequest_JIT);
-        if (status == mjit::Compile_Error)
-            return false;
-        if (status != mjit::Compile_Okay)
-            break;
-        /* Cannot also cache the raw code pointer; it can change. */
-
-        /* Hoist dynamic checks from CheckStackAndEnterMethodJIT. */
-        JS_CHECK_RECURSION(cx, return false);
-        stackLimit_ = stack.space().getStackLimit(cx, REPORT_ERROR);
-        if (!stackLimit_)
-            return false;
-
-        stop_ = script_->code + script_->length - 1;
-        JS_ASSERT(*stop_ == JSOP_STOP);
-#endif
-
-        /* Cached to avoid canonicalActualArg in InvokeSessionGuard::operator[]. */
-        nformals_ = fp->numFormalArgs();
-        formals_ = fp->formalArgs();
-        actuals_ = args_.argv();
-        JS_ASSERT(actuals_ == fp->actualArgs());
-        return true;
-    } while (0);
-
-    /*
-     * Use the normal invoke path.
-     *
-     * The callee slot gets overwritten during an unoptimized Invoke, so we
-     * cache it here and restore it before every Invoke call. The 'this' value
-     * does not get overwritten, so we can fill it here once.
-     */
-    if (ifg_.pushed())
-        ifg_.pop();
-    formals_ = actuals_ = args_.argv();
-    nformals_ = (unsigned)-1;
-    return true;
-}
-
-bool
 js::Invoke(JSContext *cx, const Value &thisv, const Value &fval, uintN argc, Value *argv,
            Value *rval)
 {
     InvokeArgsGuard args;
     if (!cx->stack.pushInvokeArgs(cx, argc, &args))
         return false;
 
     args.calleev() = fval;
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -66,137 +66,16 @@ class AutoPreserveEnumerators {
     }
 
     ~AutoPreserveEnumerators()
     {
         cx->enumerators = enumerators;
     }
 };
 
-class InvokeSessionGuard
-{
-    InvokeArgsGuard args_;
-    InvokeFrameGuard ifg_;
-    Value savedCallee_, savedThis_;
-    Value *formals_, *actuals_;
-    unsigned nformals_;
-    JSScript *script_;
-    Value *stackLimit_;
-    jsbytecode *stop_;
-
-    bool optimized() const { return ifg_.pushed(); }
-
-  public:
-    InvokeSessionGuard() : args_(), ifg_() {}
-    ~InvokeSessionGuard() {}
-
-    bool start(JSContext *cx, const Value &callee, const Value &thisv, uintN argc);
-    bool invoke(JSContext *cx);
-
-    bool started() const {
-        return args_.pushed();
-    }
-
-    Value &operator[](unsigned i) const {
-        JS_ASSERT(i < argc());
-        Value &arg = i < nformals_ ? formals_[i] : actuals_[i];
-        JS_ASSERT_IF(optimized(), &arg == &ifg_.fp()->canonicalActualArg(i));
-        JS_ASSERT_IF(!optimized(), &arg == &args_[i]);
-        return arg;
-    }
-
-    uintN argc() const {
-        return args_.argc();
-    }
-
-    const Value &rval() const {
-        return optimized() ? ifg_.fp()->returnValue() : args_.rval();
-    }
-};
-
-inline bool
-InvokeSessionGuard::invoke(JSContext *cx)
-{
-    /* N.B. Must be kept in sync with Invoke */
-
-    /* Refer to canonical (callee, this) for optimized() sessions. */
-    formals_[-2] = savedCallee_;
-    formals_[-1] = savedThis_;
-
-    /* Prevent spurious accessing-callee-after-rval assert. */
-    args_.calleeHasBeenReset();
-
-    if (!optimized())
-        return Invoke(cx, args_);
-
-    /*
-     * Update the types of each argument. The 'this' type and missing argument
-     * types were handled when the invoke session was created.
-     */
-    for (unsigned i = 0; i < Min(argc(), nformals_); i++)
-        types::TypeScript::SetArgument(cx, script_, i, (*this)[i]);
-
-#ifdef JS_METHODJIT
-    mjit::JITScript *jit = script_->getJIT(false /* !constructing */);
-    if (!jit) {
-        /* Watch in case the code was thrown away due a recompile. */
-        mjit::CompileStatus status = mjit::TryCompile(cx, script_, false);
-        if (status == mjit::Compile_Error)
-            return false;
-        JS_ASSERT(status == mjit::Compile_Okay);
-        jit = script_->getJIT(false);
-    }
-    void *code;
-    if (!(code = jit->invokeEntry))
-        return Invoke(cx, args_);
-#endif
-
-    StackFrame *fp = ifg_.fp();
-
-    /*
-     * Clear any activation objects on the frame. Normally the frame should not
-     * have any, but since we leave it on the stack between calls to invoke()
-     * the debugger can start operating on it. See markFunctionEpilogueDone()
-     * calls below. :XXX: this is pretty gross, and slows us down. Can the
-     * debugger be prevented from observing this frame?
-     */
-    fp->functionEpilogue(/* activationOnly = */ true);
-    fp->markFunctionEpilogueDone(/* activationOnly = */ true);
-
-    fp->resetCallFrame(script_);
-
-    JSBool ok;
-    {
-        AutoPreserveEnumerators preserve(cx);
-        args_.setActive();  /* From js::Invoke(InvokeArgsGuard) overload. */
-        Probes::enterJSFun(cx, fp->fun(), script_);
-#ifdef JS_METHODJIT
-        ok = mjit::EnterMethodJIT(cx, fp, code, stackLimit_, /* partial = */ false);
-        cx->regs().pc = stop_;
-#else
-        cx->regs().pc = script_->code;
-        ok = Interpret(cx, cx->fp());
-
-        /* Interpret does not perform the entry frame's epilogue, unlike EnterMethodJIT. */
-        cx->fp()->functionEpilogue();
-#endif
-        Probes::exitJSFun(cx, fp->fun(), script_);
-        args_.setInactive();
-    }
-
-    /*
-     * Clear activation object flags, for the functionEpilogue() call in the
-     * next invoke().
-     */
-    fp->markFunctionEpilogueDone(/* activationOnly = */ true);
-
-    /* Don't clobber callee with rval; rval gets read from fp->rval. */
-    return ok;
-}
-
 namespace detail {
 
 template<typename T> class PrimitiveBehavior { };
 
 template<>
 class PrimitiveBehavior<JSString *> {
   public:
     static inline bool isType(const Value &v) { return v.isString(); }