[INFER] Move containingSegment to StackSpace, fix uninitialized field, bug 646660.

This commit is contained in:
Brian Hackett 2011-03-30 17:24:34 -07:00
parent 740de451bc
commit 4b2582d94a
5 changed files with 31 additions and 49 deletions

View File

@ -114,29 +114,38 @@ static const size_t TEMP_POOL_CHUNK_SIZE = 4096 - ARENA_HEADER_SIZE_HACK;
static void static void
FreeContext(JSContext *cx); FreeContext(JSContext *cx);
#ifdef DEBUG
JS_REQUIRES_STACK bool JS_REQUIRES_STACK bool
StackSegment::contains(const JSStackFrame *fp) const StackSegment::contains(const JSStackFrame *fp) const
{ {
JS_ASSERT(inContext()); JS_ASSERT(inContext());
if (fp < initialFrame)
return false;
JSStackFrame *start; JSStackFrame *start;
JSStackFrame *stop;
if (isActive()) { if (isActive()) {
JS_ASSERT(cx->hasfp()); JS_ASSERT(cx->hasfp() && this == cx->activeSegment());
start = cx->fp(); start = cx->fp();
stop = cx->activeSegment()->initialFrame->prev();
} else { } else {
JS_ASSERT(suspendedRegs && suspendedRegs->fp); JS_ASSERT(suspendedRegs && suspendedRegs->fp);
start = suspendedRegs->fp; start = suspendedRegs->fp;
stop = initialFrame->prev();
} }
for (JSStackFrame *f = start; f != stop; f = f->prev()) {
if (fp > start)
return false;
#ifdef DEBUG
bool found = false;
JSStackFrame *stop = initialFrame->prev();
for (JSStackFrame *f = start; !found && f != stop; f = f->prev()) {
if (f == fp) if (f == fp)
found = true;
}
JS_ASSERT(found);
#endif
return true; return true;
} }
return false;
}
#endif
JSStackFrame * JSStackFrame *
StackSegment::computeNextFrame(JSStackFrame *fp) const StackSegment::computeNextFrame(JSStackFrame *fp) const
@ -2055,36 +2064,13 @@ JSContext::generatorFor(JSStackFrame *fp) const
} }
StackSegment * StackSegment *
JSContext::containingSegment(const JSStackFrame *target) StackSpace::containingSegment(const JSStackFrame *target)
{ {
/* The context may have nothing running. */ for (StackSegment *seg = currentSegment; seg; seg = seg->getPreviousInMemory()) {
StackSegment *seg = currentSegment; if (seg->contains(target))
if (!seg)
return NULL;
/* The active segments's top frame is cx->regs->fp. */
if (regs) {
JS_ASSERT(regs->fp);
JS_ASSERT(activeSegment() == seg);
JSStackFrame *f = regs->fp;
JSStackFrame *stop = seg->getInitialFrame()->prev();
for (; f != stop; f = f->prev()) {
if (f == target)
return seg; return seg;
} }
seg = seg->getPreviousInContext(); JS_NOT_REACHED("frame not in stack space");
}
/* A suspended segment's top frame is its suspended frame. */
for (; seg; seg = seg->getPreviousInContext()) {
JSStackFrame *f = seg->getSuspendedFrame();
JSStackFrame *stop = seg->getInitialFrame()->prev();
for (; f != stop; f = f->prev()) {
if (f == target)
return seg;
}
}
return NULL; return NULL;
} }

View File

@ -416,9 +416,7 @@ class StackSegment
return *initialVarObj; return *initialVarObj;
} }
#ifdef DEBUG
JS_REQUIRES_STACK bool contains(const JSStackFrame *fp) const; JS_REQUIRES_STACK bool contains(const JSStackFrame *fp) const;
#endif
JSStackFrame *computeNextFrame(JSStackFrame *fp) const; JSStackFrame *computeNextFrame(JSStackFrame *fp) const;
}; };
@ -725,6 +723,9 @@ class StackSpace
bool getExecuteFrame(JSContext *cx, JSScript *script, ExecuteFrameGuard *fg) const; bool getExecuteFrame(JSContext *cx, JSScript *script, ExecuteFrameGuard *fg) const;
void pushExecuteFrame(JSContext *cx, JSObject *initialVarObj, ExecuteFrameGuard *fg); void pushExecuteFrame(JSContext *cx, JSObject *initialVarObj, ExecuteFrameGuard *fg);
/* Get the segment which contains the target frame. */
js::StackSegment *containingSegment(const JSStackFrame *target);
/* /*
* Since RAII cannot be used for inline frames, callers must manually * Since RAII cannot be used for inline frames, callers must manually
* call pushInlineFrame/popInlineFrame. * call pushInlineFrame/popInlineFrame.
@ -1766,12 +1767,6 @@ struct JSContext
/* Undoes calls to suspendActiveSegment. */ /* Undoes calls to suspendActiveSegment. */
void restoreSegment(); void restoreSegment();
/*
* Perform a linear search of all frames in all segments in the given context
* for the given frame, returning the segment, if found, and null otherwise.
*/
js::StackSegment *containingSegment(const JSStackFrame *target);
/* Search the call stack for the nearest frame with static level targetLevel. */ /* Search the call stack for the nearest frame with static level targetLevel. */
JSStackFrame *findFrameAtLevel(uintN targetLevel) const { JSStackFrame *findFrameAtLevel(uintN targetLevel) const {
JSStackFrame *fp = regs->fp; JSStackFrame *fp = regs->fp;

View File

@ -116,7 +116,7 @@ JSStackFrame::pc(JSContext *cx, JSStackFrame *next, JSInlinedSite **pinlined)
{ {
JS_ASSERT_IF(next, next->prev_ == this); JS_ASSERT_IF(next, next->prev_ == this);
StackSegment *seg = cx->containingSegment(this); StackSegment *seg = cx->stack().containingSegment(this);
JSFrameRegs *regs = seg->getCurrentRegs(); JSFrameRegs *regs = seg->getCurrentRegs();
if (regs->fp == this) { if (regs->fp == this) {
if (pinlined) if (pinlined)
@ -1004,7 +1004,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
*/ */
initialVarObj = (prev == cx->maybefp()) initialVarObj = (prev == cx->maybefp())
? &prev->varobj(cx) ? &prev->varobj(cx)
: &prev->varobj(cx->containingSegment(prev)); : &prev->varobj(cx->stack().containingSegment(prev));
} else { } else {
/* The scope chain could be anything, so innerize just in case. */ /* The scope chain could be anything, so innerize just in case. */
JSObject *innerizedChain = chain; JSObject *innerizedChain = chain;

View File

@ -191,7 +191,7 @@ Parser::Parser(JSContext *cx, JSPrincipals *prin, JSStackFrame *cfp)
tokenStream(cx), tokenStream(cx),
principals(NULL), principals(NULL),
callerFrame(cfp), callerFrame(cfp),
callerVarObj(cfp ? &cfp->varobj(cx->containingSegment(cfp)) : NULL), callerVarObj(cfp ? &cfp->varobj(cx->stack().containingSegment(cfp)) : NULL),
nodeList(NULL), nodeList(NULL),
functionCount(0), functionCount(0),
traceListHead(NULL), traceListHead(NULL),

View File

@ -335,7 +335,7 @@ ExpandInlineFrames(JSContext *cx, bool all)
f = f->previous) { f = f->previous) {
if (f->regs.inlined) { if (f->regs.inlined) {
StackSegment *seg = cx->containingSegment(f->fp()); StackSegment *seg = cx->stack().containingSegment(f->fp());
JSFrameRegs *regs = seg->getCurrentRegs(); JSFrameRegs *regs = seg->getCurrentRegs();
if (regs->fp == f->fp()) { if (regs->fp == f->fp()) {
JS_ASSERT(regs == &f->regs); JS_ASSERT(regs == &f->regs);
@ -446,6 +446,7 @@ Recompiler::recompile()
PatchableFrame frame; PatchableFrame frame;
frame.fp = fp; frame.fp = fp;
frame.pc = fp->pc(cx, next); frame.pc = fp->pc(cx, next);
frame.scriptedCall = false;
if (next) { if (next) {
// check for a scripted call returning into the recompiled script. // check for a scripted call returning into the recompiled script.