Bug 832373 part 2 - Refactor initExecuteFrame to use AbstractFramePtr. r=luke a=nonlibxul

This commit is contained in:
Jan de Mooij 2013-01-22 14:33:43 +01:00
parent 7cad99bba1
commit 33dee1099a
3 changed files with 46 additions and 15 deletions

View File

@ -803,6 +803,14 @@ AbstractFramePtr::callee() const
JS_NOT_REACHED("Invalid frame");
return asStackFrame()->callee();
}
inline Value
AbstractFramePtr::calleev() const
{
if (isStackFrame())
return asStackFrame()->calleev();
JS_NOT_REACHED("Invalid frame");
return asStackFrame()->calleev();
}
inline bool
AbstractFramePtr::isNonEvalFunctionFrame() const
{

View File

@ -50,24 +50,34 @@ using mozilla::DebugOnly;
/*****************************************************************************/
void
StackFrame::initExecuteFrame(UnrootedScript script, StackFrame *prev, FrameRegs *regs,
const Value &thisv, JSObject &scopeChain, ExecuteType type)
StackFrame::initExecuteFrame(UnrootedScript script, StackFrame *prevLink, AbstractFramePtr prev,
FrameRegs *regs, const Value &thisv, JSObject &scopeChain,
ExecuteType type)
{
/*
* If |prev| is an interpreter frame, we can always prev-link to it.
* If |prev| is a baseline JIT frame, we prev-link to its entry frame.
*/
JS_ASSERT_IF(prev.isStackFrame(), prev.asStackFrame() == prevLink);
JS_ASSERT_IF(prev, prevLink != NULL);
/*
* See encoding of ExecuteType. When GLOBAL isn't set, we are executing a
* script in the context of another frame and the frame type is determined
* by the context.
*/
flags_ = type | HAS_SCOPECHAIN | HAS_BLOCKCHAIN | HAS_PREVPC;
if (!(flags_ & GLOBAL))
flags_ |= (prev->flags_ & (FUNCTION | GLOBAL));
if (!(flags_ & GLOBAL)) {
JS_ASSERT(prev.isFunctionFrame() || prev.isGlobalFrame());
flags_ |= prev.isFunctionFrame() ? FUNCTION : GLOBAL;
}
Value *dstvp = (Value *)this - 2;
dstvp[1] = thisv;
if (isFunctionFrame()) {
dstvp[0] = prev->calleev();
exec = prev->exec;
dstvp[0] = prev.calleev();
exec.fun = prev.fun();
u.evalScript = script;
} else {
JS_ASSERT(isGlobalFrame());
@ -79,7 +89,7 @@ StackFrame::initExecuteFrame(UnrootedScript script, StackFrame *prev, FrameRegs
}
scopeChain_ = &scopeChain;
prev_ = prev;
prev_ = prevLink;
prevpc_ = regs ? regs->pc : (jsbytecode *)0xbad;
prevInline_ = regs ? regs->inlined() : NULL;
blockChain_ = NULL;
@ -1061,24 +1071,35 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
* Eval-in-frame is the exception since it prev-links to an arbitrary frame
* (possibly in the middle of some previous segment). Thus pass CANT_EXTEND
* (to start a new segment) and link the frame and call chain manually
* below.
* below. If |evalInFrame| is a baseline JIT frame, prev-link to its entry
* frame.
*/
CallArgsList *evalInFrameCalls = NULL; /* quell overwarning */
MaybeExtend extend;
StackFrame *prevLink;
if (evalInFrame) {
/* Though the prev-frame is given, need to search for prev-call. */
StackSegment &seg = cx->stack.space().containingSegment(evalInFrame.asStackFrame());
/* First, find the right segment. */
AllFramesIter frameIter(cx->runtime);
while (frameIter.isIon() || frameIter.abstractFramePtr() != evalInFrame)
++frameIter;
JS_ASSERT(frameIter.abstractFramePtr() == evalInFrame);
StackSegment &seg = *frameIter.seg();
StackIter iter(cx->runtime, seg);
/* Debug-mode currently disables Ion compilation. */
JS_ASSERT(!evalInFrame.asStackFrame()->runningInIon());
JS_ASSERT_IF(evalInFrame.isStackFrame(), !evalInFrame.asStackFrame()->runningInIon());
JS_ASSERT_IF(evalInFrame.compartment() == iter.compartment(), !iter.isIon());
while (!iter.isScript() || iter.isIon() || iter.abstractFramePtr() != evalInFrame) {
++iter;
JS_ASSERT_IF(evalInFrame.compartment() == iter.compartment(), !iter.isIon());
}
JS_ASSERT(iter.abstractFramePtr() == evalInFrame);
evalInFrameCalls = iter.data_.calls_;
prevLink = iter.data_.fp_;
extend = CANT_EXTEND;
} else {
prevLink = maybefp();
extend = CAN_EXTEND;
}
@ -1087,9 +1108,9 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
if (!firstUnused)
return false;
StackFrame *prev = evalInFrame ? evalInFrame.asStackFrame() : maybefp();
AbstractFramePtr prev = evalInFrame ? evalInFrame : maybefp();
StackFrame *fp = reinterpret_cast<StackFrame *>(firstUnused + 2);
fp->initExecuteFrame(script, prev, seg_->maybeRegs(), thisv, scopeChain, type);
fp->initExecuteFrame(script, prevLink, prev, seg_->maybeRegs(), thisv, scopeChain, type);
fp->initVarsToUndefined();
efg->regs_.prepareToRun(*fp, script);

View File

@ -275,6 +275,7 @@ class AbstractFramePtr
inline UnrootedScript script() const;
inline JSFunction *fun() const;
inline JSFunction &callee() const;
inline Value calleev() const;
inline Value &thisValue() const;
inline bool isNonEvalFunctionFrame() const;
@ -454,8 +455,9 @@ class StackFrame
void initFixupFrame(StackFrame *prev, StackFrame::Flags flags, void *ncode, unsigned nactual);
/* Used for eval. */
void initExecuteFrame(UnrootedScript script, StackFrame *prev, FrameRegs *regs,
const Value &thisv, JSObject &scopeChain, ExecuteType type);
void initExecuteFrame(UnrootedScript script, StackFrame *prevLink, AbstractFramePtr prev,
FrameRegs *regs, const Value &thisv, JSObject &scopeChain,
ExecuteType type);
public:
/*