зеркало из https://github.com/mozilla/gecko-dev.git
Bug 632358 - Only call resetCompartment() when safe to GC (r=waldo,a=blocking)
This commit is contained in:
Родитель
ec364ebcae
Коммит
f0b5c459cd
|
@ -5285,7 +5285,6 @@ JS_RestoreFrameChain(JSContext *cx, JSStackFrame *fp)
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return;
|
return;
|
||||||
cx->restoreSegment();
|
cx->restoreSegment();
|
||||||
cx->resetCompartment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
|
|
|
@ -316,20 +316,20 @@ StackSpace::getSegmentAndFrame(JSContext *cx, uintN vplen, uintN nfixed,
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StackSpace::pushSegmentAndFrame(JSContext *cx, JSObject *initialVarObj,
|
StackSpace::pushSegmentAndFrame(JSContext *cx, JSFrameRegs *regs, FrameGuard *fg)
|
||||||
JSFrameRegs *regs, FrameGuard *fg)
|
|
||||||
{
|
{
|
||||||
/* Caller should have already initialized regs. */
|
/* Caller should have already initialized regs. */
|
||||||
JS_ASSERT(regs->fp == fg->fp());
|
JS_ASSERT(regs->fp == fg->fp());
|
||||||
|
|
||||||
/* Push segment. */
|
|
||||||
StackSegment *seg = fg->segment();
|
StackSegment *seg = fg->segment();
|
||||||
|
|
||||||
|
/* Register new segment/frame with the context. */
|
||||||
|
cx->pushSegmentAndFrame(seg, *regs);
|
||||||
|
|
||||||
|
/* Officially push the segment/frame on the stack. */
|
||||||
seg->setPreviousInMemory(currentSegment);
|
seg->setPreviousInMemory(currentSegment);
|
||||||
currentSegment = seg;
|
currentSegment = seg;
|
||||||
|
|
||||||
/* Push frame. */
|
/* Mark as 'pushed' in the guard. */
|
||||||
cx->pushSegmentAndFrame(seg, *regs);
|
|
||||||
seg->setInitialVarObj(initialVarObj);
|
|
||||||
fg->cx_ = cx;
|
fg->cx_ = cx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,8 +338,17 @@ StackSpace::popSegmentAndFrame(JSContext *cx)
|
||||||
{
|
{
|
||||||
JS_ASSERT(isCurrentAndActive(cx));
|
JS_ASSERT(isCurrentAndActive(cx));
|
||||||
JS_ASSERT(cx->hasActiveSegment());
|
JS_ASSERT(cx->hasActiveSegment());
|
||||||
cx->popSegmentAndFrame();
|
|
||||||
|
/* Officially pop the segment/frame from the stack. */
|
||||||
currentSegment = currentSegment->getPreviousInMemory();
|
currentSegment = currentSegment->getPreviousInMemory();
|
||||||
|
|
||||||
|
/* Unregister pushed segment/frame from the context. */
|
||||||
|
cx->popSegmentAndFrame();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* N.B. This StackSpace should be GC-able without any operations after
|
||||||
|
* cx->popSegmentAndFrame executes since it can trigger GC.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameGuard::~FrameGuard()
|
FrameGuard::~FrameGuard()
|
||||||
|
@ -365,7 +374,8 @@ StackSpace::pushExecuteFrame(JSContext *cx, JSObject *initialVarObj, ExecuteFram
|
||||||
fg->regs_.pc = script->code;
|
fg->regs_.pc = script->code;
|
||||||
fg->regs_.fp = fp;
|
fg->regs_.fp = fp;
|
||||||
fg->regs_.sp = fp->base();
|
fg->regs_.sp = fp->base();
|
||||||
pushSegmentAndFrame(cx, initialVarObj, &fg->regs_, fg);
|
pushSegmentAndFrame(cx, &fg->regs_, fg);
|
||||||
|
fg->seg_->setInitialVarObj(initialVarObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -377,7 +387,7 @@ StackSpace::pushDummyFrame(JSContext *cx, JSObject &scopeChain, DummyFrameGuard
|
||||||
fg->regs_.fp = fg->fp();
|
fg->regs_.fp = fg->fp();
|
||||||
fg->regs_.pc = NULL;
|
fg->regs_.pc = NULL;
|
||||||
fg->regs_.sp = fg->fp()->slots();
|
fg->regs_.sp = fg->fp()->slots();
|
||||||
pushSegmentAndFrame(cx, NULL /*varobj*/, &fg->regs_, fg);
|
pushSegmentAndFrame(cx, &fg->regs_, fg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +402,7 @@ StackSpace::pushGeneratorFrame(JSContext *cx, JSFrameRegs *regs, GeneratorFrameG
|
||||||
{
|
{
|
||||||
JS_ASSERT(regs->fp == fg->fp());
|
JS_ASSERT(regs->fp == fg->fp());
|
||||||
JS_ASSERT(regs->fp->prev() == cx->maybefp());
|
JS_ASSERT(regs->fp->prev() == cx->maybefp());
|
||||||
pushSegmentAndFrame(cx, NULL /*varobj*/, regs, fg);
|
pushSegmentAndFrame(cx, regs, fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2045,6 +2055,11 @@ JSContext::pushSegmentAndFrame(js::StackSegment *newseg, JSFrameRegs &newregs)
|
||||||
void
|
void
|
||||||
JSContext::popSegmentAndFrame()
|
JSContext::popSegmentAndFrame()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* NB: This function calls resetCompartment, which may GC, so the stack needs
|
||||||
|
* to be in a GC-able state by that point.
|
||||||
|
*/
|
||||||
|
|
||||||
JS_ASSERT(currentSegment->maybeContext() == this);
|
JS_ASSERT(currentSegment->maybeContext() == this);
|
||||||
JS_ASSERT(currentSegment->getInitialFrame() == regs->fp);
|
JS_ASSERT(currentSegment->getInitialFrame() == regs->fp);
|
||||||
currentSegment->leaveContext();
|
currentSegment->leaveContext();
|
||||||
|
@ -2052,6 +2067,7 @@ JSContext::popSegmentAndFrame()
|
||||||
if (currentSegment) {
|
if (currentSegment) {
|
||||||
if (currentSegment->isSaved()) {
|
if (currentSegment->isSaved()) {
|
||||||
setCurrentRegs(NULL);
|
setCurrentRegs(NULL);
|
||||||
|
resetCompartment();
|
||||||
} else {
|
} else {
|
||||||
setCurrentRegs(currentSegment->getSuspendedRegs());
|
setCurrentRegs(currentSegment->getSuspendedRegs());
|
||||||
currentSegment->resume();
|
currentSegment->resume();
|
||||||
|
@ -2059,6 +2075,7 @@ JSContext::popSegmentAndFrame()
|
||||||
} else {
|
} else {
|
||||||
JS_ASSERT(regs->fp->prev() == NULL);
|
JS_ASSERT(regs->fp->prev() == NULL);
|
||||||
setCurrentRegs(NULL);
|
setCurrentRegs(NULL);
|
||||||
|
resetCompartment();
|
||||||
}
|
}
|
||||||
maybeMigrateVersionOverride();
|
maybeMigrateVersionOverride();
|
||||||
}
|
}
|
||||||
|
@ -2069,6 +2086,7 @@ JSContext::saveActiveSegment()
|
||||||
JS_ASSERT(hasActiveSegment());
|
JS_ASSERT(hasActiveSegment());
|
||||||
currentSegment->save(regs);
|
currentSegment->save(regs);
|
||||||
setCurrentRegs(NULL);
|
setCurrentRegs(NULL);
|
||||||
|
resetCompartment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2077,6 +2095,7 @@ JSContext::restoreSegment()
|
||||||
js::StackSegment *ccs = currentSegment;
|
js::StackSegment *ccs = currentSegment;
|
||||||
setCurrentRegs(ccs->getSuspendedRegs());
|
setCurrentRegs(ccs->getSuspendedRegs());
|
||||||
ccs->restore();
|
ccs->restore();
|
||||||
|
resetCompartment();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSGenerator *
|
JSGenerator *
|
||||||
|
|
|
@ -601,8 +601,7 @@ class StackSpace
|
||||||
|
|
||||||
bool getSegmentAndFrame(JSContext *cx, uintN vplen, uintN nfixed,
|
bool getSegmentAndFrame(JSContext *cx, uintN vplen, uintN nfixed,
|
||||||
FrameGuard *fg) const;
|
FrameGuard *fg) const;
|
||||||
void pushSegmentAndFrame(JSContext *cx, JSObject *initialVarObj,
|
void pushSegmentAndFrame(JSContext *cx, JSFrameRegs *regs, FrameGuard *fg);
|
||||||
JSFrameRegs *regs, FrameGuard *fg);
|
|
||||||
void popSegmentAndFrame(JSContext *cx);
|
void popSegmentAndFrame(JSContext *cx);
|
||||||
|
|
||||||
struct EnsureSpaceCheck {
|
struct EnsureSpaceCheck {
|
||||||
|
@ -1692,12 +1691,10 @@ struct JSContext
|
||||||
void resetCompartment();
|
void resetCompartment();
|
||||||
void wrapPendingException();
|
void wrapPendingException();
|
||||||
|
|
||||||
/* 'regs' must only be changed by calling this function. */
|
/* For grep-ability, changes to 'regs' should call this function. */
|
||||||
void setCurrentRegs(JSFrameRegs *regs) {
|
void setCurrentRegs(JSFrameRegs *regs) {
|
||||||
JS_ASSERT_IF(regs, regs->fp);
|
JS_ASSERT_IF(regs, regs->fp);
|
||||||
this->regs = regs;
|
this->regs = regs;
|
||||||
if (!regs)
|
|
||||||
resetCompartment();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Temporary arena pool used while compiling and decompiling. */
|
/* Temporary arena pool used while compiling and decompiling. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче