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; }
static inline void AssertMatchesCallSite(const WasmActivation& activation, void* callerPC, void* callerFP, void* fp) { #ifdef DEBUG Code* code = activation.compartment()->wasm.lookupCode(callerPC); MOZ_ASSERT(code); const CodeRange* callerCodeRange = code->lookupRange(callerPC); MOZ_ASSERT(callerCodeRange); if (callerCodeRange->kind() == CodeRange::Entry) { MOZ_ASSERT(callerFP == nullptr); return; } const CallSite* callsite = code->lookupCallSite(callerPC); MOZ_ASSERT(callsite); MOZ_ASSERT(callerFP == (uint8_t*)fp + callsite->stackDepth()); #endif }