зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1188878 - Ensure RematerializedFrames are cleared from Debugger instances on Ion bailout failure. (r=jandem)
This commit is contained in:
Родитель
bbd18bfb28
Коммит
22067a94a8
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче