Back out 710220a5ac33 (bug 714109) on suspicion of causing GC crashes in browser-chrome

This commit is contained in:
Phil Ringnalda 2012-02-09 20:40:59 -08:00
parent beb37ca78c
commit 71249eea70
4 changed files with 28 additions and 83 deletions

View File

@ -1371,11 +1371,16 @@ MarkGenerator(JSTracer *trc, JSGenerator *gen)
*/
JS_ASSERT(size_t(gen->regs.sp - fp->slots()) <= fp->numSlots());
MarkValueRange(trc, (HeapValue *)fp->formalArgsEnd() - gen->floatingStack,
gen->floatingStack, "Generator Floating Args");
/*
* Currently, generators are not mjitted. Still, (overflow) args can be
* pushed by the mjit and need to be conservatively marked. Technically, the
* formal args and generator slots are safe for exact marking, but since the
* plan is to eventually mjit generators, it makes sense to future-proof
* this code and save someone an hour later.
*/
MarkStackRangeConservatively(trc, gen->floatingStack, fp->formalArgsEnd());
js_TraceStackFrame(trc, fp);
MarkValueRange(trc, gen->regs.sp - fp->slots(),
(HeapValue *)fp->slots(), "Generator Floating Stack");
MarkStackRangeConservatively(trc, fp->slots(), gen->regs.sp);
}
static void
@ -1464,18 +1469,14 @@ js_NewGenerator(JSContext *cx)
(-1 + /* one Value included in JSGenerator */
vplen +
VALUES_PER_STACK_FRAME +
stackfp->numSlots()) * sizeof(HeapValue);
JS_ASSERT(nbytes % sizeof(Value) == 0);
JS_STATIC_ASSERT(sizeof(StackFrame) % sizeof(HeapValue) == 0);
stackfp->numSlots()) * sizeof(Value);
JSGenerator *gen = (JSGenerator *) cx->malloc_(nbytes);
if (!gen)
return NULL;
SetValueRangeToUndefined((Value *)gen, nbytes / sizeof(Value));
/* Cut up floatingStack space. */
HeapValue *genvp = gen->floatingStack;
Value *genvp = gen->floatingStack;
StackFrame *genfp = reinterpret_cast<StackFrame *>(genvp + vplen);
/* Initialize JSGenerator. */
@ -1486,8 +1487,7 @@ js_NewGenerator(JSContext *cx)
/* Copy from the stack to the generator's floating frame. */
gen->regs.rebaseFromTo(stackRegs, *genfp);
genfp->stealFrameAndSlots<HeapValue, Value, StackFrame::DoPostBarrier>(
genfp, genvp, stackfp, stackvp, stackRegs.sp);
genfp->stealFrameAndSlots(genvp, stackfp, stackvp, stackRegs.sp);
genfp->initFloatingGenerator();
obj->setPrivate(gen);

View File

@ -237,7 +237,7 @@ struct JSGenerator {
js::FrameRegs regs;
JSObject *enumerators;
js::StackFrame *floating;
js::HeapValue floatingStack[1];
js::Value floatingStack[1];
js::StackFrame *floatingFrame() {
return floating;

View File

@ -38,7 +38,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "jscntxt.h"
#include "jsgcmark.h"
#include "methodjit/MethodJIT.h"
#include "Stack.h"
@ -126,31 +125,21 @@ StackFrame::initDummyFrame(JSContext *cx, JSObject &chain)
setScopeChainNoCallObj(chain);
}
template <class T, class U, StackFrame::TriggerPostBarriers doPostBarrier>
void
StackFrame::stealFrameAndSlots(StackFrame *fp, T *vp, StackFrame *otherfp, U *othervp,
Value *othersp)
StackFrame::stealFrameAndSlots(Value *vp, StackFrame *otherfp,
Value *othervp, Value *othersp)
{
JS_ASSERT((U *)vp == (U *)this - ((U *)otherfp - othervp));
JS_ASSERT((Value *)othervp == otherfp->actualArgs() - 2);
JS_ASSERT(vp == (Value *)this - ((Value *)otherfp - othervp));
JS_ASSERT(othervp == otherfp->actualArgs() - 2);
JS_ASSERT(othersp >= otherfp->slots());
JS_ASSERT(othersp <= otherfp->base() + otherfp->numSlots());
JS_ASSERT((T *)fp - vp == (U *)otherfp - othervp);
/* Copy args, StackFrame, and slots. */
U *srcend = (U *)otherfp->formalArgsEnd();
T *dst = vp;
for (U *src = othervp; src < srcend; src++, dst++)
*dst = *src;
PodCopy(vp, othervp, othersp - othervp);
JS_ASSERT(vp == this->actualArgs() - 2);
*fp = *otherfp;
if (doPostBarrier)
fp->writeBarrierPost();
srcend = (U *)othersp;
dst = (T *)fp->slots();
for (U *src = (U *)otherfp->slots(); src < srcend; src++, dst++)
*dst = *src;
/* Catch bad-touching of non-canonical args (e.g., generator_trace). */
if (otherfp->hasOverflowArgs())
Debug_SetValueRangeToCrashOnTouch(othervp, othervp + 2 + otherfp->numFormalArgs());
/*
* Repoint Call, Arguments, Block and With objects to the new live frame.
@ -177,37 +166,6 @@ StackFrame::stealFrameAndSlots(StackFrame *fp, T *vp, StackFrame *otherfp, U *ot
}
}
/* Note: explicit instantiation for js_NewGenerator located in jsiter.cpp. */
template void StackFrame::stealFrameAndSlots<Value, HeapValue, StackFrame::NoPostBarrier>(
StackFrame *, Value *,
StackFrame *, HeapValue *, Value *);
template void StackFrame::stealFrameAndSlots<HeapValue, Value, StackFrame::DoPostBarrier>(
StackFrame *, HeapValue *,
StackFrame *, Value *, Value *);
void
StackFrame::writeBarrierPost()
{
/* This needs to follow the same rules as in js_TraceStackFrame. */
if (scopeChain_)
JSObject::writeBarrierPost(scopeChain_, (void *)&scopeChain_);
if (isDummyFrame())
return;
if (hasArgsObj())
JSObject::writeBarrierPost(argsObj_, (void *)&argsObj_);
if (isScriptFrame()) {
if (isFunctionFrame()) {
JSFunction::writeBarrierPost((JSObject *)exec.fun, (void *)&exec.fun);
if (isEvalFrame())
JSScript::writeBarrierPost(u.evalScript, (void *)&u.evalScript);
} else {
JSScript::writeBarrierPost(exec.script, (void *)&exec.script);
}
}
if (hasReturnValue())
HeapValue::writeBarrierPost(rval_, &rval_);
}
#ifdef DEBUG
JSObject *const StackFrame::sInvalidScopeChain = (JSObject *)0xbeef;
#endif
@ -797,8 +755,8 @@ bool
ContextStack::pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrameGuard *gfg)
{
StackFrame *genfp = gen->floatingFrame();
HeapValue *genvp = gen->floatingStack;
uintN vplen = (HeapValue *)genfp - genvp;
Value *genvp = gen->floatingStack;
uintN vplen = (Value *)genfp - genvp;
uintN nvars = vplen + VALUES_PER_STACK_FRAME + genfp->numSlots();
Value *firstUnused = ensureOnTop(cx, REPORT_ERROR, nvars, CAN_EXTEND, &gfg->pushedSeg_);
@ -824,8 +782,7 @@ ContextStack::pushGeneratorFrame(JSContext *cx, JSGenerator *gen, GeneratorFrame
JSObject::writeBarrierPre(genobj);
/* Copy from the generator's floating frame to the stack. */
stackfp->stealFrameAndSlots<Value, HeapValue, StackFrame::NoPostBarrier>(
stackfp, stackvp, genfp, genvp, gen->regs.sp);
stackfp->stealFrameAndSlots(stackvp, genfp, genvp, gen->regs.sp);
stackfp->resetGeneratorPrev(cx);
stackfp->unsetFloatingGenerator();
gfg->regs_.rebaseFromTo(gen->regs, *stackfp);
@ -841,7 +798,7 @@ ContextStack::popGeneratorFrame(const GeneratorFrameGuard &gfg)
{
JSGenerator *gen = gfg.gen_;
StackFrame *genfp = gen->floatingFrame();
HeapValue *genvp = gen->floatingStack;
Value *genvp = gen->floatingStack;
const FrameRegs &stackRegs = gfg.regs_;
StackFrame *stackfp = stackRegs.fp();
@ -849,8 +806,7 @@ ContextStack::popGeneratorFrame(const GeneratorFrameGuard &gfg)
/* Copy from the stack to the generator's floating frame. */
gen->regs.rebaseFromTo(stackRegs, *genfp);
genfp->stealFrameAndSlots<HeapValue, Value, StackFrame::DoPostBarrier>(
genfp, genvp, stackfp, stackvp, stackRegs.sp);
genfp->stealFrameAndSlots(genvp, stackfp, stackvp, stackRegs.sp);
genfp->setFloatingGenerator();
/* ~FrameGuard/popFrame will finish the popping. */

View File

@ -430,14 +430,7 @@ class StackFrame
const Value &thisv, JSObject &scopeChain, ExecuteType type);
/* Used when activating generators. */
enum TriggerPostBarriers {
DoPostBarrier = true,
NoPostBarrier = false
};
template <class T, class U, TriggerPostBarriers doPostBarrier>
void stealFrameAndSlots(StackFrame *fp, T *vp, StackFrame *otherfp, U *othervp,
Value *othersp);
void writeBarrierPost();
void stealFrameAndSlots(Value *vp, StackFrame *otherfp, Value *othervp, Value *othersp);
/* Perhaps one fine day we will remove dummy frames. */
void initDummyFrame(JSContext *cx, JSObject &chain);
@ -995,10 +988,6 @@ class StackFrame
/* Return value */
bool hasReturnValue() const {
return !!(flags_ & HAS_RVAL);
}
const Value &returnValue() {
if (!(flags_ & HAS_RVAL))
rval_.setUndefined();