зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1576567 part 3 - Use real NOPs for debug trap handler calls in interpreter loop. r=tcampbell
We now use real NOPs on all platforms. On x86/x64 this used to be a CMP instruction and on ARM64 this involved an unconditional LDR with some other instructions. Depends on D43413 Differential Revision: https://phabricator.services.mozilla.com/D43414 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1072abd991
Коммит
ee9632c4ba
|
@ -6866,15 +6866,7 @@ MethodStatus BaselineCompiler::emitBody() {
|
|||
}
|
||||
|
||||
bool BaselineInterpreterGenerator::emitDebugTrap() {
|
||||
JitRuntime* jrt = cx->runtime()->jitRuntime();
|
||||
|
||||
JitCode* handlerCode =
|
||||
jrt->debugTrapHandler(cx, DebugTrapHandlerKind::Interpreter);
|
||||
if (!handlerCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CodeOffset offset = masm.toggledCall(handlerCode, /* enabled = */ false);
|
||||
CodeOffset offset = masm.nopPatchableToCall();
|
||||
if (!debugTrapOffsets_.append(offset.offset())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
|
@ -6995,6 +6987,20 @@ bool BaselineInterpreterGenerator::emitInterpreterLoop() {
|
|||
restoreInterpreterPCReg();
|
||||
masm.jump(&bailoutPrologue_);
|
||||
|
||||
// Emit debug trap handler code (target of patchable call instructions). This
|
||||
// is just a tail call to the debug trap handler trampoline code.
|
||||
{
|
||||
JitRuntime* jrt = cx->runtime()->jitRuntime();
|
||||
JitCode* handlerCode =
|
||||
jrt->debugTrapHandler(cx, DebugTrapHandlerKind::Interpreter);
|
||||
if (!handlerCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
debugTrapHandlerOffset_ = masm.currentOffset();
|
||||
masm.jump(handlerCode);
|
||||
}
|
||||
|
||||
// Emit code for JSOP_UNUSED* ops.
|
||||
Label invalidOp;
|
||||
masm.bind(&invalidOp);
|
||||
|
@ -7129,7 +7135,7 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
|
|||
bailoutPrologueOffset_.offset(),
|
||||
handler.generatorThrowOrReturnCallOffset(),
|
||||
profilerEnterFrameToggleOffset_.offset(),
|
||||
profilerExitFrameToggleOffset_.offset(),
|
||||
profilerExitFrameToggleOffset_.offset(), debugTrapHandlerOffset_,
|
||||
std::move(handler.debugInstrumentationOffsets()),
|
||||
std::move(debugTrapOffsets_), std::move(handler.codeCoverageOffsets()),
|
||||
std::move(handler.icReturnOffsets()), handler.callVMOffsets());
|
||||
|
|
|
@ -768,6 +768,10 @@ class BaselineInterpreterGenerator final : private BaselineInterpreterCodeGen {
|
|||
// Like interpretOpOffset_ but skips the debug trap for the current op.
|
||||
uint32_t interpretOpNoDebugTrapOffset_ = 0;
|
||||
|
||||
// Offset of the jump (tail call) to the debug trap handler trampoline code.
|
||||
// When the debugger is enabled, NOPs are patched to calls to this location.
|
||||
uint32_t debugTrapHandlerOffset_ = 0;
|
||||
|
||||
public:
|
||||
explicit BaselineInterpreterGenerator(JSContext* cx);
|
||||
|
||||
|
|
|
@ -899,9 +899,16 @@ void BaselineInterpreter::toggleDebuggerInstrumentation(bool enable) {
|
|||
}
|
||||
|
||||
// Toggle DebugTrapHandler calls.
|
||||
|
||||
uint8_t* debugTrapHandler = codeAtOffset(debugTrapHandlerOffset_);
|
||||
|
||||
for (uint32_t offset : debugTrapOffsets_) {
|
||||
CodeLocationLabel trapLocation(code_, CodeOffset(offset));
|
||||
Assembler::ToggleCall(trapLocation, enable);
|
||||
uint8_t* trap = codeAtOffset(offset);
|
||||
if (enable) {
|
||||
MacroAssembler::patchNopToCall(trap, debugTrapHandler);
|
||||
} else {
|
||||
MacroAssembler::patchCallToNop(trap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1012,6 +1019,7 @@ void BaselineInterpreter::init(JitCode* code, uint32_t interpretOpOffset,
|
|||
uint32_t generatorThrowOrReturnCallOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset,
|
||||
uint32_t debugTrapHandlerOffset,
|
||||
CodeOffsetVector&& debugInstrumentationOffsets,
|
||||
CodeOffsetVector&& debugTrapOffsets,
|
||||
CodeOffsetVector&& codeCoverageOffsets,
|
||||
|
@ -1024,6 +1032,7 @@ void BaselineInterpreter::init(JitCode* code, uint32_t interpretOpOffset,
|
|||
generatorThrowOrReturnCallOffset_ = generatorThrowOrReturnCallOffset;
|
||||
profilerEnterToggleOffset_ = profilerEnterToggleOffset;
|
||||
profilerExitToggleOffset_ = profilerExitToggleOffset;
|
||||
debugTrapHandlerOffset_ = debugTrapHandlerOffset;
|
||||
debugInstrumentationOffsets_ = std::move(debugInstrumentationOffsets);
|
||||
debugTrapOffsets_ = std::move(debugTrapOffsets);
|
||||
codeCoverageOffsets_ = std::move(codeCoverageOffsets);
|
||||
|
|
|
@ -504,6 +504,10 @@ class BaselineInterpreter {
|
|||
uint32_t profilerEnterToggleOffset_ = 0;
|
||||
uint32_t profilerExitToggleOffset_ = 0;
|
||||
|
||||
// Offset of the jump (tail call) to the debug trap handler trampoline code.
|
||||
// When the debugger is enabled, NOPs are patched to calls to this location.
|
||||
uint32_t debugTrapHandlerOffset_ = 0;
|
||||
|
||||
// The offsets of toggled jumps for debugger instrumentation.
|
||||
using CodeOffsetVector = Vector<uint32_t, 0, SystemAllocPolicy>;
|
||||
CodeOffsetVector debugInstrumentationOffsets_;
|
||||
|
@ -538,7 +542,7 @@ class BaselineInterpreter {
|
|||
uint32_t bailoutPrologueOffset,
|
||||
uint32_t generatorThrowOrReturnCallOffset,
|
||||
uint32_t profilerEnterToggleOffset,
|
||||
uint32_t profilerExitToggleOffset,
|
||||
uint32_t profilerExitToggleOffset, uint32_t debugTrapHandlerOffset,
|
||||
CodeOffsetVector&& debugInstrumentationOffsets,
|
||||
CodeOffsetVector&& debugTrapOffsets,
|
||||
CodeOffsetVector&& codeCoverageOffsets,
|
||||
|
|
Загрузка…
Ссылка в новой задаче