Bug 1188878 - Ensure RematerializedFrames are cleared from Debugger instances on Ion bailout failure. (r=jandem)

This commit is contained in:
Shu-yu Guo 2015-08-12 16:37:07 -07:00
Родитель bbd18bfb28
Коммит 22067a94a8
4 изменённых файлов: 28 добавлений и 7 удалений

Просмотреть файл

@ -4,6 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ScopeExit.h"
#include "mozilla/SizePrintfMacros.h" #include "mozilla/SizePrintfMacros.h"
#include "jsprf.h" #include "jsprf.h"
@ -1406,6 +1407,13 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
TraceLogStopEvent(logger, TraceLogger_IonMonkey); TraceLogStopEvent(logger, TraceLogger_IonMonkey);
TraceLogStartEvent(logger, TraceLogger_Baseline); TraceLogStartEvent(logger, TraceLogger_Baseline);
// Ion bailout can fail due to overrecursion and OOM. In such cases we
// cannot honor any further Debugger hooks on the frame, and need to
// ensure that its Debugger.Frame entry is cleaned up.
auto guardRemoveRematerializedFramesFromDebugger = mozilla::MakeScopeExit([&] {
activation->removeRematerializedFramesFromDebugger(cx, iter.fp());
});
// The caller of the top frame must be one of the following: // The caller of the top frame must be one of the following:
// IonJS - Ion calling into Ion. // IonJS - Ion calling into Ion.
// BaselineStub - Baseline calling into Ion. // BaselineStub - Baseline calling into Ion.
@ -1591,6 +1599,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter
info->numFrames = frameNo + 1; info->numFrames = frameNo + 1;
info->bailoutKind = bailoutKind; info->bailoutKind = bailoutKind;
*bailoutInfo = info; *bailoutInfo = info;
guardRemoveRematerializedFramesFromDebugger.release();
return BAILOUT_RETURN_OK; return BAILOUT_RETURN_OK;
} }

Просмотреть файл

@ -466,13 +466,6 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed); uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed);
if (retval == BAILOUT_RETURN_OK) if (retval == BAILOUT_RETURN_OK)
return; return;
// If bailout failed (e.g., due to overrecursion), clean up any
// Debugger.Frame instances here. Normally this should happen
// inside the debug epilogue, but due to bailout failure, we
// cannot honor any Debugger hooks.
if (rematFrame)
Debugger::handleUnrecoverableIonBailoutError(cx, rematFrame);
} }
MOZ_ASSERT_IF(rematFrame, !Debugger::inFrameMaps(rematFrame)); MOZ_ASSERT_IF(rematFrame, !Debugger::inFrameMaps(rematFrame));

Просмотреть файл

@ -17,6 +17,7 @@
#include "jit/JitcodeMap.h" #include "jit/JitcodeMap.h"
#include "jit/JitCompartment.h" #include "jit/JitCompartment.h"
#include "js/GCAPI.h" #include "js/GCAPI.h"
#include "vm/Debugger.h"
#include "vm/Opcodes.h" #include "vm/Opcodes.h"
#include "jit/JitFrameIterator-inl.h" #include "jit/JitFrameIterator-inl.h"
@ -1569,6 +1570,20 @@ jit::JitActivation::lookupRematerializedFrame(uint8_t* top, size_t inlineDepth)
return nullptr; return nullptr;
} }
void
jit::JitActivation::removeRematerializedFramesFromDebugger(JSContext* cx, uint8_t* top)
{
// Ion bailout can fail due to overrecursion and OOM. In such cases we
// cannot honor any further Debugger hooks on the frame, and need to
// ensure that its Debugger.Frame entry is cleaned up.
if (!cx->compartment()->isDebuggee() || !rematerializedFrames_)
return;
if (RematerializedFrameTable::Ptr p = rematerializedFrames_->lookup(top)) {
for (uint32_t i = 0; i < p->value().length(); i++)
Debugger::handleUnrecoverableIonBailoutError(cx, p->value()[i]);
}
}
void void
jit::JitActivation::markRematerializedFrames(JSTracer* trc) jit::JitActivation::markRematerializedFrames(JSTracer* trc)
{ {

Просмотреть файл

@ -1604,6 +1604,10 @@ class JitActivation : public Activation
// bounds of what has been rematerialized, nullptr is returned. // bounds of what has been rematerialized, nullptr is returned.
RematerializedFrame* lookupRematerializedFrame(uint8_t* top, size_t inlineDepth = 0); RematerializedFrame* lookupRematerializedFrame(uint8_t* top, size_t inlineDepth = 0);
// Remove all rematerialized frames associated with the fp top from the
// Debugger.
void removeRematerializedFramesFromDebugger(JSContext* cx, uint8_t* top);
bool hasRematerializedFrame(uint8_t* top, size_t inlineDepth = 0) { bool hasRematerializedFrame(uint8_t* top, size_t inlineDepth = 0) {
return !!lookupRematerializedFrame(top, inlineDepth); return !!lookupRematerializedFrame(top, inlineDepth);
} }