mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 925308 - Dont pop profiler frames for stack frames pushed by invalidated IonScripts which didn not have profiler instrumentation. r=jandem
This commit is contained in:
parent
20c1ae1d0a
commit
d2984a88e7
18
js/src/jit-test/tests/baseline/bug925308.js
Normal file
18
js/src/jit-test/tests/baseline/bug925308.js
Normal file
@ -0,0 +1,18 @@
|
||||
// |jit-test| error: ReferenceError
|
||||
|
||||
var lfcode = new Array();
|
||||
lfcode.push("3");
|
||||
lfcode.push("enableSPSProfilingAssertions(false);foo();");
|
||||
while (true) {
|
||||
var file = lfcode.shift(); if (file == undefined) { break; }
|
||||
loadFile(file)
|
||||
}
|
||||
function loadFile(lfVarx) {
|
||||
if (lfVarx.substr(-3) != ".js" && lfVarx.length != 1) {
|
||||
switch (lfRunTypeId) {
|
||||
default: function newFunc(x) { new Function(x)(); }; newFunc(lfVarx); break;
|
||||
}
|
||||
} else if (!isNaN(lfVarx)) {
|
||||
lfRunTypeId = parseInt(lfVarx);
|
||||
}
|
||||
}
|
@ -549,30 +549,41 @@ HandleException(ResumeFromException *rfe)
|
||||
// Search each inlined frame for live iterator objects, and close
|
||||
// them.
|
||||
InlineFrameIterator frames(cx, &iter);
|
||||
|
||||
// Invalidation state will be the same for all inlined scripts in the frame.
|
||||
IonScript *ionScript = nullptr;
|
||||
bool invalidated = iter.checkInvalidation(&ionScript);
|
||||
|
||||
for (;;) {
|
||||
HandleExceptionIon(cx, frames, rfe, &overrecursed);
|
||||
|
||||
if (rfe->kind == ResumeFromException::RESUME_BAILOUT) {
|
||||
IonScript *ionScript = nullptr;
|
||||
if (iter.checkInvalidation(&ionScript))
|
||||
if (invalidated)
|
||||
ionScript->decref(cx->runtime()->defaultFreeOp());
|
||||
return;
|
||||
}
|
||||
|
||||
JS_ASSERT(rfe->kind == ResumeFromException::RESUME_ENTRY_FRAME);
|
||||
|
||||
// Figure out whether SPS frame was pushed for this frame or not.
|
||||
// Even if profiler is enabled, the frame being popped might have
|
||||
// been entered prior to SPS being enabled, and thus not have
|
||||
// a pushed SPS frame.
|
||||
bool popSPSFrame = cx->runtime()->spsProfiler.enabled();
|
||||
if (invalidated)
|
||||
popSPSFrame = ionScript->hasSPSInstrumentation();
|
||||
|
||||
// When profiling, each frame popped needs a notification that
|
||||
// the function has exited, so invoke the probe that a function
|
||||
// is exiting.
|
||||
JSScript *script = frames.script();
|
||||
probes::ExitScript(cx, script, script->function(), nullptr);
|
||||
probes::ExitScript(cx, script, script->function(), popSPSFrame);
|
||||
if (!frames.more())
|
||||
break;
|
||||
++frames;
|
||||
}
|
||||
|
||||
IonScript *ionScript = nullptr;
|
||||
if (iter.checkInvalidation(&ionScript))
|
||||
if (invalidated)
|
||||
ionScript->decref(cx->runtime()->defaultFreeOp());
|
||||
|
||||
} else if (iter.isBaselineJS()) {
|
||||
@ -585,7 +596,8 @@ HandleException(ResumeFromException *rfe)
|
||||
|
||||
// Unwind profiler pseudo-stack
|
||||
JSScript *script = iter.script();
|
||||
probes::ExitScript(cx, script, script->function(), iter.baselineFrame());
|
||||
probes::ExitScript(cx, script, script->function(),
|
||||
iter.baselineFrame()->hasPushedSPSFrame());
|
||||
// After this point, any pushed SPS frame would have been popped if it needed
|
||||
// to be. Unset the flag here so that if we call DebugEpilogue below,
|
||||
// it doesn't try to pop the SPS frame again.
|
||||
|
@ -1660,7 +1660,7 @@ CASE(JSOP_RETRVAL)
|
||||
if (!REGS.fp()->isYielding())
|
||||
REGS.fp()->epilogue(cx);
|
||||
else
|
||||
probes::ExitScript(cx, script, script->function(), REGS.fp());
|
||||
probes::ExitScript(cx, script, script->function(), REGS.fp()->hasPushedSPSFrame());
|
||||
|
||||
#if defined(JS_ION)
|
||||
jit_return_pop_frame:
|
||||
@ -3437,7 +3437,7 @@ DEFAULT()
|
||||
if (!REGS.fp()->isYielding())
|
||||
REGS.fp()->epilogue(cx);
|
||||
else
|
||||
probes::ExitScript(cx, script, script->function(), REGS.fp());
|
||||
probes::ExitScript(cx, script, script->function(), REGS.fp()->hasPushedSPSFrame());
|
||||
|
||||
gc::MaybeVerifyBarriers(cx, true);
|
||||
|
||||
|
@ -63,8 +63,7 @@ probes::EnterScript(JSContext *cx, JSScript *script, JSFunction *maybeFun,
|
||||
}
|
||||
|
||||
inline bool
|
||||
probes::ExitScript(JSContext *cx, JSScript *script, JSFunction *maybeFun,
|
||||
AbstractFramePtr fp)
|
||||
probes::ExitScript(JSContext *cx, JSScript *script, JSFunction *maybeFun, bool popSPSFrame)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
@ -76,22 +75,10 @@ probes::ExitScript(JSContext *cx, JSScript *script, JSFunction *maybeFun,
|
||||
cx->doFunctionCallback(maybeFun, script, 0);
|
||||
#endif
|
||||
|
||||
JSRuntime *rt = cx->runtime();
|
||||
/*
|
||||
* Coming from IonMonkey, the fp might not be known (fp == nullptr), but
|
||||
* IonMonkey will only call exitScript() when absolutely necessary, so it is
|
||||
* guaranteed that fp->hasPushedSPSFrame() would have been true
|
||||
*/
|
||||
if ((!fp && rt->spsProfiler.enabled()) || (fp && fp.hasPushedSPSFrame()))
|
||||
rt->spsProfiler.exit(cx, script, maybeFun);
|
||||
return ok;
|
||||
}
|
||||
if (popSPSFrame && cx->runtime()->spsProfiler.enabled())
|
||||
cx->runtime()->spsProfiler.exit(cx, script, maybeFun);
|
||||
|
||||
inline bool
|
||||
probes::ExitScript(JSContext *cx, JSScript *script, JSFunction *maybeFun,
|
||||
StackFrame *fp)
|
||||
{
|
||||
return probes::ExitScript(cx, script, maybeFun, fp ? AbstractFramePtr(fp) : AbstractFramePtr());
|
||||
return ok;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -69,8 +69,7 @@ bool WantNativeAddressInfo(JSContext *);
|
||||
bool EnterScript(JSContext *, JSScript *, JSFunction *, StackFrame *);
|
||||
|
||||
/* About to leave a JS function */
|
||||
bool ExitScript(JSContext *, JSScript *, JSFunction *, AbstractFramePtr);
|
||||
bool ExitScript(JSContext *, JSScript *, JSFunction *, StackFrame *);
|
||||
bool ExitScript(JSContext *, JSScript *, JSFunction *, bool popSPSFrame);
|
||||
|
||||
/* Executing a script */
|
||||
bool StartExecution(JSScript *script);
|
||||
|
@ -300,7 +300,7 @@ StackFrame::epilogue(JSContext *cx)
|
||||
JS_ASSERT(!hasBlockChain());
|
||||
|
||||
RootedScript script(cx, this->script());
|
||||
probes::ExitScript(cx, script, script->function(), this);
|
||||
probes::ExitScript(cx, script, script->function(), hasPushedSPSFrame());
|
||||
|
||||
if (isEvalFrame()) {
|
||||
if (isStrictEvalFrame()) {
|
||||
|
Loading…
Reference in New Issue
Block a user