void wasm::ToggleProfiling(const Code& code, const CallSite& callSite, bool enabled) { if (callSite.kind() != CallSite::FuncDef) return; uint8_t* callerRetAddr = code.segment().base() + callSite.returnAddressOffset(); #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) void* callee = X86Encoding::GetRel32Target(callerRetAddr); #elif defined(JS_CODEGEN_ARM) uint8_t* caller = callerRetAddr - 4; Instruction* callerInsn = reinterpret_cast<Instruction*>(caller); BOffImm calleeOffset; callerInsn->as<InstBLImm>()->extractImm(&calleeOffset); void* callee = calleeOffset.getDest(callerInsn); #elif defined(JS_CODEGEN_ARM64) MOZ_CRASH(); void* callee = nullptr; (void)callerRetAddr; #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) uint8_t* caller = callerRetAddr - 2 * sizeof(uint32_t); InstImm* callerInsn = reinterpret_cast<InstImm*>(caller); BOffImm16 calleeOffset; callerInsn->extractImm16(&calleeOffset); void* callee = calleeOffset.getDest(reinterpret_cast<Instruction*>(caller)); #elif defined(JS_CODEGEN_NONE) MOZ_CRASH(); void* callee = nullptr; #else # error "Missing architecture" #endif const CodeRange* codeRange = code.lookupRange(callee); if (!codeRange->isFunction()) return; uint8_t* from = code.segment().base() + codeRange->funcNonProfilingEntry(); uint8_t* to = code.segment().base() + codeRange->funcProfilingEntry(); if (!enabled) Swap(from, to); MOZ_ASSERT(callee == from); #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) X86Encoding::SetRel32(callerRetAddr, to); #elif defined(JS_CODEGEN_ARM) new (caller) InstBLImm(BOffImm(to - caller), Assembler::Always); #elif defined(JS_CODEGEN_ARM64) (void)to; MOZ_CRASH(); #elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) new (caller) InstImm(op_regimm, zero, rt_bgezal, BOffImm16(to - caller)); #elif defined(JS_CODEGEN_NONE) MOZ_CRASH(); #else # error "Missing architecture" #endif }
static void UpdateEntry(const Code& code, bool profilingEnabled, void** entry) { const CodeRange& codeRange = *code.lookupRange(*entry); void* from = code.segment().base() + codeRange.funcNonProfilingEntry(); void* to = code.segment().base() + codeRange.funcProfilingEntry(); if (!profilingEnabled) Swap(from, to); MOZ_ASSERT(*entry == from); *entry = to; }
void wasm::ToggleProfiling(const Code& code, const CallThunk& callThunk, bool enabled) { const CodeRange& cr = code.metadata().codeRanges[callThunk.u.codeRangeIndex]; uint32_t calleeOffset = enabled ? cr.funcProfilingEntry() : cr.funcNonProfilingEntry(); MacroAssembler::repatchFarJump(code.segment().base(), callThunk.offset, calleeOffset); }
void wasm::ToggleProfiling(const Code& code, const CodeRange& codeRange, bool enabled) { if (!codeRange.isFunction()) return; uint8_t* codeBase = code.segment().base(); uint8_t* profilingEntry = codeBase + codeRange.funcProfilingEntry(); uint8_t* tableProfilingJump = codeBase + codeRange.funcTableProfilingJump(); uint8_t* profilingJump = codeBase + codeRange.funcProfilingJump(); uint8_t* profilingEpilogue = codeBase + codeRange.funcProfilingEpilogue(); if (enabled) { MacroAssembler::patchNopToNearJump(tableProfilingJump, profilingEntry); MacroAssembler::patchNopToNearJump(profilingJump, profilingEpilogue); } else { MacroAssembler::patchNearJumpToNop(tableProfilingJump); MacroAssembler::patchNearJumpToNop(profilingJump); } }