mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
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:
parent
e6fbf15029
commit
85db9b40c2
@ -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,
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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|.
|
||||
|
Loading…
Reference in New Issue
Block a user