Bug 847446 - Correctly handle fake exit frames in ionStackRange. r=djvj

This commit is contained in:
Jan de Mooij 2013-03-25 19:38:50 +01:00
parent 50722320c8
commit d45d9ce25a
3 changed files with 45 additions and 18 deletions

View File

@ -114,8 +114,18 @@ class IonFrameIterator
return (IonJSFrameLayout *) fp();
}
// Returns true iff this exit frame was created using EnsureExitFrame.
bool isFakeExitFrame() const {
bool res = (prevType() == IonFrame_Unwound_Rectifier ||
prevType() == IonFrame_Unwound_OptimizedJS ||
prevType() == IonFrame_Unwound_BaselineStub);
JS_ASSERT_IF(res, type() == IonFrame_Exit || type() == IonFrame_BaselineJS);
return res;
}
IonExitFrameLayout *exitFrame() const {
JS_ASSERT(type() == IonFrame_Exit);
JS_ASSERT(!isFakeExitFrame());
return (IonExitFrameLayout *) fp();
}

View File

@ -104,7 +104,7 @@ IonFrameIterator::maybeCallee() const
bool
IonFrameIterator::isNative() const
{
if (type_ != IonFrame_Exit)
if (type_ != IonFrame_Exit || isFakeExitFrame())
return false;
return exitFrame()->footer()->ionCode() == NULL;
}
@ -203,11 +203,7 @@ IonFrameIterator::prevFp() const
// This quick fix must be removed as soon as bug 717297 land. This is
// needed because the descriptor size of JS-to-JS frame which is just after
// a Rectifier frame should not change. (cf EnsureExitFrame function)
if (prevType() == IonFrame_Unwound_Rectifier ||
prevType() == IonFrame_Unwound_OptimizedJS ||
prevType() == IonFrame_Unwound_BaselineStub)
{
JS_ASSERT(type_ == IonFrame_Exit || type_ == IonFrame_BaselineJS);
if (isFakeExitFrame()) {
JS_ASSERT(SizeOfFramePrefix(IonFrame_BaselineJS) ==
SizeOfFramePrefix(IonFrame_OptimizedJS));
currentSize = SizeOfFramePrefix(IonFrame_OptimizedJS);
@ -698,13 +694,17 @@ IonActivationIterator::ionStackRange(uintptr_t *&min, uintptr_t *&end)
{
IonFrameIterator frames(top());
IonExitFrameLayout *exitFrame = frames.exitFrame();
IonExitFooterFrame *footer = exitFrame->footer();
const VMFunction *f = footer->function();
if (exitFrame->isWrapperExit() && f->outParam == Type_Handle)
min = reinterpret_cast<uintptr_t *>(footer->outVp());
else
min = reinterpret_cast<uintptr_t *>(footer);
if (frames.isFakeExitFrame()) {
min = reinterpret_cast<uintptr_t *>(frames.fp());
} else {
IonExitFrameLayout *exitFrame = frames.exitFrame();
IonExitFooterFrame *footer = exitFrame->footer();
const VMFunction *f = footer->function();
if (exitFrame->isWrapperExit() && f->outParam == Type_Handle)
min = reinterpret_cast<uintptr_t *>(footer->outVp());
else
min = reinterpret_cast<uintptr_t *>(footer);
}
while (!frames.done())
++frames;
@ -716,12 +716,8 @@ static void
MarkIonExitFrame(JSTracer *trc, const IonFrameIterator &frame)
{
// Ignore fake exit frames created by EnsureExitFrame.
if (frame.prevType() == IonFrame_Unwound_Rectifier ||
frame.prevType() == IonFrame_Unwound_OptimizedJS ||
frame.prevType() == IonFrame_Unwound_BaselineStub)
{
if (frame.isFakeExitFrame())
return;
}
IonExitFooterFrame *footer = frame.exitFrame()->footer();

View File

@ -0,0 +1,21 @@
// |jit-test| error: ReferenceError
var k = 0;
function test() {
function gen() {
try {
try {
yield 1;
} finally {
if (k++ < 60)
actual += "Inner finally";
}
} finally { }
}
try {
for (var i in gen())
test();
} catch (e) {
throw e;
}
}
test();