Bug 989934 - Do not rely on SnapshotIterator::frameCount to iterate over inline frames. r=djvj

This commit is contained in:
Nicolas B. Pierron 2014-04-08 07:21:19 -07:00
parent 2d12354440
commit cc25031e47
3 changed files with 31 additions and 5 deletions

View File

@ -23,6 +23,7 @@ InlineFrameIteratorMaybeGC<allowGC>::InlineFrameIteratorMaybeGC(
JSContext *cx, const IonBailoutIterator *iter)
: frame_(iter),
framesRead_(0),
frameCount_(UINT32_MAX),
callee_(cx),
script_(cx)
{

View File

@ -413,7 +413,14 @@ class InlineFrameIteratorMaybeGC
const IonFrameIterator *frame_;
SnapshotIterator start_;
SnapshotIterator si_;
unsigned framesRead_;
uint32_t framesRead_;
// When the inline-frame-iterator is created, this variable is defined to
// UINT32_MAX. Then the first iteration of findNextFrame, which settle on
// the innermost frame, is used to update this counter to the number of
// frames contained in the recover buffer.
uint32_t frameCount_;
typename MaybeRooted<JSFunction*, allowGC>::RootType callee_;
typename MaybeRooted<JSScript*, allowGC>::RootType script_;
jsbytecode *pc_;
@ -446,6 +453,7 @@ class InlineFrameIteratorMaybeGC
InlineFrameIteratorMaybeGC(JSContext *cx, const InlineFrameIteratorMaybeGC *iter)
: frame_(iter ? iter->frame_ : nullptr),
framesRead_(0),
frameCount_(iter ? iter->frameCount_ : UINT32_MAX),
callee_(cx),
script_(cx)
{
@ -459,7 +467,7 @@ class InlineFrameIteratorMaybeGC
}
bool more() const {
return frame_ && framesRead_ < start_.frameCount();
return frame_ && framesRead_ < frameCount_;
}
JSFunction *callee() const {
JS_ASSERT(callee_);
@ -601,7 +609,8 @@ class InlineFrameIteratorMaybeGC
// Inline frame number, 0 for the outermost (non-inlined) frame.
size_t frameNo() const {
return start_.frameCount() - framesRead_;
MOZ_ASSERT(frameCount_ != UINT32_MAX);
return frameCount_ - framesRead_;
}
private:

View File

@ -1555,6 +1555,7 @@ InlineFrameIteratorMaybeGC<allowGC>::resetOn(const IonFrameIterator *iter)
{
frame_ = iter;
framesRead_ = 0;
frameCount_ = UINT32_MAX;
if (iter) {
start_ = SnapshotIterator(*iter);
@ -1582,8 +1583,15 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
// This unfortunately is O(n*m), because we must skip over outer frames
// before reading inner ones.
unsigned remaining = start_.frameCount() - framesRead_ - 1;
for (unsigned i = 0; i < remaining; i++) {
// The first time (frameCount_ == UINT32_MAX) we do not know the number of
// frames that we are going to inspect. So we are iterating until there is
// no more frames, to settle on the inner most frame and to count the number
// of frames.
size_t remaining = (frameCount_ != UINT32_MAX) ? frameNo() - 1 : SIZE_MAX;
size_t i = 1;
for (; i <= remaining && si_.moreFrames(); i++) {
JS_ASSERT(IsIonInlinablePC(pc_));
// Recover the number of actual arguments from the script.
@ -1623,6 +1631,14 @@ InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
pc_ = script_->offsetToPC(si_.pcOffset());
}
// The first time we do not know the number of frames, we only settle on the
// last frame, and update the number of frames based on the number of
// iteration that we have done.
if (frameCount_ == UINT32_MAX) {
MOZ_ASSERT(!si_.moreFrames());
frameCount_ = i;
}
framesRead_++;
}
template void InlineFrameIteratorMaybeGC<NoGC>::findNextFrame();