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:
Jan de Mooij 2019-08-27 15:57:33 +00:00
Родитель 1072abd991
Коммит ee9632c4ba
4 изменённых файлов: 36 добавлений и 13 удалений

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

@ -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,