void wasm::ToggleProfiling(const Instance& instance, const CallSite& callSite, bool enabled) { if (callSite.kind() != CallSite::Relative) return; uint8_t* callerRetAddr = instance.codeSegment().code() + 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 = instance.lookupCodeRange(callee); if (!codeRange->isFunction()) return; uint8_t* from = instance.codeSegment().code() + codeRange->funcNonProfilingEntry(); uint8_t* to = instance.codeSegment().code() + 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 }
void wasm::ToggleProfiling(const Instance& instance, const CallThunk& callThunk, bool enabled) { const CodeRange& cr = instance.metadata().codeRanges[callThunk.u.codeRangeIndex]; uint32_t calleeOffset = enabled ? cr.funcProfilingEntry() : cr.funcNonProfilingEntry(); MacroAssembler::repatchThunk(instance.codeSegment().code(), callThunk.offset, calleeOffset); }
void wasm::ToggleProfiling(const Instance& instance, const CodeRange& codeRange, bool enabled) { if (!codeRange.isFunction()) return; uint8_t* code = instance.codeSegment().code(); uint8_t* profilingEntry = code + codeRange.funcProfilingEntry(); uint8_t* tableProfilingJump = code + codeRange.funcTableProfilingJump(); uint8_t* profilingJump = code + codeRange.funcProfilingJump(); uint8_t* profilingEpilogue = code + codeRange.funcProfilingEpilogue(); if (enabled) { MacroAssembler::patchNopToNearJump(tableProfilingJump, profilingEntry); MacroAssembler::patchNopToNearJump(profilingJump, profilingEpilogue); } else { MacroAssembler::patchNearJumpToNop(tableProfilingJump); MacroAssembler::patchNearJumpToNop(profilingJump); } }