mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Back out 710220a5ac33 (bug 714109) on suspicion of causing GC crashes in browser-chrome
This commit is contained in:
parent
59e5501107
commit
a8b3d39330
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user