Пример #1
0
static bool
InThunk(const CodeRange& codeRange, uint32_t offsetInModule)
{
    if (codeRange.kind() == CodeRange::FarJumpIsland)
        return true;

    return codeRange.isFunction() &&
           offsetInModule >= codeRange.funcTableEntry() &&
           offsetInModule < codeRange.funcNonProfilingEntry();
}
Пример #2
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);
    }
}
Пример #3
0
Token::Ptr Token::construct(CodeRange &range)
{
    Token::Ptr res;
    if (range.empty())
        res.reset(new End(range));
    else if ('\n' == range.front())
        res.reset(new Newline(reduce(range, 1)));
    else
    {
        //We use an smatch here iso a cmatch, sometime, this function is called with a range
        //that is _not_ the full string, but that needs to end earlier (e.g., when we split a Name that comes after an escape-character)
        smatch match;
        auto str = toCode(range);
        if (regex_search(str, match, reName))
        {
            auto m = match[0];
            DEBUG_PRINT("Name: size: " << match.size() << ", match[0]: " << m << ", match[0].length(): " << m.length());
            res.reset(new Name(reduce(range, m.length())));
        }
        else if (regex_search(str, match, reNumber))
        {
            auto m = match[0];
            DEBUG_PRINT("Number: size: " << match.size() << ", match[0]: " << m << ", match[0].length(): " << m.length());
            res.reset(new Number(reduce(range, m.length())));
        }
        else if (regex_search(str, match, reWhitespace))
        {
            auto m = match[0];
            DEBUG_PRINT("Whitespace: size: " << match.size() << ", match[0]: " << m << ", match[0].length(): " << m.length());
            res.reset(new Whitespace(reduce(range, m.length())));
        }
        else
        {
            DEBUG_PRINT("Symbol: \"" << str[0] << "\"");
            res.reset(new Symbol(reduce(range, 1)));
        }
    }
    return res;
}
Пример #4
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
}