Пример #1
0
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);
    }
}
Пример #2
0
// Replace all the nops in all the epilogues of asm.js functions with jumps
// to the profiling epilogues.
void
wasm::EnableProfilingEpilogue(const Module& module, const CodeRange& codeRange, bool enabled)
{
    if (!codeRange.isFunction())
        return;

    uint8_t* jump = module.code() + codeRange.functionProfilingJump();
    uint8_t* profilingEpilogue = module.code() + codeRange.funcProfilingEpilogue();

#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
    // An unconditional jump with a 1 byte offset immediate has the opcode
    // 0x90. The offset is relative to the address of the instruction after
    // the jump. 0x66 0x90 is the canonical two-byte nop.
    ptrdiff_t jumpImmediate = profilingEpilogue - jump - 2;
    MOZ_ASSERT(jumpImmediate > 0 && jumpImmediate <= 127);
    if (enabled) {
        MOZ_ASSERT(jump[0] == 0x66);
        MOZ_ASSERT(jump[1] == 0x90);
        jump[0] = 0xeb;
        jump[1] = jumpImmediate;
    } else {
        MOZ_ASSERT(jump[0] == 0xeb);
        MOZ_ASSERT(jump[1] == jumpImmediate);
        jump[0] = 0x66;
        jump[1] = 0x90;
    }
#elif defined(JS_CODEGEN_ARM)
    if (enabled) {
        MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->is<InstNOP>());
        new (jump) InstBImm(BOffImm(profilingEpilogue - jump), Assembler::Always);
    } else {
        MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->is<InstBImm>());
        new (jump) InstNOP();
    }
#elif defined(JS_CODEGEN_ARM64)
    (void)jump;
    (void)profilingEpilogue;
    MOZ_CRASH();
#elif defined(JS_CODEGEN_MIPS32)
    Instruction* instr = (Instruction*)jump;
    if (enabled) {
        Assembler::WriteLuiOriInstructions(instr, instr->next(),
                                           ScratchRegister, (uint32_t)profilingEpilogue);
        instr[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr);
    } else {
        for (unsigned i = 0; i < 3; i++)
            instr[i].makeNop();
    }
#elif defined(JS_CODEGEN_MIPS64)
    Instruction* instr = (Instruction*)jump;
    if (enabled) {
        Assembler::WriteLoad64Instructions(instr, ScratchRegister, (uint64_t)profilingEpilogue);
        instr[4] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr);
    } else {
        for (unsigned i = 0; i < 5; i++)
            instr[i].makeNop();
    }
#elif defined(JS_CODEGEN_NONE)
    MOZ_CRASH();
#else
# error "Missing architecture"
#endif
}