mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 829579 - Rewrite AllFramesIter to iterate Ion frames too. r=luke
--HG-- extra : rebase_source : 73b9cf6d2ab9b1a167cc6847fcc114045f796fc5
This commit is contained in:
parent
3f4c90b945
commit
3623056142
@ -801,7 +801,7 @@ JSCompartment::onTooMuchMalloc()
|
||||
bool
|
||||
JSCompartment::hasScriptsOnStack()
|
||||
{
|
||||
for (AllFramesIter afi(rt->stackSpace); !afi.done(); ++afi) {
|
||||
for (AllFramesIter afi(rt); !afi.done(); ++afi) {
|
||||
#ifdef JS_ION
|
||||
// If this is an Ion frame, check the IonActivation instead
|
||||
if (afi.isIon())
|
||||
|
@ -2702,7 +2702,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||
* assumption of !script->needsArgsObj();
|
||||
* - type inference data for the script assuming script->needsArgsObj; and
|
||||
*/
|
||||
for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) {
|
||||
for (AllFramesIter i(cx->runtime); !i.done(); ++i) {
|
||||
/*
|
||||
* We cannot reliably create an arguments object for Ion activations of
|
||||
* this script. To maintain the invariant that "script->needsArgsObj
|
||||
|
@ -1984,7 +1984,7 @@ Debugger::getNewestFrame(JSContext *cx, unsigned argc, Value *vp)
|
||||
* cx->fp() would return the topmost frame in the current context.
|
||||
* Since there may be multiple contexts, use AllFramesIter instead.
|
||||
*/
|
||||
for (AllFramesIter i(cx->stack.space()); !i.done(); ++i) {
|
||||
for (AllFramesIter i(cx->runtime); !i.done(); ++i) {
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
|
@ -1922,7 +1922,7 @@ DebugScopes::updateLiveScopes(JSContext *cx)
|
||||
* to date' bit for fp->prev() in fp, simply popping fp effectively clears
|
||||
* the flag for us, at exactly the time when execution resumes fp->prev().
|
||||
*/
|
||||
for (AllFramesIter i(cx->runtime->stackSpace); !i.done(); ++i) {
|
||||
for (AllFramesIter i(cx->runtime); !i.done(); ++i) {
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
|
@ -816,7 +816,9 @@ StackSpace::sizeOf()
|
||||
bool
|
||||
StackSpace::containsSlow(StackFrame *fp)
|
||||
{
|
||||
for (AllFramesIter i(*this); !i.done(); ++i) {
|
||||
if (!seg_)
|
||||
return false;
|
||||
for (AllFramesIter i(seg_->cx()->runtime); !i.done(); ++i) {
|
||||
/*
|
||||
* Debug-mode currently disables Ion compilation in the compartment of
|
||||
* the debuggee.
|
||||
@ -2041,24 +2043,75 @@ StackIter::frameSlotValue(size_t index) const
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
AllFramesIter::AllFramesIter(StackSpace &space)
|
||||
: seg_(space.seg_),
|
||||
AllFramesIter::AllFramesIter(JSRuntime *rt)
|
||||
: seg_(rt->stackSpace.seg_),
|
||||
fp_(seg_ ? seg_->maybefp() : NULL)
|
||||
#ifdef JS_ION
|
||||
, ionActivations_(rt),
|
||||
ionFrames_((uint8_t *)NULL)
|
||||
#endif
|
||||
{
|
||||
settle();
|
||||
settleOnNewState();
|
||||
}
|
||||
|
||||
#ifdef JS_ION
|
||||
void
|
||||
AllFramesIter::popIonFrame()
|
||||
{
|
||||
JS_ASSERT(state_ == ION);
|
||||
|
||||
++ionFrames_;
|
||||
while (!ionFrames_.done() && !ionFrames_.isScripted())
|
||||
++ionFrames_;
|
||||
|
||||
if (!ionFrames_.done())
|
||||
return;
|
||||
|
||||
// The activation has no other frames. If entryfp is NULL, it was invoked
|
||||
// by a native written in C++, using FastInvoke, on top of another activation.
|
||||
ion::IonActivation *activation = ionActivations_.activation();
|
||||
if (!activation->entryfp()) {
|
||||
JS_ASSERT(activation->prevpc());
|
||||
JS_ASSERT(fp_->beginsIonActivation());
|
||||
++ionActivations_;
|
||||
settleOnNewState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fp_->runningInIon()) {
|
||||
++ionActivations_;
|
||||
fp_ = fp_->prev();
|
||||
settleOnNewState();
|
||||
} else {
|
||||
JS_ASSERT(fp_->callingIntoIon());
|
||||
state_ = SCRIPTED;
|
||||
++ionActivations_;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
AllFramesIter&
|
||||
AllFramesIter::operator++()
|
||||
{
|
||||
JS_ASSERT(!done());
|
||||
fp_ = fp_->prev();
|
||||
settle();
|
||||
switch (state_) {
|
||||
case SCRIPTED:
|
||||
fp_ = fp_->prev();
|
||||
settleOnNewState();
|
||||
break;
|
||||
#ifdef JS_ION
|
||||
case ION:
|
||||
popIonFrame();
|
||||
break;
|
||||
#endif
|
||||
case DONE:
|
||||
default:
|
||||
JS_NOT_REACHED("Unexpeced state");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
AllFramesIter::settle()
|
||||
AllFramesIter::settleOnNewState()
|
||||
{
|
||||
while (seg_ && (!fp_ || !seg_->contains(fp_))) {
|
||||
seg_ = seg_->prevInMemory();
|
||||
@ -2067,10 +2120,33 @@ AllFramesIter::settle()
|
||||
|
||||
JS_ASSERT(!!seg_ == !!fp_);
|
||||
JS_ASSERT_IF(fp_, seg_->contains(fp_));
|
||||
|
||||
#ifdef JS_ION
|
||||
if (fp_ && fp_->beginsIonActivation()) {
|
||||
// Start at the first scripted frame.
|
||||
ionFrames_ = ion::IonFrameIterator(ionActivations_);
|
||||
while (!ionFrames_.isScripted() && !ionFrames_.done())
|
||||
++ionFrames_;
|
||||
|
||||
state_ = ionFrames_.done() ? SCRIPTED : ION;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
state_ = fp_ ? SCRIPTED : DONE;
|
||||
}
|
||||
|
||||
TaggedFramePtr
|
||||
AllFramesIter::taggedFramePtr() const
|
||||
{
|
||||
return TaggedFramePtr(interpFrame());
|
||||
switch (state_) {
|
||||
case SCRIPTED:
|
||||
return TaggedFramePtr(interpFrame());
|
||||
case ION:
|
||||
break;
|
||||
case DONE:
|
||||
break;
|
||||
}
|
||||
JS_NOT_REACHED("Unexpected state");
|
||||
return TaggedFramePtr();
|
||||
}
|
||||
|
@ -2159,26 +2159,39 @@ class NonBuiltinScriptFrameIter : public StackIter
|
||||
|
||||
/*
|
||||
* Blindly iterate over all frames in the current thread's stack. These frames
|
||||
* can be from different contexts and compartments, so beware.
|
||||
* can be from different contexts and compartments, so beware. Iterates over
|
||||
* Ion frames, but does not handle inlined frames.
|
||||
*/
|
||||
class AllFramesIter
|
||||
{
|
||||
public:
|
||||
AllFramesIter(StackSpace &space);
|
||||
AllFramesIter(JSRuntime *rt);
|
||||
|
||||
bool done() const { return fp_ == NULL; }
|
||||
bool done() const { return state_ == DONE; }
|
||||
AllFramesIter& operator++();
|
||||
|
||||
bool isIon() const { return fp_->runningInIon(); }
|
||||
StackFrame *interpFrame() const { return fp_; }
|
||||
bool isIon() const { return state_ == ION; }
|
||||
StackFrame *interpFrame() const { JS_ASSERT(state_ == SCRIPTED); return fp_; }
|
||||
StackSegment *seg() const { return seg_; }
|
||||
|
||||
TaggedFramePtr taggedFramePtr() const;
|
||||
|
||||
private:
|
||||
void settle();
|
||||
enum State { DONE, SCRIPTED, ION };
|
||||
|
||||
#ifdef JS_ION
|
||||
void popIonFrame();
|
||||
#endif
|
||||
void settleOnNewState();
|
||||
|
||||
StackSegment *seg_;
|
||||
StackFrame *fp_;
|
||||
State state_;
|
||||
|
||||
#ifdef JS_ION
|
||||
ion::IonActivationIterator ionActivations_;
|
||||
ion::IonFrameIterator ionFrames_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
Loading…
Reference in New Issue
Block a user