Bug 1552154 part 5 - Stop using pc-to-native map for BaselineScript::toggleDebugTraps. r=tcampbell

Because DebugTrapEntries are only present if the script has debugger instrumentation
it should be fine to store this as a simple list of entries.

Differential Revision: https://phabricator.services.mozilla.com/D40948

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jan de Mooij 2019-08-10 10:21:20 +00:00
parent e6fbf15029
commit 85db9b40c2
4 changed files with 70 additions and 57 deletions

View File

@ -297,8 +297,9 @@ MethodStatus BaselineCompiler::compile() {
profilerEnterFrameToggleOffset_.offset(),
profilerExitFrameToggleOffset_.offset(),
handler.retAddrEntries().length(), handler.osrEntries().length(),
pcMappingIndexEntries.length(), pcEntries.length(),
script->resumeOffsets().size(), traceLoggerToggleOffsets_.length()),
debugTrapEntries_.length(), pcMappingIndexEntries.length(),
pcEntries.length(), script->resumeOffsets().size(),
traceLoggerToggleOffsets_.length()),
JS::DeletePolicy<BaselineScript>(cx->runtime()));
if (!baselineScript) {
ReportOutOfMemory(cx);
@ -320,6 +321,7 @@ MethodStatus BaselineCompiler::compile() {
baselineScript->copyRetAddrEntries(handler.retAddrEntries().begin());
baselineScript->copyOSREntries(handler.osrEntries().begin());
baselineScript->copyDebugTrapEntries(debugTrapEntries_.begin());
// If profiler instrumentation is enabled, toggle instrumentation on.
if (cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(
@ -1548,28 +1550,20 @@ bool BaselineCompiler::emitDebugTrap() {
bool enabled = DebugAPI::stepModeEnabled(script) ||
DebugAPI::hasBreakpointsAt(script, handler.pc());
#if defined(JS_CODEGEN_ARM64)
// Flush any pending constant pools to prevent incorrect
// PCMappingEntry offsets. See Bug 1446819.
masm.flush();
// Fix up the PCMappingEntry to avoid any constant pool.
pcMappingEntries_.back().nativeOffset = masm.currentOffset();
#endif
// Emit patchable call to debug trap handler.
JitCode* handlerCode = cx->runtime()->jitRuntime()->debugTrapHandler(
cx, DebugTrapHandlerKind::Compiler);
if (!handlerCode) {
return false;
}
mozilla::DebugOnly<CodeOffset> offset =
masm.toggledCall(handlerCode, enabled);
#ifdef DEBUG
// Patchable call offset has to match the pc mapping offset.
PCMappingEntry& entry = pcMappingEntries_.back();
MOZ_ASSERT((&offset)->offset() == entry.nativeOffset);
#endif
CodeOffset nativeOffset = masm.toggledCall(handlerCode, enabled);
uint32_t pcOffset = script->pcToOffset(handler.pc());
if (!debugTrapEntries_.emplaceBack(pcOffset, nativeOffset.offset())) {
ReportOutOfMemory(cx);
return false;
}
// Add a RetAddrEntry for the return offset -> pc mapping.
return handler.recordCallRetAddr(cx, RetAddrEntry::Kind::DebugTrap,

View File

@ -634,6 +634,12 @@ class BaselineCompiler final : private BaselineCompilerCodeGen {
// Native code offsets for bytecode ops in the script's resume offsets list.
ResumeOffsetEntryVector resumeOffsetEntries_;
// Native code offsets for debug traps if the script is compiled with debug
// instrumentation.
using DebugTrapEntryVector =
Vector<BaselineScript::DebugTrapEntry, 0, SystemAllocPolicy>;
DebugTrapEntryVector debugTrapEntries_;
CodeOffset profilerPushToggleOffset_;
CodeOffset traceLoggerScriptTextIdOffset_;

View File

@ -432,18 +432,18 @@ bool jit::BaselineCompileFromBaselineInterpreter(JSContext* cx,
MOZ_CRASH("Unexpected status");
}
BaselineScript* BaselineScript::New(JSScript* jsscript,
uint32_t warmUpCheckPrologueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
size_t retAddrEntries, size_t osrEntries,
size_t pcMappingIndexEntries,
size_t pcMappingSize, size_t resumeEntries,
size_t traceLoggerToggleOffsetEntries) {
BaselineScript* BaselineScript::New(
JSScript* jsscript, uint32_t warmUpCheckPrologueOffset,
uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset,
size_t retAddrEntries, size_t osrEntries, size_t debugTrapEntries,
size_t pcMappingIndexEntries, size_t pcMappingSize, size_t resumeEntries,
size_t traceLoggerToggleOffsetEntries) {
static const unsigned DataAlignment = sizeof(uintptr_t);
size_t retAddrEntriesSize = retAddrEntries * sizeof(RetAddrEntry);
size_t osrEntriesSize = osrEntries * sizeof(BaselineScript::OSREntry);
size_t debugTrapEntriesSize =
debugTrapEntries * sizeof(BaselineScript::DebugTrapEntry);
size_t pcMappingIndexEntriesSize =
pcMappingIndexEntries * sizeof(PCMappingIndexEntry);
size_t resumeEntriesSize = resumeEntries * sizeof(uintptr_t);
@ -452,6 +452,8 @@ BaselineScript* BaselineScript::New(JSScript* jsscript,
size_t paddedRetAddrEntriesSize =
AlignBytes(retAddrEntriesSize, DataAlignment);
size_t paddedOSREntriesSize = AlignBytes(osrEntriesSize, DataAlignment);
size_t paddedDebugTrapEntriesSize =
AlignBytes(debugTrapEntriesSize, DataAlignment);
size_t paddedPCMappingIndexEntriesSize =
AlignBytes(pcMappingIndexEntriesSize, DataAlignment);
size_t paddedPCMappingSize = AlignBytes(pcMappingSize, DataAlignment);
@ -459,6 +461,7 @@ BaselineScript* BaselineScript::New(JSScript* jsscript,
size_t paddedTLEntriesSize = AlignBytes(tlEntriesSize, DataAlignment);
size_t allocBytes = paddedRetAddrEntriesSize + paddedOSREntriesSize +
paddedDebugTrapEntriesSize +
paddedPCMappingIndexEntriesSize + paddedPCMappingSize +
paddedResumeEntriesSize + paddedTLEntriesSize;
@ -483,6 +486,10 @@ BaselineScript* BaselineScript::New(JSScript* jsscript,
script->osrEntries_ = osrEntries;
offsetCursor += paddedOSREntriesSize;
script->debugTrapEntriesOffset_ = offsetCursor;
script->debugTrapEntries_ = debugTrapEntries;
offsetCursor += paddedDebugTrapEntriesSize;
script->pcMappingIndexOffset_ = offsetCursor;
script->pcMappingIndexEntries_ = pcMappingIndexEntries;
offsetCursor += paddedPCMappingIndexEntriesSize;
@ -710,6 +717,10 @@ void BaselineScript::copyOSREntries(const OSREntry* entries) {
std::copy_n(entries, osrEntries().size(), osrEntries().data());
}
void BaselineScript::copyDebugTrapEntries(const DebugTrapEntry* entries) {
std::copy_n(entries, debugTrapEntries().size(), debugTrapEntries().data());
}
void BaselineScript::copyPCMappingEntries(const CompactBufferWriter& entries) {
MOZ_ASSERT(entries.length() > 0);
MOZ_ASSERT(entries.length() == pcMappingSize_);
@ -808,32 +819,20 @@ void BaselineScript::toggleDebugTraps(JSScript* script, jsbytecode* pc) {
AutoWritableJitCode awjc(method());
for (uint32_t i = 0; i < numPCMappingIndexEntries(); i++) {
PCMappingIndexEntry& entry = pcMappingIndexEntry(i);
for (const DebugTrapEntry& entry : debugTrapEntries()) {
jsbytecode* entryPC = script->offsetToPC(entry.pcOffset());
CompactBufferReader reader(pcMappingReader(i));
jsbytecode* curPC = script->offsetToPC(entry.pcOffset);
uint32_t nativeOffset = entry.nativeOffset;
MOZ_ASSERT(script->containsPC(curPC));
while (reader.more()) {
uint8_t b = reader.readByte();
if (b & 0x80) {
nativeOffset += reader.readUnsigned();
}
if (!pc || pc == curPC) {
bool enabled = DebugAPI::stepModeEnabled(script) ||
DebugAPI::hasBreakpointsAt(script, curPC);
// Patch the trap.
CodeLocationLabel label(method(), CodeOffset(nativeOffset));
Assembler::ToggleCall(label, enabled);
}
curPC += GetBytecodeLength(curPC);
// If the |pc| argument is non-null we can skip all other bytecode ops.
if (pc && pc != entryPC) {
continue;
}
bool enabled = DebugAPI::stepModeEnabled(script) ||
DebugAPI::hasBreakpointsAt(script, entryPC);
// Patch the trap.
CodeLocationLabel label(method(), CodeOffset(entry.nativeOffset()));
Assembler::ToggleCall(label, enabled);
}
}

View File

@ -251,6 +251,9 @@ struct BaselineScript final {
uint32_t osrEntriesOffset_ = 0;
uint32_t osrEntries_ = 0;
uint32_t debugTrapEntriesOffset_ = 0;
uint32_t debugTrapEntries_ = 0;
uint32_t pcMappingIndexOffset_ = 0;
uint32_t pcMappingIndexEntries_ = 0;
@ -286,6 +289,13 @@ struct BaselineScript final {
using BasePCToNativeEntry::BasePCToNativeEntry;
};
// Native code offset for a debug trap when the script is compiled with debug
// instrumentation.
class DebugTrapEntry : public BasePCToNativeEntry {
public:
using BasePCToNativeEntry::BasePCToNativeEntry;
};
private:
uint8_t flags_ = 0;
@ -317,6 +327,11 @@ struct BaselineScript final {
return mozilla::MakeSpan(offsetToPointer<OSREntry>(osrEntriesOffset_),
osrEntries_);
}
mozilla::Span<DebugTrapEntry> debugTrapEntries() const {
return mozilla::MakeSpan(
offsetToPointer<DebugTrapEntry>(debugTrapEntriesOffset_),
debugTrapEntries_);
}
#ifdef JS_TRACE_LOGGING
mozilla::Span<uint32_t> traceLoggerToggleOffsets() const {
@ -334,14 +349,12 @@ struct BaselineScript final {
}
public:
static BaselineScript* New(JSScript* jsscript,
uint32_t warmUpCheckPrologueOffset,
uint32_t profilerEnterToggleOffset,
uint32_t profilerExitToggleOffset,
size_t retAddrEntries, size_t osrEntries,
size_t pcMappingIndexEntries, size_t pcMappingSize,
size_t resumeEntries,
size_t traceLoggerToggleOffsetEntries);
static BaselineScript* New(
JSScript* jsscript, uint32_t warmUpCheckPrologueOffset,
uint32_t profilerEnterToggleOffset, uint32_t profilerExitToggleOffset,
size_t retAddrEntries, size_t osrEntries, size_t debugTrapEntries,
size_t pcMappingIndexEntries, size_t pcMappingSize, size_t resumeEntries,
size_t traceLoggerToggleOffsetEntries);
static void Trace(JSTracer* trc, BaselineScript* script);
static void Destroy(FreeOp* fop, BaselineScript* script);
@ -395,6 +408,7 @@ struct BaselineScript final {
void copyRetAddrEntries(const RetAddrEntry* entries);
void copyOSREntries(const OSREntry* entries);
void copyDebugTrapEntries(const DebugTrapEntry* entries);
// Copy resumeOffsets list from |script| and convert the pcOffsets
// to native addresses in the Baseline code based on |entries|.