Bug 1725587 - SpiderMonkey `IONFLAGS=codegen` printing: hierarchical created-by markers. r=nbp.

This is an `#ifdef DEBUG` only patch and has no space or time effect on
non-debug builds.  It makes it easier to figure out which part of the SM suite
of code generators, stub generators, etc, created each instruction shown in
the `IONFLAGS=codegen` output.

In the base class of all assemblers, `js::jit::AssemblerShared`, there is a
new field `Vector<const char*> creators_`.  This is a small stack of arbitrary
strings.  Every time a string is pushed onto or popped off the stack, the
stack is printed in the `IONFLAGS=codegen` output.  Crucially, it is
debug-asserted that the stack is non-empty at emission of (almost) every
instruction.  Hence each instruction in the log output is bracketed within at
least one level of text-label.  By suitable choice of the labels, it is
possible to find which part of SM created an instruction with little
difficulty.

Pushing and popping the stack directly is strongly discouraged.  Instead, an
RAII `class AutoCreatedBy` is provided to manage the stack.  Adding
C++-scope-level annotations is then simply a matter of adding lines of the
form `AutoCreatedBy acb(masm, "my tag text");`.

The stacks resulting from the current annotation set have at most three
entries, for example:

  BaselineInterpreterGenerator::generate/interpreter loop/op=Uint24

The patch looks large but is really very simple.  There are the following
logical components, unfortunately interleaved in the patch:

* A large set of `AutoCreatedBy` annotations.  This gives complete coverage
  for code generation on x86, x64, arm, arm64 and mips64, as far as I can
  tell.  This is the vast majority of the patch.

* In `class AssemblerShared` (Assembler-shared.h), new field `creators_` and
  methods `{push,pop,has}Creator` to operate on it.

* Also in Assembler-shared.h, `class MOZ_RAII AutoCreatedBy`, to manage the
  stack.

* The assertions to ensure that the stack is not empty at emission of any
  instruction.

  - for arm64, this is done in `MozBaseAssembler::Emit` (two functions)

  - for arm, this is done in `Assembler::writeInst`

  - for mips64, this is done in `AssemblerMIPSShared::writeInst`

  - for x86 and x64 I failed to find any single place to put such an
    assertion, that also has convenient access to the required
    `AssemblerShared` base class.  Instead these have a best-effort solution:
    assertions have been added to around 20 methods in `AssemblerX86Shared`.
    These cover the most common instructions (loads, stores, reg-reg moves,
    pushes, pops, returns, immediate data, alignment directives).  Although
    this is not complete coverage, in practice it's good enough because it's
    almost impossible to create any piece of code without using at least one
    insn in that group.

Almost all of the implementation is guarded `#ifdef DEBUG`.  The one exception
is constructor `AutoCreatedBy::AutoCreatedBy`.  I did not want to uglify
dozens of places in SM with guards at all its use points.  So instead a dummy
release-build version has been provided:

  inline AutoCreatedBy(AssemblerShared& ash, const char* who) {}

on the basis that an optimising compiler will inline it away completely.

`AssemblerShared::pushCreator` ignores OOM conditions when pushing on the
stack.  This is assumed to be OK since this is a debug-build-only activity.

Differential Revision: https://phabricator.services.mozilla.com/D123854
This commit is contained in:
Julian Seward 2021-09-09 17:11:35 +00:00
Родитель c35fc5e1a3
Коммит 3294afd2f5
33 изменённых файлов: 372 добавлений и 11 удалений

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

@ -477,6 +477,12 @@ enum class AssembleResult {
// which needs a jit context.
jctx.emplace(cx, nullptr);
stack_masm.emplace();
#ifdef DEBUG
// It would be much preferable to use `class AutoCreatedBy` here, but we
// may be operating without an assembler at all if `useNativeCode` is
// `false`, so there's no place to put such a call.
stack_masm.ref().pushCreator("Assemble() in RegExpAPI.cpp");
#endif
uint32_t num_capture_registers = re->pairCount() * 2;
masm = MakeUnique<SMRegExpMacroAssembler>(cx, stack_masm.ref(), zone, mode,
num_capture_registers);
@ -532,6 +538,14 @@ enum class AssembleResult {
V8HandleString wrappedPattern(v8::internal::String(pattern), cx->isolate);
RegExpCompiler::CompilationResult result = compiler->Assemble(
cx->isolate, masm_ptr, data->node, data->capture_count, wrappedPattern);
if (useNativeCode) {
#ifdef DEBUG
// See comment referencing `pushCreator` above.
stack_masm.ref().popCreator();
#endif
}
if (!result.Succeeded()) {
MOZ_ASSERT(result.error == RegExpError::kTooLarge);
return AssembleResult::TooLarge;

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

@ -1117,6 +1117,9 @@ void SMRegExpMacroAssembler::stackOverflowHandler() {
return;
}
js::jit::AutoCreatedBy acb(masm_,
"SMRegExpMacroAssembler::stackOverflowHandler");
// Called if the backtrack-stack limit has been hit.
masm_.bind(&stack_overflow_label_);

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

@ -133,6 +133,8 @@ void BaselineCacheIRCompiler::tailCallVMInternal(MacroAssembler& masm,
}
JitCode* BaselineCacheIRCompiler::compile() {
AutoCreatedBy acb(masm, "BaselineCacheIRCompiler::compile");
#ifndef JS_USE_LINK_REGISTER
// The first value contains the return addres,
// which we pull into ICTailCallReg for tail calls.

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

@ -193,6 +193,8 @@ bool BaselineInterpreterHandler::addDebugInstrumentationOffset(
}
MethodStatus BaselineCompiler::compile() {
AutoCreatedBy acb(masm, "BaselineCompiler::compile");
JSScript* script = handler.script();
JitSpew(JitSpew_BaselineScripts, "Baseline compiling script %s:%u:%u (%p)",
script->filename(), script->lineno(), script->column(), script);
@ -241,6 +243,7 @@ MethodStatus BaselineCompiler::compile() {
return Method_Error;
}
AutoCreatedBy acb2(masm, "exception_tail");
Linker linker(masm);
if (masm.oom()) {
ReportOutOfMemory(cx);
@ -501,6 +504,9 @@ void BaselineInterpreterCodeGen::emitInitializeLocals() {
// void PostWriteBarrier(JSRuntime* rt, JSObject* obj);
template <typename Handler>
bool BaselineCodeGen<Handler>::emitOutOfLinePostBarrierSlot() {
AutoCreatedBy acb(masm,
"BaselineCodeGen<Handler>::emitOutOfLinePostBarrierSlot");
if (!postBarrierSlot_.used()) {
return true;
}
@ -592,6 +598,8 @@ static void CreateAllocSitesForICChain(JSScript* script, uint32_t entryIndex) {
template <>
bool BaselineCompilerCodeGen::emitNextIC() {
AutoCreatedBy acb(masm, "emitNextIC");
// Emit a call to an IC stored in JitScript. Calls to this must match the
// ICEntry order in JitScript: first the non-op IC entries for |this| and
// formal arguments, then the for-op IC entries for JOF_IC ops.
@ -6441,6 +6449,8 @@ bool BaselineInterpreterCodeGen::emit_ForceInterpreter() {
template <typename Handler>
bool BaselineCodeGen<Handler>::emitPrologue() {
AutoCreatedBy acb(masm, "BaselineCodeGen<Handler>::emitPrologue");
#ifdef JS_USE_LINK_REGISTER
// Push link register from generateEnterJIT()'s BLR.
masm.pushReturnAddress();
@ -6510,6 +6520,8 @@ bool BaselineCodeGen<Handler>::emitPrologue() {
template <typename Handler>
bool BaselineCodeGen<Handler>::emitEpilogue() {
AutoCreatedBy acb(masm, "BaselineCodeGen<Handler>::emitEpilogue");
masm.bind(&return_);
if (!handler.shouldEmitDebugEpilogueAtReturnOp()) {
@ -6534,6 +6546,8 @@ bool BaselineCodeGen<Handler>::emitEpilogue() {
}
MethodStatus BaselineCompiler::emitBody() {
AutoCreatedBy acb(masm, "BaselineCompiler::emitBody");
JSScript* script = handler.script();
MOZ_ASSERT(handler.pc() == script->code());
@ -6594,9 +6608,10 @@ MethodStatus BaselineCompiler::emitBody() {
}
#define EMIT_OP(OP, ...) \
case JSOp::OP: \
case JSOp::OP: { \
AutoCreatedBy acb(masm, "op=" #OP); \
if (MOZ_UNLIKELY(!this->emit_##OP())) return Method_Error; \
break;
} break;
switch (op) {
FOR_EACH_OPCODE(EMIT_OP)
@ -6639,6 +6654,8 @@ static constexpr Register InterpreterPCRegAtDispatch =
HasInterpreterPCReg() ? InterpreterPCReg : R0.scratchReg();
bool BaselineInterpreterGenerator::emitInterpreterLoop() {
AutoCreatedBy acb(masm, "BaselineInterpreterGenerator::emitInterpreterLoop");
Register scratch1 = R0.scratchReg();
Register scratch2 = R1.scratchReg();
@ -6713,6 +6730,7 @@ bool BaselineInterpreterGenerator::emitInterpreterLoop() {
Label opLabels[JSOP_LIMIT];
#define EMIT_OP(OP, ...) \
{ \
AutoCreatedBy acb(masm, "op=" #OP); \
masm.bind(&opLabels[uint8_t(JSOp::OP)]); \
handler.setCurrentOp(JSOp::OP); \
if (!this->emit_##OP()) { \
@ -6782,6 +6800,10 @@ bool BaselineInterpreterGenerator::emitInterpreterLoop() {
}
void BaselineInterpreterGenerator::emitOutOfLineCodeCoverageInstrumentation() {
AutoCreatedBy acb(masm,
"BaselineInterpreterGenerator::"
"emitOutOfLineCodeCoverageInstrumentation");
masm.bind(handler.codeCoverageAtPrologueLabel());
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
@ -6818,6 +6840,8 @@ void BaselineInterpreterGenerator::emitOutOfLineCodeCoverageInstrumentation() {
}
bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
AutoCreatedBy acb(masm, "BaselineInterpreterGenerator::generate");
if (!emitPrologue()) {
return false;
}
@ -6837,6 +6861,7 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
emitOutOfLineCodeCoverageInstrumentation();
{
AutoCreatedBy acb(masm, "everything_else");
Linker linker(masm);
if (masm.oom()) {
ReportOutOfMemory(cx);
@ -6902,6 +6927,7 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
JitCode* JitRuntime::generateDebugTrapHandler(JSContext* cx,
DebugTrapHandlerKind kind) {
StackMacroAssembler masm;
AutoCreatedBy acb(masm, "JitRuntime::generateDebugTrapHandler");
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.takeUnchecked(BaselineFrameReg);

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

@ -2431,6 +2431,7 @@ bool FallbackICCodeCompiler::emit_NewObject() {
bool JitRuntime::generateBaselineICFallbackCode(JSContext* cx) {
StackMacroAssembler masm;
AutoCreatedBy acb(masm, "JitRuntime::generateBaselineICFallbackCode");
BaselineICFallbackCode& fallbackCode = baselineICFallbackCode_.ref();
FallbackICCodeCompiler compiler(cx, fallbackCode, masm);
@ -2439,6 +2440,7 @@ bool JitRuntime::generateBaselineICFallbackCode(JSContext* cx) {
#define EMIT_CODE(kind) \
{ \
AutoCreatedBy acb(masm, "kind=" #kind); \
uint32_t offset = startTrampolineCode(masm); \
InitMacroAssemblerForICStub(masm); \
if (!compiler.emit_##kind()) { \

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

@ -2554,6 +2554,7 @@ JitCode* JitRealm::generateRegExpMatcherStub(JSContext* cx) {
gc::GetGCKindSlots(templateObj.getAllocKind()));
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, "JitRealm::generateRegExpMatcherStub");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
@ -2893,6 +2894,7 @@ JitCode* JitRealm::generateRegExpSearcherStub(JSContext* cx) {
Register temp3 = regs.takeAny();
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, "JitRealm::generateRegExpSearcherStub");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
@ -3057,6 +3059,7 @@ JitCode* JitRealm::generateRegExpTesterStub(JSContext* cx) {
Register result = ReturnReg;
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, "JitRealm::generateRegExpTesterStub");
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
@ -6513,6 +6516,8 @@ void CodeGenerator::emitDebugForceBailing(LInstruction* lir) {
bool CodeGenerator::generateBody() {
JitSpewCont(JitSpew_Codegen, "\n");
AutoCreatedBy acb(masm, "CodeGenerator::generateBody");
JitSpew(JitSpew_Codegen, "==== BEGIN CodeGenerator::generateBody ====");
IonScriptCounts* counts = maybeCreateScriptCounts();
@ -10080,6 +10085,7 @@ JitCode* JitRealm::generateStringConcatStub(JSContext* cx) {
JitSpew(JitSpew_Codegen, "# Emitting StringConcat stub");
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, "JitRealm::generateStringConcatStub");
Register lhs = CallTempReg0;
Register rhs = CallTempReg1;
@ -10186,6 +10192,8 @@ JitCode* JitRealm::generateStringConcatStub(JSContext* cx) {
}
void JitRuntime::generateFreeStub(MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateFreeStub");
const Register regSlots = CallTempReg0;
freeStubOffset_ = startTrampolineCode(masm);
@ -10213,6 +10221,8 @@ void JitRuntime::generateFreeStub(MacroAssembler& masm) {
}
void JitRuntime::generateLazyLinkStub(MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateLazyLinkStub");
lazyLinkStubOffset_ = startTrampolineCode(masm);
#ifdef JS_USE_LINK_REGISTER
@ -10246,6 +10256,8 @@ void JitRuntime::generateLazyLinkStub(MacroAssembler& masm) {
}
void JitRuntime::generateInterpreterStub(MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateInterpreterStub");
interpreterStubOffset_ = startTrampolineCode(masm);
#ifdef JS_USE_LINK_REGISTER
@ -10280,6 +10292,7 @@ void JitRuntime::generateInterpreterStub(MacroAssembler& masm) {
}
void JitRuntime::generateDoubleToInt32ValueStub(MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateDoubleToInt32ValueStub");
doubleToInt32ValueStubOffset_ = startTrampolineCode(masm);
Label done;
@ -11416,6 +11429,8 @@ bool CodeGenerator::generateWasm(wasm::TypeIdDesc funcTypeId,
size_t trapExitLayoutNumWords,
wasm::FuncOffsets* offsets,
wasm::StackMaps* stackMaps) {
AutoCreatedBy acb(masm, "CodeGenerator::generateWasm");
JitSpew(JitSpew_Codegen, "# Emitting wasm code");
setUseWasmStackArgumentAbi();
@ -11515,6 +11530,8 @@ bool CodeGenerator::generateWasm(wasm::TypeIdDesc funcTypeId,
}
bool CodeGenerator::generate() {
AutoCreatedBy acb(masm, "CodeGenerator::generate");
JitSpew(JitSpew_Codegen, "# Emitting code for script %s:%u:%u",
gen->outerInfo().script()->filename(),
gen->outerInfo().script()->lineno(),
@ -11623,6 +11640,8 @@ static bool AddInlinedCompilations(JSContext* cx, HandleScript script,
}
bool CodeGenerator::link(JSContext* cx, const WarpSnapshot* snapshot) {
AutoCreatedBy acb(masm, "CodeGenerator::link");
// We cancel off-thread Ion compilations in a few places during GC, but if
// this compilation was performed off-thread it will already have been
// removed from the relevant lists by this point. Don't allow GC here.

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

@ -93,6 +93,8 @@ JitRuntime::~JitRuntime() {
}
uint32_t JitRuntime::startTrampolineCode(MacroAssembler& masm) {
AutoCreatedBy acb(masm, "startTrampolineCode");
masm.assumeUnreachable("Shouldn't get here");
masm.flushBuffer();
masm.haltingAlign(CodeAlignment);

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

@ -531,6 +531,8 @@ bool IonCacheIRCompiler::init() {
}
JitCode* IonCacheIRCompiler::compile(IonICStub* stub) {
AutoCreatedBy acb(masm, "IonCacheIRCompiler::compile");
masm.setFramePushed(ionScript_->frameSize());
if (cx_->runtime()->geckoProfiler().enabled()) {
masm.enableProfilingInstrumentation();

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

@ -1338,6 +1338,7 @@ class Assembler : public AssemblerShared {
// Write a single instruction into the instruction stream. Very hot,
// inlined for performance
MOZ_ALWAYS_INLINE BufferOffset writeInst(uint32_t x) {
MOZ_ASSERT(hasCreator());
BufferOffset offs = m_buffer.putInt(x);
#ifdef JS_DISASM_ARM
spew(m_buffer.getInstOrNull(offs));

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

@ -100,6 +100,8 @@ struct EnterJITStack {
* ...using standard EABI calling convention
*/
void JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateEnterJIT");
enterJITOffset_ = startTrampolineCode(masm);
const Address slot_token(sp, offsetof(EnterJITStack, token));
@ -380,6 +382,8 @@ JitRuntime::getCppEntryRegisters(JitFrameLayout* frameStackAddress) {
void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
// See large comment in x86's JitRuntime::generateInvalidator.
AutoCreatedBy acb(masm, "JitRuntime::generateInvalidator");
invalidatorOffset_ = startTrampolineCode(masm);
// At this point, one of two things has happened:
@ -454,6 +458,8 @@ void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
void JitRuntime::generateArgumentsRectifier(MacroAssembler& masm,
ArgumentsRectifierKind kind) {
AutoCreatedBy acb(masm, "JitRuntime::generateArgumentsRectifier");
switch (kind) {
case ArgumentsRectifierKind::Normal:
argumentsRectifierOffset_ = startTrampolineCode(masm);
@ -726,6 +732,8 @@ static void GenerateBailoutThunk(MacroAssembler& masm, uint32_t frameClass,
JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
Label* bailoutTail,
uint32_t frameClass) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTable");
uint32_t offset = startTrampolineCode(masm);
{
@ -745,6 +753,8 @@ JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutHandler");
bailoutHandlerOffset_ = startTrampolineCode(masm);
GenerateBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID, bailoutTail);
@ -753,6 +763,8 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, DynFn nativeFun,
uint32_t* wrapperOffset) {
AutoCreatedBy acb(masm, "JitRuntime::generateVMWrapper");
*wrapperOffset = startTrampolineCode(masm);
AllocatableGeneralRegisterSet regs(Register::Codes::WrapperMask);
@ -944,6 +956,8 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type) {
AutoCreatedBy acb(masm, "JitRuntime::generatePreBarrier");
uint32_t offset = startTrampolineCode(masm);
masm.pushReturnAddress();
@ -996,6 +1010,8 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateExceptionTailStub");
exceptionTailOffset_ = startTrampolineCode(masm);
masm.bind(masm.failureLabel());
@ -1004,6 +1020,8 @@ void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTailStub");
bailoutTailOffset_ = startTrampolineCode(masm);
masm.bind(bailoutTail);
@ -1012,6 +1030,8 @@ void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateProfilerExitFrameTailStub");
profilerExitFrameTailOffset_ = startTrampolineCode(masm);
masm.bind(profilerExitTail);

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

@ -40,6 +40,8 @@ CodeGeneratorARM64::CodeGeneratorARM64(MIRGenerator* gen, LIRGraph* graph,
: CodeGeneratorShared(gen, graph, masm) {}
bool CodeGeneratorARM64::generateOutOfLineCode() {
AutoCreatedBy acb(masm, "CodeGeneratorARM64::generateOutOfLineCode");
if (!CodeGeneratorShared::generateOutOfLineCode()) {
return false;
}

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

@ -29,6 +29,8 @@ using namespace js::jit;
* ...using standard AArch64 calling convention
*/
void JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateEnterJIT");
enterJITOffset_ = startTrampolineCode(masm);
const Register reg_code = IntArgReg0; // EnterJitData::jitcode.
@ -357,6 +359,8 @@ static void PushRegisterDump(MacroAssembler& masm) {
}
void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateInvalidator");
invalidatorOffset_ = startTrampolineCode(masm);
// The InvalidationBailoutStack saved in r0 must be:
@ -394,6 +398,8 @@ void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
void JitRuntime::generateArgumentsRectifier(MacroAssembler& masm,
ArgumentsRectifierKind kind) {
AutoCreatedBy acb(masm, "JitRuntime::generateArgumentsRectifier");
switch (kind) {
case ArgumentsRectifierKind::Normal:
argumentsRectifierOffset_ = startTrampolineCode(masm);
@ -588,6 +594,8 @@ JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutHandler");
bailoutHandlerOffset_ = startTrampolineCode(masm);
GenerateBailoutThunk(masm, bailoutTail);
@ -596,6 +604,8 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, DynFn nativeFun,
uint32_t* wrapperOffset) {
AutoCreatedBy acb(masm, "JitRuntime::generateVMWrapper");
*wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after
@ -798,6 +808,8 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type) {
AutoCreatedBy acb(masm, "JitRuntime::generatePreBarrier");
uint32_t offset = startTrampolineCode(masm);
static_assert(PreBarrierReg == r1);
@ -848,6 +860,8 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateExceptionTailStub");
exceptionTailOffset_ = startTrampolineCode(masm);
masm.bind(masm.failureLabel());
@ -856,6 +870,8 @@ void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTailStub");
bailoutTailOffset_ = startTrampolineCode(masm);
masm.bind(bailoutTail);
@ -864,6 +880,8 @@ void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateProfilerExitFrameTailStub");
profilerExitFrameTailOffset_ = startTrampolineCode(masm);
masm.bind(profilerExitTail);

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

@ -249,6 +249,7 @@ class MozBaseAssembler : public js::jit::AssemblerShared {
static_assert(sizeof(instruction) == kInstructionSize);
// TODO: isBranch is obsolete and should be removed.
(void)isBranch;
MOZ_ASSERT(hasCreator());
BufferOffset offs = armbuffer_.putInt(*(uint32_t*)(&instruction));
#ifdef JS_DISASM_ARM64
if (!isBranch)
@ -280,6 +281,7 @@ class MozBaseAssembler : public js::jit::AssemblerShared {
// Emit data inline in the instruction stream.
BufferOffset EmitData(void const * data, unsigned size) {
VIXL_ASSERT(size % 4 == 0);
MOZ_ASSERT(hasCreator());
return armbuffer_.allocEntry(size / sizeof(uint32_t), 0, (uint8_t*)(data), nullptr);
}

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

@ -209,6 +209,7 @@ size_t AssemblerMIPSShared::bytesNeeded() const {
// write a blob of binary into the instruction stream
BufferOffset AssemblerMIPSShared::writeInst(uint32_t x, uint32_t* dest) {
MOZ_ASSERT(hasCreator());
if (dest == nullptr) {
return m_buffer.putInt(x);
}

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

@ -152,6 +152,8 @@ static void GeneratePrologue(MacroAssembler& masm) {
// The trampoline use the EnterJitCode signature, with the standard x64 fastcall
// calling convention.
void JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateEnterJIT");
enterJITOffset_ = startTrampolineCode(masm);
const Register reg_code = IntArgReg0;
@ -387,6 +389,8 @@ JitRuntime::getCppEntryRegisters(JitFrameLayout* frameStackAddress) {
}
void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateInvalidator");
invalidatorOffset_ = startTrampolineCode(masm);
// Stack has to be alligned here. If not, we will have to fix it.
@ -433,6 +437,8 @@ void JitRuntime::generateArgumentsRectifier(MacroAssembler& masm,
ArgumentsRectifierKind kind) {
// Do not erase the frame pointer in this function.
AutoCreatedBy acb(masm, "JitRuntime::generateArgumentsRectifier");
switch (kind) {
case ArgumentsRectifierKind::Normal:
argumentsRectifierOffset_ = startTrampolineCode(masm);
@ -696,6 +702,8 @@ JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutHandler");
bailoutHandlerOffset_ = startTrampolineCode(masm);
GenerateBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID, bailoutTail);
@ -704,6 +712,8 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, DynFn nativeFun,
uint32_t* wrapperOffset) {
AutoCreatedBy acb(masm, "JitRuntime::generateVMWrapper");
*wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after
@ -887,6 +897,8 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type) {
AutoCreatedBy acb(masm, "JitRuntime::generatePreBarrier");
uint32_t offset = startTrampolineCode(masm);
MOZ_ASSERT(PreBarrierReg == a1);
@ -939,6 +951,8 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateExceptionTailStub");
exceptionTailOffset_ = startTrampolineCode(masm);
masm.bind(masm.failureLabel());
@ -947,6 +961,8 @@ void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTailStub");
bailoutTailOffset_ = startTrampolineCode(masm);
masm.bind(bailoutTail);
@ -955,6 +971,8 @@ void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateProfilerExitFrameTailStub");
profilerExitFrameTailOffset_ = startTrampolineCode(masm);
masm.bind(profilerExitTail);

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

@ -6,6 +6,7 @@
#include "jit/shared/Assembler-shared.h"
#include "jit/JitSpewer.h"
#include "vm/NativeObject.h"
namespace js::jit {
@ -18,4 +19,56 @@ void BaseObjectSlotIndex::staticAssertions() {
NativeObject::slotsSizeMustNotOverflow();
}
AssemblerShared::~AssemblerShared() {
#ifdef DEBUG
while (hasCreator()) {
popCreator();
}
#endif
}
#ifdef DEBUG
void AssemblerShared::pushCreator(const char* who) {
(void)creators_.append(who);
JitSpewStart(JitSpew_Codegen, "# BEGIN creators: ");
bool first = true;
for (const char* str : creators_) {
JitSpewCont(JitSpew_Codegen, "%s%s", first ? "" : "/", str);
first = false;
}
JitSpewCont(JitSpew_Codegen, "\n");
}
void AssemblerShared::popCreator() {
JitSpewStart(JitSpew_Codegen, "# END creators: ");
bool first = true;
for (const char* str : creators_) {
JitSpewCont(JitSpew_Codegen, "%s%s", first ? "" : "/", str);
first = false;
}
JitSpewCont(JitSpew_Codegen, "\n");
if (creators_.empty()) {
JitSpew(JitSpew_Codegen, " ");
}
MOZ_ASSERT(!creators_.empty());
creators_.popBack();
}
bool AssemblerShared::hasCreator() const {
// If you get failures of assertions of the form `MOZ_ASSERT(hasCreator())`,
// what this means is that a `MacroAssembler` (or, really, anything that
// inherits from `js::jit::AssemblerShared`) has emitted code or data from a
// place, in the SM C++ hierarchy, that is not nested within an
// `AutoCreatedBy` RAII scope. Consequently the emitted instructions/data
// won't have any owner that is identifiable in the `IONFLAGS=codegen`
// output.
//
// Fixing this is easy: work back up the crash stack and decide on a place
// to put an `AutoCreatedBy` call. A bit of grepping for `AutoCreatedBy`
// should make it obvious what to do. If in doubt, add `AutoCreatedBy`
// calls liberally; "extra" ones are harmless.
return !creators_.empty();
}
#endif
} // namespace js::jit

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

@ -578,6 +578,14 @@ class AssemblerShared {
#ifdef ENABLE_WASM_EXCEPTIONS
wasm::WasmTryNoteVector tryNotes_;
#endif
#ifdef DEBUG
// To facilitate figuring out which part of SM created each instruction as
// shown by IONFLAGS=codegen, this maintains a stack of (notionally)
// code-creating routines, which is printed in the log output every time an
// entry is pushed or popped. Do not push/pop entries directly; instead use
// `class AutoCreatedBy`.
mozilla::Vector<const char*> creators_;
#endif
protected:
CodeLabelVector codeLabels_;
@ -588,6 +596,17 @@ class AssemblerShared {
public:
AssemblerShared() : enoughMemory_(true), embedsNurseryPointers_(false) {}
~AssemblerShared();
#ifdef DEBUG
// Do not use these directly; instead use `class AutoCreatedBy`.
void pushCreator(const char*);
void popCreator();
// See comment on the implementation of `hasCreator` for guidance on what to
// do if you get failures of the assertion `MOZ_ASSERT(hasCreator())`,
bool hasCreator() const;
#endif
void propagateOOM(bool success) { enoughMemory_ &= success; }
void setOOM() { enoughMemory_ = false; }
@ -643,6 +662,30 @@ class AssemblerShared {
#endif
};
// AutoCreatedBy pushes and later pops a who-created-these-insns? tag into the
// JitSpew_Codegen output. These could be created fairly frequently, so a
// dummy inlineable-out version is provided for non-debug builds. The tag
// text can be completely arbitrary -- it serves only to help readers of the
// output text to relate instructions back to the part(s) of SM that created
// them.
#ifdef DEBUG
class MOZ_RAII AutoCreatedBy {
private:
AssemblerShared& ash_;
public:
AutoCreatedBy(AssemblerShared& ash, const char* who) : ash_(ash) {
ash_.pushCreator(who);
}
~AutoCreatedBy() { ash_.popCreator(); }
};
#else
class MOZ_RAII AutoCreatedBy {
public:
inline AutoCreatedBy(AssemblerShared& ash, const char* who) {}
};
#endif
} // namespace jit
} // namespace js

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

@ -760,6 +760,7 @@ bool InitializeJittedAtomics() {
TempAllocator alloc(&lifo);
JitContext jcx(&alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, "InitializeJittedAtomics");
uint32_t fenceSeqCst = GenFenceSeqCst(masm);

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

@ -163,6 +163,8 @@ bool CodeGeneratorShared::generateEpilogue() {
}
bool CodeGeneratorShared::generateOutOfLineCode() {
AutoCreatedBy acb(masm, "CodeGeneratorShared::generateOutOfLineCode");
// OOL paths should not attempt to use |current| as it's the last block
// instead of the block corresponding to the OOL path.
current = nullptr;

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

@ -140,6 +140,8 @@ void Assembler::finish() {
return;
}
AutoCreatedBy acb(*this, "Assembler::finish");
if (!extendedJumps_.length()) {
// Since we may be folowed by non-executable data, eagerly insert an
// undefined instruction byte to prevent processors from decoding
@ -157,6 +159,7 @@ void Assembler::finish() {
#ifdef DEBUG
size_t oldSize = masm.size();
#endif
MOZ_ASSERT(hasCreator());
masm.jmp_rip(2);
MOZ_ASSERT_IF(!masm.oom(), masm.size() - oldSize == 6);
// Following an indirect branch with ud2 hints to the hardware that

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

@ -1140,6 +1140,7 @@ class Assembler : public AssemblerX86Shared {
}
void jmp(ImmPtr target, RelocationKind reloc = RelocationKind::HARDCODED) {
MOZ_ASSERT(hasCreator());
JmpSrc src = masm.jmp();
addPendingJump(src, target, reloc);
}

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

@ -75,6 +75,8 @@ static const LiveRegisterSet AllRegs =
// The trampoline use the EnterJitCode signature, with the standard x64 fastcall
// calling convention.
void JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateEnterJIT");
enterJITOffset_ = startTrampolineCode(masm);
masm.assertStackAlignment(ABIStackAlignment,
@ -430,6 +432,8 @@ static void DumpAllRegs(MacroAssembler& masm) {
}
void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateInvalidator");
// See explanatory comment in x86's JitRuntime::generateInvalidator.
invalidatorOffset_ = startTrampolineCode(masm);
@ -470,6 +474,8 @@ void JitRuntime::generateArgumentsRectifier(MacroAssembler& masm,
ArgumentsRectifierKind kind) {
// Do not erase the frame pointer in this function.
AutoCreatedBy acb(masm, "JitRuntime::generateArgumentsRectifier");
switch (kind) {
case ArgumentsRectifierKind::Normal:
argumentsRectifierOffset_ = startTrampolineCode(masm);
@ -693,6 +699,8 @@ JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutHandler");
bailoutHandlerOffset_ = startTrampolineCode(masm);
GenerateBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID, bailoutTail);
@ -701,6 +709,8 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, DynFn nativeFun,
uint32_t* wrapperOffset) {
AutoCreatedBy acb(masm, "JitRuntime::generateVMWrapper");
*wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after
@ -879,6 +889,8 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type) {
AutoCreatedBy acb(masm, "JitRuntime::generatePreBarrier");
uint32_t offset = startTrampolineCode(masm);
static_assert(PreBarrierReg == rdx);
@ -924,6 +936,8 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateExceptionTailStub");
exceptionTailOffset_ = startTrampolineCode(masm);
masm.bind(masm.failureLabel());
@ -932,6 +946,8 @@ void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTailStub");
bailoutTailOffset_ = startTrampolineCode(masm);
masm.bind(bailoutTail);
@ -940,6 +956,8 @@ void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateProfilerExitFrameTailStub");
profilerExitFrameTailOffset_ = startTrampolineCode(masm);
masm.bind(profilerExitTail);

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

@ -455,9 +455,16 @@ class AssemblerX86Shared : public AssemblerShared {
}
public:
void haltingAlign(int alignment) { masm.haltingAlign(alignment); }
void nopAlign(int alignment) { masm.nopAlign(alignment); }
void haltingAlign(int alignment) {
MOZ_ASSERT(hasCreator());
masm.haltingAlign(alignment);
}
void nopAlign(int alignment) {
MOZ_ASSERT(hasCreator());
masm.nopAlign(alignment);
}
void writeCodePointer(CodeLabel* label) {
MOZ_ASSERT(hasCreator());
// Use -1 as dummy value. This will be patched after codegen.
masm.jumpTablePointer(-1);
label->patchAt()->bind(masm.size());
@ -490,12 +497,15 @@ class AssemblerX86Shared : public AssemblerShared {
cmovCCl(Condition::NonZero, src, dest);
}
void movl(Imm32 imm32, Register dest) {
MOZ_ASSERT(hasCreator());
masm.movl_i32r(imm32.value, dest.encoding());
}
void movl(Register src, Register dest) {
MOZ_ASSERT(hasCreator());
masm.movl_rr(src.encoding(), dest.encoding());
}
void movl(const Operand& src, Register dest) {
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::REG:
masm.movl_rr(src.reg(), dest.encoding());
@ -515,6 +525,7 @@ class AssemblerX86Shared : public AssemblerShared {
}
}
void movl(Register src, const Operand& dest) {
MOZ_ASSERT(hasCreator());
switch (dest.kind()) {
case Operand::REG:
masm.movl_rr(src.encoding(), dest.reg());
@ -646,6 +657,7 @@ class AssemblerX86Shared : public AssemblerShared {
src.scale, dest.encoding());
}
void vmovsd(const Operand& src, FloatRegister dest) {
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::MEM_REG_DISP:
vmovsd(src.toAddress(), dest);
@ -676,6 +688,7 @@ class AssemblerX86Shared : public AssemblerShared {
src.scale, dest.encoding());
}
void vmovss(const Operand& src, FloatRegister dest) {
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::MEM_REG_DISP:
vmovss(src.toAddress(), dest);
@ -712,6 +725,7 @@ class AssemblerX86Shared : public AssemblerShared {
}
void vmovdqu(const Operand& src, FloatRegister dest) {
MOZ_ASSERT(HasSSE2());
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::MEM_REG_DISP:
masm.vmovdqu_mr(src.disp(), src.base(), dest.encoding());
@ -726,6 +740,7 @@ class AssemblerX86Shared : public AssemblerShared {
}
void vmovdqu(FloatRegister src, const Operand& dest) {
MOZ_ASSERT(HasSSE2());
MOZ_ASSERT(hasCreator());
switch (dest.kind()) {
case Operand::MEM_REG_DISP:
masm.vmovdqu_rm(src.encoding(), dest.disp(), dest.base());
@ -987,12 +1002,25 @@ class AssemblerX86Shared : public AssemblerShared {
}
public:
void nop() { masm.nop(); }
void nop(size_t n) { masm.insert_nop(n); }
void j(Condition cond, Label* label) { jSrc(cond, label); }
void jmp(Label* label) { jmpSrc(label); }
void nop() {
MOZ_ASSERT(hasCreator());
masm.nop();
}
void nop(size_t n) {
MOZ_ASSERT(hasCreator());
masm.insert_nop(n);
}
void j(Condition cond, Label* label) {
MOZ_ASSERT(hasCreator());
jSrc(cond, label);
}
void jmp(Label* label) {
MOZ_ASSERT(hasCreator());
jmpSrc(label);
}
void jmp(const Operand& op) {
MOZ_ASSERT(hasCreator());
switch (op.kind()) {
case Operand::MEM_REG_DISP:
masm.jmp_m(op.disp(), op.base());
@ -1060,8 +1088,12 @@ class AssemblerX86Shared : public AssemblerShared {
}
}
void ret() { masm.ret(); }
void ret() {
MOZ_ASSERT(hasCreator());
masm.ret();
}
void retn(Imm32 n) {
MOZ_ASSERT(hasCreator());
// Remove the size of the return address which is included in the frame.
masm.ret_i(n.value - sizeof(void*));
}
@ -1123,6 +1155,7 @@ class AssemblerX86Shared : public AssemblerShared {
void breakpoint() { masm.int3(); }
CodeOffset ud2() {
MOZ_ASSERT(hasCreator());
CodeOffset off(masm.currentOffset());
masm.ud2();
return off;
@ -2162,6 +2195,7 @@ class AssemblerX86Shared : public AssemblerShared {
void push(const Imm32 imm) { masm.push_i(imm.value); }
void push(const Operand& src) {
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::REG:
masm.push_r(src.reg());
@ -2176,12 +2210,16 @@ class AssemblerX86Shared : public AssemblerShared {
MOZ_CRASH("unexpected operand kind");
}
}
void push(Register src) { masm.push_r(src.encoding()); }
void push(Register src) {
MOZ_ASSERT(hasCreator());
masm.push_r(src.encoding());
}
void push(const Address& src) {
masm.push_m(src.offset, src.base.encoding());
}
void pop(const Operand& src) {
MOZ_ASSERT(hasCreator());
switch (src.kind()) {
case Operand::REG:
masm.pop_r(src.reg());
@ -2193,7 +2231,10 @@ class AssemblerX86Shared : public AssemblerShared {
MOZ_CRASH("unexpected operand kind");
}
}
void pop(Register src) { masm.pop_r(src.encoding()); }
void pop(Register src) {
MOZ_ASSERT(hasCreator());
masm.pop_r(src.encoding());
}
void pop(const Address& src) { masm.pop_m(src.offset, src.base.encoding()); }
void pushFlags() { masm.push_flags(); }

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

@ -54,6 +54,8 @@ enum EnterJitEbpArgumentOffset {
// The trampoline use the EnterJitCode signature, with the standard cdecl
// calling convention.
void JitRuntime::generateEnterJIT(JSContext* cx, MacroAssembler& masm) {
AutoCreatedBy acb(masm, "JitRuntime::generateEnterJIT");
enterJITOffset_ = startTrampolineCode(masm);
masm.assertStackAlignment(ABIStackAlignment,
@ -351,6 +353,8 @@ static void DumpAllRegs(MacroAssembler& masm) {
}
void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateInvalidator");
invalidatorOffset_ = startTrampolineCode(masm);
// We do the minimum amount of work in assembly and shunt the rest
@ -396,6 +400,8 @@ void JitRuntime::generateInvalidator(MacroAssembler& masm, Label* bailoutTail) {
void JitRuntime::generateArgumentsRectifier(MacroAssembler& masm,
ArgumentsRectifierKind kind) {
AutoCreatedBy acb(masm, "JitRuntime::generateArgumentsRectifier");
switch (kind) {
case ArgumentsRectifierKind::Normal:
argumentsRectifierOffset_ = startTrampolineCode(masm);
@ -634,6 +640,8 @@ static void GenerateBailoutThunk(MacroAssembler& masm, uint32_t frameClass,
JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
Label* bailoutTail,
uint32_t frameClass) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTable");
uint32_t offset = startTrampolineCode(masm);
Label bailout;
@ -649,6 +657,8 @@ JitRuntime::BailoutTable JitRuntime::generateBailoutTable(MacroAssembler& masm,
void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutHandler");
bailoutHandlerOffset_ = startTrampolineCode(masm);
GenerateBailoutThunk(masm, NO_FRAME_SIZE_CLASS_ID, bailoutTail);
@ -657,6 +667,8 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
const VMFunctionData& f, DynFn nativeFun,
uint32_t* wrapperOffset) {
AutoCreatedBy acb(masm, "JitRuntime::generateVMWrapper");
*wrapperOffset = startTrampolineCode(masm);
// Avoid conflicts with argument registers while discarding the result after
@ -837,6 +849,8 @@ bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type) {
AutoCreatedBy acb(masm, "JitRuntime::generatePreBarrier");
uint32_t offset = startTrampolineCode(masm);
static_assert(PreBarrierReg == edx);
@ -887,6 +901,8 @@ uint32_t JitRuntime::generatePreBarrier(JSContext* cx, MacroAssembler& masm,
void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateExceptionTailStub");
exceptionTailOffset_ = startTrampolineCode(masm);
masm.bind(masm.failureLabel());
@ -895,6 +911,8 @@ void JitRuntime::generateExceptionTailStub(MacroAssembler& masm,
void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
Label* bailoutTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateBailoutTailStub");
bailoutTailOffset_ = startTrampolineCode(masm);
masm.bind(bailoutTail);
@ -903,6 +921,8 @@ void JitRuntime::generateBailoutTailStub(MacroAssembler& masm,
void JitRuntime::generateProfilerExitFrameTailStub(MacroAssembler& masm,
Label* profilerExitTail) {
AutoCreatedBy acb(masm, "JitRuntime::generateProfilerExitFrameTailStub");
profilerExitFrameTailOffset_ = startTrampolineCode(masm);
masm.bind(profilerExitTail);

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

@ -525,6 +525,7 @@ BEGIN_TEST(testAssemblerBuffer_ARM64) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
// Branches to an unbound label.
Label lab1;

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

@ -635,6 +635,7 @@ class JitABICall final : public JSAPITest, public DefineCheckArgs<Sig> {
this->set_instance(this, &result);
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());

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

@ -28,6 +28,7 @@ using mozilla::PositiveInfinity;
BEGIN_TEST(testJitMacroAssembler_flexibleDivMod) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -84,6 +85,7 @@ END_TEST(testJitMacroAssembler_flexibleDivMod)
BEGIN_TEST(testJitMacroAssembler_flexibleRemainder) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -131,6 +133,7 @@ END_TEST(testJitMacroAssembler_flexibleRemainder)
BEGIN_TEST(testJitMacroAssembler_flexibleQuotient) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -185,6 +188,7 @@ bool shiftTest(JSContext* cx, const char* name,
const uintptr_t* lhsInput, const uintptr_t* rhsInput,
const uintptr_t* result) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -378,6 +382,7 @@ END_TEST(testJitMacroAssembler_flexibleLshift)
BEGIN_TEST(testJitMacroAssembler_truncateDoubleToInt64) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -424,6 +429,7 @@ END_TEST(testJitMacroAssembler_truncateDoubleToInt64)
BEGIN_TEST(testJitMacroAssembler_truncateDoubleToUInt64) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -475,6 +481,7 @@ END_TEST(testJitMacroAssembler_truncateDoubleToUInt64)
BEGIN_TEST(testJitMacroAssembler_branchDoubleNotInInt64Range) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -527,6 +534,7 @@ END_TEST(testJitMacroAssembler_branchDoubleNotInInt64Range)
BEGIN_TEST(testJitMacroAssembler_branchDoubleNotInUInt64Range) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -582,6 +590,7 @@ END_TEST(testJitMacroAssembler_branchDoubleNotInUInt64Range)
BEGIN_TEST(testJitMacroAssembler_lshift64) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -649,6 +658,7 @@ END_TEST(testJitMacroAssembler_lshift64)
BEGIN_TEST(testJitMacroAssembler_rshift64Arithmetic) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);
@ -716,6 +726,7 @@ END_TEST(testJitMacroAssembler_rshift64Arithmetic)
BEGIN_TEST(testJitMacroAssembler_rshift64) {
StackMacroAssembler masm(cx);
AutoCreatedBy acb(masm, __func__);
PrepareJit(masm);

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

@ -71,6 +71,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_simple) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);
@ -118,6 +119,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_autogen) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);
@ -243,6 +245,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_autogen2) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);
@ -385,6 +388,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_autogen3) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);
@ -526,6 +530,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_bug1299147_1) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);
@ -576,6 +581,7 @@ BEGIN_TEST(testJitMoveEmitterCycles_bug1299147) {
TempAllocator alloc(&lifo);
JitContext jc(cx, &alloc);
StackMacroAssembler masm;
AutoCreatedBy acb(masm, __func__);
MoveEmitter mover(masm);
MoveResolver mr;
mr.setAllocator(alloc);

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

@ -393,6 +393,8 @@ void BaseCompiler::remainderI64(RegI64 rhs, RegI64 srcDest, RegI64 reserved,
// Function entry and exit
bool BaseCompiler::beginFunction() {
AutoCreatedBy acb(masm, "(wasm)BaseCompiler::beginFunction");
JitSpew(JitSpew_Codegen, "# ========================================");
JitSpew(JitSpew_Codegen, "# Emitting wasm baseline code");
JitSpew(JitSpew_Codegen,
@ -576,6 +578,8 @@ bool BaseCompiler::beginFunction() {
}
bool BaseCompiler::endFunction() {
AutoCreatedBy acb(masm, "(wasm)BaseCompiler::endFunction");
JitSpew(JitSpew_Codegen, "# endFunction: start of function epilogue");
// Always branch to returnLabel_.
@ -7647,6 +7651,8 @@ bool BaseCompiler::emitIntrinsic(IntrinsicOp op) {
// Function bodies - main opcode dispatch loop.
bool BaseCompiler::emitBody() {
AutoCreatedBy acb(masm, "(wasm)BaseCompiler::emitBody");
MOZ_ASSERT(stackMapGenerator_.framePushedAtEntryToBody.isSome());
if (!iter_.startFunction(func_.index)) {
@ -9509,6 +9515,8 @@ void BaseCompiler::assertStackInvariants() const {
// Main compilation logic.
bool BaseCompiler::emitFunction() {
AutoCreatedBy acb(masm, "(wasm)BaseCompiler::emitFunction");
if (!beginFunction()) {
return false;
}

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

@ -1598,6 +1598,7 @@ bool wasm::EnsureBuiltinThunksInitialized() {
LifoAlloc lifo(BUILTIN_THUNK_LIFO_SIZE);
TempAllocator tempAlloc(&lifo);
WasmMacroAssembler masm(tempAlloc);
AutoCreatedBy acb(masm, "wasm::EnsureBuiltinThunksInitialized");
for (auto sym : MakeEnumeratedRange(SymbolicAddress::Limit)) {
if (!NeedsBuiltinThunk(sym)) {

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

@ -408,6 +408,8 @@ void wasm::ClearExitFP(MacroAssembler& masm, Register scratch) {
}
static void GenerateCallablePrologue(MacroAssembler& masm, uint32_t* entry) {
AutoCreatedBy acb(masm, "GenerateCallablePrologue");
masm.setFramePushed(0);
// ProfilingFrameIterator needs to know the offsets of several key
@ -486,6 +488,8 @@ static void GenerateCallablePrologue(MacroAssembler& masm, uint32_t* entry) {
static void GenerateCallableEpilogue(MacroAssembler& masm, unsigned framePushed,
ExitReason reason, uint32_t* ret) {
AutoCreatedBy acb(masm, "GenerateCallableEpilogue");
if (framePushed) {
masm.freeStack(framePushed);
}
@ -562,6 +566,8 @@ void wasm::GenerateFunctionPrologue(MacroAssembler& masm,
const TypeIdDesc& funcTypeId,
const Maybe<uint32_t>& tier1FuncIndex,
FuncOffsets* offsets) {
AutoCreatedBy acb(masm, "wasm::GenerateFunctionPrologue");
// These constants reflect statically-determined offsets between a function's
// checked call entry and the checked tail's entry, see diagram below. The
// Entry is a call target, so must have CodeAlignment, but the TailEntry is

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

@ -458,6 +458,8 @@ using TrapMaybeOffsetArray =
EnumeratedArray<Trap, Trap::Limit, Maybe<uint32_t>>;
bool ModuleGenerator::linkCallSites() {
AutoCreatedBy acb(masm_, "linkCallSites");
masm_.haltingAlign(CodeAlignment);
// Create far jumps for calls that have relative offsets that may otherwise
@ -605,6 +607,8 @@ static bool AppendForEach(Vec* dstVec, const Vec& srcVec, Op op) {
}
bool ModuleGenerator::linkCompiledCode(CompiledCode& code) {
AutoCreatedBy acb(masm_, "ModuleGenerator::linkCompiledCode");
// Before merging in new code, if calls in a prior code range might go out of
// range, insert far jumps to extend the range.
@ -785,6 +789,8 @@ bool ModuleGenerator::locallyCompileCurrentTask() {
}
bool ModuleGenerator::finishTask(CompileTask* task) {
AutoCreatedBy acb(masm_, "ModuleGenerator::finishTask");
masm_.haltingAlign(CodeAlignment);
if (!linkCompiledCode(task->output)) {

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

@ -714,6 +714,8 @@ static void BoxValueIntoAnyref(MacroAssembler& masm, ValueOperand src,
static bool GenerateInterpEntry(MacroAssembler& masm, const FuncExport& fe,
const Maybe<ImmPtr>& funcPtr,
Offsets* offsets) {
AutoCreatedBy acb(masm, "GenerateInterpEntry");
AssertExpectedSP(masm);
masm.haltingAlign(CodeAlignment);
@ -984,6 +986,8 @@ static void GenerateBigIntInitialization(MacroAssembler& masm,
static bool GenerateJitEntry(MacroAssembler& masm, size_t funcExportIndex,
const FuncExport& fe, const Maybe<ImmPtr>& funcPtr,
Offsets* offsets) {
AutoCreatedBy acb(masm, "GenerateJitEntry");
AssertExpectedSP(masm);
RegisterOrSP sp = masm.getStackPointer();
@ -1935,6 +1939,8 @@ static void FillArgumentArrayForExit(
static bool GenerateImportFunction(jit::MacroAssembler& masm,
const FuncImport& fi, TypeIdDesc funcTypeId,
FuncOffsets* offsets) {
AutoCreatedBy acb(masm, "wasm::GenerateImportFunction");
AssertExpectedSP(masm);
GenerateFunctionPrologue(masm, funcTypeId, Nothing(), offsets);
@ -2998,6 +3004,7 @@ bool wasm::GenerateStubs(const ModuleEnvironment& env,
LifoAlloc lifo(STUBS_LIFO_DEFAULT_CHUNK_SIZE);
TempAllocator alloc(&lifo);
WasmMacroAssembler masm(alloc, env);
AutoCreatedBy acb(masm, "wasm::GenerateStubs");
// Swap in already-allocated empty vectors to avoid malloc/free.
if (!code->swap(masm)) {