mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1227263 part 3 - Remove this-slot from non-function frames. r=efaust
This commit is contained in:
parent
78e54d2bfb
commit
980c73e927
@ -436,7 +436,7 @@ class BaselineFrame
|
||||
return FramePointerOffset + js::jit::JitFrameLayout::offsetOfThis();
|
||||
}
|
||||
static size_t offsetOfEvalNewTarget() {
|
||||
return offsetOfArg(0);
|
||||
return FramePointerOffset + js::jit::JitFrameLayout::offsetOfEvalNewTarget();
|
||||
}
|
||||
static size_t offsetOfArg(size_t index) {
|
||||
return FramePointerOffset + js::jit::JitFrameLayout::offsetOfActualArg(index);
|
||||
|
@ -2743,8 +2743,8 @@ jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoVal
|
||||
} else {
|
||||
data.constructing = false;
|
||||
data.numActualArgs = 0;
|
||||
data.maxArgc = 1;
|
||||
data.maxArgv = state.asExecute()->addressOfThisv();
|
||||
data.maxArgc = 0;
|
||||
data.maxArgv = nullptr;
|
||||
data.scopeChain = state.asExecute()->scopeChain();
|
||||
|
||||
data.calleeToken = CalleeToToken(state.script());
|
||||
@ -2756,13 +2756,12 @@ jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoVal
|
||||
if (iter.isFunctionFrame())
|
||||
data.calleeToken = CalleeToToken(iter.callee(cx), /* constructing = */ false);
|
||||
|
||||
// Push newTarget onto the stack, as well as Argv.
|
||||
if (!vals.reserve(2))
|
||||
// Push newTarget onto the stack.
|
||||
if (!vals.reserve(1))
|
||||
return false;
|
||||
|
||||
data.maxArgc = 2;
|
||||
data.maxArgc = 1;
|
||||
data.maxArgv = vals.begin();
|
||||
vals.infallibleAppend(state.asExecute()->thisv());
|
||||
if (iter.isFunctionFrame()) {
|
||||
if (state.asExecute()->newTarget().isNull())
|
||||
vals.infallibleAppend(iter.newTarget());
|
||||
|
@ -1055,19 +1055,21 @@ MarkThisAndArguments(JSTracer* trc, const JitFrameIterator& frame)
|
||||
? frame.exitFrame()->as<LazyLinkExitFrameLayout>()->jsFrame()
|
||||
: frame.jsFrame();
|
||||
|
||||
if (!CalleeTokenIsFunction(layout->calleeToken()))
|
||||
return;
|
||||
|
||||
size_t nargs = layout->numActualArgs();
|
||||
size_t nformals = 0;
|
||||
size_t newTargetOffset = 0;
|
||||
if (CalleeTokenIsFunction(layout->calleeToken())) {
|
||||
JSFunction* fun = CalleeTokenToFunction(layout->calleeToken());
|
||||
if (!frame.isExitFrameLayout<LazyLinkExitFrameLayout>() &&
|
||||
!fun->nonLazyScript()->argumentsHasVarBinding())
|
||||
{
|
||||
nformals = fun->nargs();
|
||||
}
|
||||
newTargetOffset = Max(nargs, fun->nargs());
|
||||
|
||||
JSFunction* fun = CalleeTokenToFunction(layout->calleeToken());
|
||||
if (!frame.isExitFrameLayout<LazyLinkExitFrameLayout>() &&
|
||||
!fun->nonLazyScript()->argumentsHasVarBinding())
|
||||
{
|
||||
nformals = fun->nargs();
|
||||
}
|
||||
|
||||
size_t newTargetOffset = Max(nargs, fun->nargs());
|
||||
|
||||
Value* argv = layout->argv();
|
||||
|
||||
// Trace |this|.
|
||||
|
@ -387,6 +387,9 @@ class JitFrameLayout : public CommonFrameLayout
|
||||
static size_t offsetOfThis() {
|
||||
return sizeof(JitFrameLayout);
|
||||
}
|
||||
static size_t offsetOfEvalNewTarget() {
|
||||
return sizeof(JitFrameLayout);
|
||||
}
|
||||
static size_t offsetOfActualArgs() {
|
||||
return offsetOfThis() + sizeof(Value);
|
||||
}
|
||||
@ -395,9 +398,11 @@ class JitFrameLayout : public CommonFrameLayout
|
||||
}
|
||||
|
||||
Value thisv() {
|
||||
MOZ_ASSERT(CalleeTokenIsFunction(calleeToken()));
|
||||
return argv()[0];
|
||||
}
|
||||
Value* argv() {
|
||||
MOZ_ASSERT(CalleeTokenIsFunction(calleeToken()));
|
||||
return (Value*)(this + 1);
|
||||
}
|
||||
uintptr_t numActualArgs() const {
|
||||
|
@ -341,7 +341,7 @@ InvokeState::pushInterpreterFrame(JSContext* cx)
|
||||
InterpreterFrame*
|
||||
ExecuteState::pushInterpreterFrame(JSContext* cx)
|
||||
{
|
||||
return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, thisv_, newTargetValue_,
|
||||
return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, newTargetValue_,
|
||||
scopeChain_, type_, evalInFrame_);
|
||||
}
|
||||
// MSVC with PGO inlines a lot of functions in RunScript, resulting in large
|
||||
@ -645,12 +645,8 @@ js::ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChainArg,
|
||||
return true;
|
||||
}
|
||||
|
||||
// It doesn't matter what we pass as thisv, global/eval scripts get |this|
|
||||
// from the scope chain. TODO: remove thisv from ExecuteState.
|
||||
RootedValue thisv(cx);
|
||||
|
||||
probes::StartExecution(script);
|
||||
ExecuteState state(cx, script, thisv, newTargetValue, scopeChainArg, type, evalInFrame, result);
|
||||
ExecuteState state(cx, script, newTargetValue, scopeChainArg, type, evalInFrame, result);
|
||||
bool ok = RunScript(cx, state);
|
||||
probes::StopExecution(script);
|
||||
|
||||
|
@ -171,7 +171,6 @@ class ExecuteState : public RunState
|
||||
{
|
||||
ExecuteType type_;
|
||||
|
||||
RootedValue thisv_;
|
||||
RootedValue newTargetValue_;
|
||||
RootedObject scopeChain_;
|
||||
|
||||
@ -179,20 +178,17 @@ class ExecuteState : public RunState
|
||||
Value* result_;
|
||||
|
||||
public:
|
||||
ExecuteState(JSContext* cx, JSScript* script, const Value& thisv, const Value& newTargetValue,
|
||||
ExecuteState(JSContext* cx, JSScript* script, const Value& newTargetValue,
|
||||
JSObject& scopeChain, ExecuteType type, AbstractFramePtr evalInFrame,
|
||||
Value* result)
|
||||
: RunState(cx, Execute, script),
|
||||
type_(type),
|
||||
thisv_(cx, thisv),
|
||||
newTargetValue_(cx, newTargetValue),
|
||||
scopeChain_(cx, &scopeChain),
|
||||
evalInFrame_(evalInFrame),
|
||||
result_(result)
|
||||
{ }
|
||||
|
||||
Value* addressOfThisv() { return thisv_.address(); }
|
||||
Value thisv() { return thisv_; }
|
||||
Value newTarget() { return newTargetValue_; }
|
||||
JSObject* scopeChain() const { return scopeChain_; }
|
||||
ExecuteType type() const { return type_; }
|
||||
|
@ -34,11 +34,9 @@ using mozilla::PodCopy;
|
||||
|
||||
void
|
||||
InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr evalInFramePrev,
|
||||
const Value& thisv, const Value& newTargetValue, HandleObject scopeChain,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type)
|
||||
{
|
||||
MOZ_ASSERT_IF(type & MODULE, thisv.isUndefined());
|
||||
|
||||
/*
|
||||
* See encoding of ExecuteType. When GLOBAL isn't set, we are executing a
|
||||
* script in the context of another frame and the frame type is determined
|
||||
@ -77,8 +75,7 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
|
||||
}
|
||||
}
|
||||
|
||||
Value* dstvp = (Value*)this - 3;
|
||||
dstvp[2] = thisv;
|
||||
Value* dstvp = (Value*)this - 2;
|
||||
|
||||
if (isFunctionFrame()) {
|
||||
dstvp[1] = ObjectValue(*callee);
|
||||
@ -454,8 +451,8 @@ InterpreterFrame::markValues(JSTracer* trc, Value* sp, jsbytecode* pc)
|
||||
unsigned argc = Max(numActualArgs(), numFormalArgs());
|
||||
TraceRootRange(trc, argc + 2 + isConstructing(), argv_ - 2, "fp argv");
|
||||
} else {
|
||||
// Mark callee, |this|, and newTarget
|
||||
TraceRootRange(trc, 3, ((Value*)this) - 3, "stack callee, this, newTarget");
|
||||
// Mark callee and newTarget
|
||||
TraceRootRange(trc, 2, ((Value*)this) - 2, "stack callee and newTarget");
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,20 +509,20 @@ InterpreterStack::pushInvokeFrame(JSContext* cx, const CallArgs& args, InitialFr
|
||||
}
|
||||
|
||||
InterpreterFrame*
|
||||
InterpreterStack::pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame)
|
||||
InterpreterStack::pushExecuteFrame(JSContext* cx, HandleScript script, const Value& newTargetValue,
|
||||
HandleObject scopeChain, ExecuteType type,
|
||||
AbstractFramePtr evalInFrame)
|
||||
{
|
||||
LifoAlloc::Mark mark = allocator_.mark();
|
||||
|
||||
unsigned nvars = 3 /* callee, this, newTarget */ + script->nslots();
|
||||
unsigned nvars = 2 /* callee, newTarget */ + script->nslots();
|
||||
uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvars * sizeof(Value));
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
|
||||
InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 3 * sizeof(Value));
|
||||
InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 2 * sizeof(Value));
|
||||
fp->mark_ = mark;
|
||||
fp->initExecuteFrame(cx, script, evalInFrame, thisv, newTargetValue, scopeChain, type);
|
||||
fp->initExecuteFrame(cx, script, evalInFrame, newTargetValue, scopeChain, type);
|
||||
fp->initLocals();
|
||||
|
||||
return fp;
|
||||
|
@ -427,8 +427,7 @@ class InterpreterFrame
|
||||
|
||||
/* Used for global and eval frames. */
|
||||
void initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr prev,
|
||||
const Value& thisv, const Value& newTargetValue,
|
||||
HandleObject scopeChain, ExecuteType type);
|
||||
const Value& newTargetValue, HandleObject scopeChain, ExecuteType type);
|
||||
|
||||
public:
|
||||
/*
|
||||
@ -742,7 +741,7 @@ class InterpreterFrame
|
||||
|
||||
const Value& maybeCalleev() const {
|
||||
Value& calleev = flags_ & (EVAL | GLOBAL)
|
||||
? ((Value*)this)[-2]
|
||||
? ((Value*)this)[-1]
|
||||
: argv()[-2];
|
||||
MOZ_ASSERT(calleev.isObjectOrNull());
|
||||
return calleev;
|
||||
@ -751,14 +750,10 @@ class InterpreterFrame
|
||||
Value& mutableCalleev() const {
|
||||
MOZ_ASSERT(isFunctionFrame());
|
||||
if (isEvalFrame())
|
||||
return ((Value*)this)[-2];
|
||||
return ((Value*)this)[-1];
|
||||
return argv()[-2];
|
||||
}
|
||||
|
||||
CallReceiver callReceiver() const {
|
||||
return CallReceiverFromArgv(argv());
|
||||
}
|
||||
|
||||
/*
|
||||
* New Target
|
||||
*
|
||||
@ -769,7 +764,7 @@ class InterpreterFrame
|
||||
Value newTarget() const {
|
||||
MOZ_ASSERT(isFunctionFrame());
|
||||
if (isEvalFrame())
|
||||
return ((Value*)this)[-3];
|
||||
return ((Value*)this)[-2];
|
||||
|
||||
if (callee().isArrow())
|
||||
return callee().getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
|
||||
@ -1055,9 +1050,9 @@ class InterpreterStack
|
||||
}
|
||||
|
||||
// For execution of eval or global code.
|
||||
InterpreterFrame* pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame);
|
||||
InterpreterFrame* pushExecuteFrame(JSContext* cx, HandleScript script,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame);
|
||||
|
||||
// Called to invoke a function.
|
||||
InterpreterFrame* pushInvokeFrame(JSContext* cx, const CallArgs& args,
|
||||
|
Loading…
Reference in New Issue
Block a user