Fix incoherent PC in FixupArity failure case (bug 629650, r=luke).

This commit is contained in:
David Anderson 2011-02-01 12:04:07 -08:00
parent 241bdcf435
commit 5f1c3a6e4f
4 changed files with 38 additions and 24 deletions

View File

@ -133,29 +133,8 @@ JSStackFrame::pc(JSContext *cx, JSStackFrame *next)
return next->prevpc_;
#if defined(JS_METHODJIT) && defined(JS_MONOIC)
JSScript *script = this->script();
js::mjit::JITScript *jit = script->getJIT(isConstructing());
size_t low = 0;
size_t high = jit->nCallICs;
while (high > low + 1) {
/* Could overflow here on a script with 2 billion calls. Oh well. */
size_t mid = (high + low) / 2;
void *entry = jit->callICs[mid].funGuard.executableAddress();
/*
* Use >= here as the return address of the call is likely to be
* the start address of the next (possibly IC'ed) operation.
*/
if (entry >= next->ncode_)
high = mid;
else
low = mid;
}
js::mjit::ic::CallICInfo &callIC = jit->callICs[low];
JS_ASSERT((uint8*)callIC.funGuard.executableAddress() + callIC.joinPointOffset == next->ncode_);
return callIC.pc;
js::mjit::JITScript *jit = script()->getJIT(isConstructing());
return jit->nativeToPC(next->ncode_);
#else
JS_NOT_REACHED("Unknown PC for frame");
return NULL;

View File

@ -272,8 +272,14 @@ stubs::FixupArity(VMFrame &f, uint32 nactual)
JSStackFrame *newfp = cx->stack().getInlineFrameWithinLimit(cx, (Value*) oldfp, nactual,
fun, fun->script(), &flags,
f.entryfp, &f.stackLimit);
if (!newfp)
if (!newfp) {
/*
* The PC is not coherent with the current frame, so fix it up for
* exception handling.
*/
f.regs.pc = f.jit()->nativeToPC(ncode);
THROWV(NULL);
}
/* Reset the part of the stack frame set by the caller. */
newfp->initCallFrameCallerHalf(cx, flags, ncode);

View File

@ -948,3 +948,30 @@ mjit::GetCallTargetCount(JSScript *script, jsbytecode *pc)
return 1;
}
#endif
jsbytecode *
JITScript::nativeToPC(void *returnAddress) const
{
size_t low = 0;
size_t high = nCallICs;
while (high > low + 1) {
/* Could overflow here on a script with 2 billion calls. Oh well. */
size_t mid = (high + low) / 2;
void *entry = callICs[mid].funGuard.executableAddress();
/*
* Use >= here as the return address of the call is likely to be
* the start address of the next (possibly IC'ed) operation.
*/
if (entry >= returnAddress)
high = mid;
else
low = mid;
}
js::mjit::ic::CallICInfo &ic = callICs[low];
JS_ASSERT((uint8*)ic.funGuard.executableAddress() + ic.joinPointOffset == returnAddress);
return ic.pc;
}

View File

@ -361,6 +361,8 @@ struct JITScript {
size_t scriptDataSize();
size_t mainCodeSize() { return code.m_size; } /* doesn't account for fragmentation */
jsbytecode *nativeToPC(void *returnAddress) const;
};
/*