Ignore:
Timestamp:
Oct 9, 2009, 5:30:49 PM (16 years ago)
Author:
[email protected]
Message:

Eliminated some legacy bytecode weirdness.

Patch by Geoffrey Garen <[email protected]> on 2009-10-09
Reviewed by Oliver Hunt.

Use vPC[x] subscripting instead of ++vPC to access instruction operands.
This is simpler, and often more efficient.

To support this, and to remove use of hard-coded offsets in bytecode and
JIT code generation and dumping, calculate jump offsets from the beginning
of an instruction, rather than the middle or end.

Also, use OPCODE_LENGTH instead of hard-coded constants for the sizes of
opcodes.

SunSpider reports no change in JIT mode, and a 1.01x speedup in Interpreter
mode.

  • bytecode/CodeBlock.cpp:

(JSC::printConditionalJump):
(JSC::CodeBlock::dump):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitJump):
(JSC::BytecodeGenerator::emitJumpIfTrue):
(JSC::BytecodeGenerator::emitJumpIfFalse):
(JSC::BytecodeGenerator::emitJumpIfNotFunctionCall):
(JSC::BytecodeGenerator::emitJumpIfNotFunctionApply):
(JSC::BytecodeGenerator::emitComplexJumpScopes):
(JSC::BytecodeGenerator::emitJumpScopes):
(JSC::BytecodeGenerator::emitNextPropertyName):
(JSC::BytecodeGenerator::emitCatch):
(JSC::BytecodeGenerator::emitJumpSubroutine):
(JSC::prepareJumpTableForImmediateSwitch):
(JSC::prepareJumpTableForCharacterSwitch):
(JSC::prepareJumpTableForStringSwitch):
(JSC::BytecodeGenerator::endSwitch):

  • bytecompiler/Label.h:

(JSC::Label::setLocation):
(JSC::Label::bind):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::resolve):
(JSC::Interpreter::resolveSkip):
(JSC::Interpreter::resolveGlobal):
(JSC::Interpreter::resolveBase):
(JSC::Interpreter::resolveBaseAndProperty):
(JSC::Interpreter::createExceptionScope):
(JSC::Interpreter::privateExecute):

  • interpreter/Interpreter.h:
  • jit/JIT.cpp:

(JSC::JIT::privateCompile):

  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_jnless):
(JSC::JIT::emitSlow_op_jnless):
(JSC::JIT::emit_op_jnlesseq):
(JSC::JIT::emitSlow_op_jnlesseq):
(JSC::JIT::emitBinaryDoubleOp):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_jmp):
(JSC::JIT::emit_op_loop):
(JSC::JIT::emit_op_loop_if_less):
(JSC::JIT::emitSlow_op_loop_if_less):
(JSC::JIT::emit_op_loop_if_lesseq):
(JSC::JIT::emitSlow_op_loop_if_lesseq):
(JSC::JIT::emit_op_loop_if_true):
(JSC::JIT::emitSlow_op_loop_if_true):
(JSC::JIT::emit_op_jfalse):
(JSC::JIT::emitSlow_op_jfalse):
(JSC::JIT::emit_op_jtrue):
(JSC::JIT::emitSlow_op_jtrue):
(JSC::JIT::emit_op_jeq_null):
(JSC::JIT::emit_op_jneq_null):
(JSC::JIT::emit_op_jneq_ptr):
(JSC::JIT::emit_op_jsr):
(JSC::JIT::emit_op_next_pname):
(JSC::JIT::emit_op_jmp_scopes):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r48662 r49409  
    609609PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
    610610{
     611    size_t begin = instructions().size();
    611612    emitOpcode(target->isForward() ? op_jmp : op_loop);
    612     instructions().append(target->offsetFrom(instructions().size()));
     613    instructions().append(target->bind(begin, instructions().size()));
    613614    return target;
    614615}
     
    625626        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    626627            rewindBinaryOp();
     628
     629            size_t begin = instructions().size();
    627630            emitOpcode(op_loop_if_less);
    628631            instructions().append(src1Index);
    629632            instructions().append(src2Index);
    630             instructions().append(target->offsetFrom(instructions().size()));
     633            instructions().append(target->bind(begin, instructions().size()));
    631634            return target;
    632635        }
     
    640643        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    641644            rewindBinaryOp();
     645
     646            size_t begin = instructions().size();
    642647            emitOpcode(op_loop_if_lesseq);
    643648            instructions().append(src1Index);
    644649            instructions().append(src2Index);
    645             instructions().append(target->offsetFrom(instructions().size()));
     650            instructions().append(target->bind(begin, instructions().size()));
    646651            return target;
    647652        }
     
    654659        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    655660            rewindUnaryOp();
     661
     662            size_t begin = instructions().size();
    656663            emitOpcode(op_jeq_null);
    657664            instructions().append(srcIndex);
    658             instructions().append(target->offsetFrom(instructions().size()));
     665            instructions().append(target->bind(begin, instructions().size()));
    659666            return target;
    660667        }
     
    667674        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    668675            rewindUnaryOp();
     676
     677            size_t begin = instructions().size();
    669678            emitOpcode(op_jneq_null);
    670679            instructions().append(srcIndex);
    671             instructions().append(target->offsetFrom(instructions().size()));
     680            instructions().append(target->bind(begin, instructions().size()));
    672681            return target;
    673682        }
    674683    }
     684
     685    size_t begin = instructions().size();
    675686
    676687    emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
    677688    instructions().append(cond->index());
    678     instructions().append(target->offsetFrom(instructions().size()));
     689    instructions().append(target->bind(begin, instructions().size()));
    679690    return target;
    680691}
     
    693704        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    694705            rewindBinaryOp();
     706
     707            size_t begin = instructions().size();
    695708            emitOpcode(op_jnless);
    696709            instructions().append(src1Index);
    697710            instructions().append(src2Index);
    698             instructions().append(target->offsetFrom(instructions().size()));
     711            instructions().append(target->bind(begin, instructions().size()));
    699712            return target;
    700713        }
     
    708721        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    709722            rewindBinaryOp();
     723
     724            size_t begin = instructions().size();
    710725            emitOpcode(op_jnlesseq);
    711726            instructions().append(src1Index);
    712727            instructions().append(src2Index);
    713             instructions().append(target->offsetFrom(instructions().size()));
     728            instructions().append(target->bind(begin, instructions().size()));
    714729            return target;
    715730        }
     
    722737        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    723738            rewindUnaryOp();
     739
     740            size_t begin = instructions().size();
    724741            emitOpcode(op_jtrue);
    725742            instructions().append(srcIndex);
    726             instructions().append(target->offsetFrom(instructions().size()));
     743            instructions().append(target->bind(begin, instructions().size()));
    727744            return target;
    728745        }
     
    735752        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    736753            rewindUnaryOp();
     754
     755            size_t begin = instructions().size();
    737756            emitOpcode(op_jneq_null);
    738757            instructions().append(srcIndex);
    739             instructions().append(target->offsetFrom(instructions().size()));
     758            instructions().append(target->bind(begin, instructions().size()));
    740759            return target;
    741760        }
     
    748767        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
    749768            rewindUnaryOp();
     769
     770            size_t begin = instructions().size();
    750771            emitOpcode(op_jeq_null);
    751772            instructions().append(srcIndex);
    752             instructions().append(target->offsetFrom(instructions().size()));
     773            instructions().append(target->bind(begin, instructions().size()));
    753774            return target;
    754775        }
    755776    }
    756777
     778    size_t begin = instructions().size();
    757779    emitOpcode(op_jfalse);
    758780    instructions().append(cond->index());
    759     instructions().append(target->offsetFrom(instructions().size()));
     781    instructions().append(target->bind(begin, instructions().size()));
    760782    return target;
    761783}
     
    763785PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
    764786{
     787    size_t begin = instructions().size();
     788
    765789    emitOpcode(op_jneq_ptr);
    766790    instructions().append(cond->index());
    767791    instructions().append(m_scopeChain->globalObject()->d()->callFunction);
    768     instructions().append(target->offsetFrom(instructions().size()));
     792    instructions().append(target->bind(begin, instructions().size()));
    769793    return target;
    770794}
     
    772796PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
    773797{
     798    size_t begin = instructions().size();
     799
    774800    emitOpcode(op_jneq_ptr);
    775801    instructions().append(cond->index());
    776802    instructions().append(m_scopeChain->globalObject()->d()->applyFunction);
    777     instructions().append(target->offsetFrom(instructions().size()));
     803    instructions().append(target->bind(begin, instructions().size()));
    778804    return target;
    779805}
     
    17191745
    17201746        if (nNormalScopes) {
     1747            size_t begin = instructions().size();
     1748
    17211749            // We need to remove a number of dynamic scopes to get to the next
    17221750            // finally block
     
    17271755            // left to emit, so make the jmp_scopes jump directly to the target label
    17281756            if (topScope == bottomScope) {
    1729                 instructions().append(target->offsetFrom(instructions().size()));
     1757                instructions().append(target->bind(begin, instructions().size()));
    17301758                return target;
    17311759            }
     
    17341762            // to the next instruction
    17351763            RefPtr<Label> nextInsn = newLabel();
    1736             instructions().append(nextInsn->offsetFrom(instructions().size()));
     1764            instructions().append(nextInsn->bind(begin, instructions().size()));
    17371765            emitLabel(nextInsn.get());
    17381766        }
     
    17591787        return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
    17601788
     1789    size_t begin = instructions().size();
     1790
    17611791    emitOpcode(op_jmp_scopes);
    17621792    instructions().append(scopeDelta);
    1763     instructions().append(target->offsetFrom(instructions().size()));
     1793    instructions().append(target->bind(begin, instructions().size()));
    17641794    return target;
    17651795}
     
    17671797RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target)
    17681798{
     1799    size_t begin = instructions().size();
     1800
    17691801    emitOpcode(op_next_pname);
    17701802    instructions().append(dst->index());
    17711803    instructions().append(iter->index());
    1772     instructions().append(target->offsetFrom(instructions().size()));
     1804    instructions().append(target->bind(begin, instructions().size()));
    17731805    return dst;
    17741806}
     
    17771809{
    17781810#if ENABLE(JIT)
    1779     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
     1811    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
    17801812#else
    1781     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
     1813    HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
    17821814#endif
    17831815
     
    17991831PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
    18001832{
     1833    size_t begin = instructions().size();
     1834
    18011835    emitOpcode(op_jsr);
    18021836    instructions().append(retAddrDst->index());
    1803     instructions().append(finally->offsetFrom(instructions().size()));
     1837    instructions().append(finally->bind(begin, instructions().size()));
    18041838    emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
    18051839    return finally;
     
    18711905        // the labels should not be "forward" references
    18721906        ASSERT(!labels[i]->isForward());
    1873         jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
     1907        jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
    18741908    }
    18751909}
     
    18971931        // the labels should not be "forward" references
    18981932        ASSERT(!labels[i]->isForward());
    1899         jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress));
     1933        jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3));
    19001934    }
    19011935}
     
    19111945        UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
    19121946        OffsetLocation location;
    1913         location.branchOffset = labels[i]->offsetFrom(switchAddress);
     1947        location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
    19141948        jumpTable.offsetTable.add(clause, location);
    19151949    }
     
    19221956    if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
    19231957        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
    1924         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
     1958        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    19251959
    19261960        SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
    1927         prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
     1961        prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
    19281962    } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
    19291963        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
    1930         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
     1964        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    19311965       
    19321966        SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
    1933         prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
     1967        prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
    19341968    } else {
    19351969        ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
    19361970        instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
    1937         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
     1971        instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
    19381972
    19391973        StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
    1940         prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes);
     1974        prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
    19411975    }
    19421976}
Note: See TracChangeset for help on using the changeset viewer.