Changeset 35593 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


Ignore:
Timestamp:
Aug 6, 2008, 3:37:34 AM (17 years ago)
Author:
[email protected]
Message:

2008-08-06 Cameron Zwarich <[email protected]>

Reviewed by Maciej.

Bug 20286: Load constants all at once instead of using op_load
<https://bugs.webkit.org/show_bug.cgi?id=20286>

Load constants all at once into temporary registers instead of using
individual instances of op_load.

This is a 2.6% speedup on SunSpider.

JavaScriptCore:

  • JavaScriptCore.exp:
  • VM/CodeBlock.cpp: (KJS::CodeBlock::dump): (KJS::CodeBlock::mark):
  • VM/CodeBlock.h:
  • VM/CodeGenerator.cpp: (KJS::CodeGenerator::CodeGenerator): (KJS::CodeGenerator::newTemporary): (KJS::CodeGenerator::addConstant): (KJS::CodeGenerator::addUnexpectedConstant): (KJS::CodeGenerator::emitLoad): (KJS::CodeGenerator::emitUnexpectedLoad): (KJS::CodeGenerator::emitNewError):
  • VM/CodeGenerator.h:
  • VM/Machine.cpp: (KJS::slideRegisterWindowForCall): (KJS::Machine::unwindCallFrame): (KJS::Machine::throwException): (KJS::Machine::execute): (KJS::Machine::privateExecute):
  • VM/Machine.h:
  • VM/Opcode.h:
  • VM/RegisterID.h: (KJS::RegisterID::RegisterID): (KJS::RegisterID::makeConstant): (KJS::RegisterID::isTemporary):
  • kjs/NodeInfo.h:
  • kjs/Parser.cpp: (KJS::Parser::didFinishParsing):
  • kjs/Parser.h: (KJS::Parser::parse):
  • kjs/grammar.y:
  • kjs/nodes.cpp: (KJS::NullNode::emitCode): (KJS::BooleanNode::emitCode): (KJS::NumberNode::emitCode): (KJS::StringNode::emitCode): (KJS::ArrayNode::emitCode): (KJS::DeleteResolveNode::emitCode): (KJS::DeleteValueNode::emitCode): (KJS::VoidNode::emitCode): (KJS::ConstDeclNode::emitCodeSingle): (KJS::ReturnNode::emitCode): (KJS::ScopeNode::ScopeNode): (KJS::ProgramNode::ProgramNode): (KJS::ProgramNode::create): (KJS::EvalNode::EvalNode): (KJS::EvalNode::create): (KJS::FunctionBodyNode::FunctionBodyNode): (KJS::FunctionBodyNode::create): (KJS::FunctionBodyNode::emitCode):
  • kjs/nodes.h: (KJS::ScopeNode::neededConstants):

LayoutTests:

  • fast/js/constant-count-expected.txt: Added.
  • fast/js/constant-count.html: Added.
  • fast/js/deep-recursion-test.html:
  • fast/js/resources/constant-count.js: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/Machine.cpp

    r35586 r35593  
    380380{
    381381    size_t registerOffset = argv + newCodeBlock->numLocals;
    382     size_t size = r - registerBase + registerOffset + newCodeBlock->numTemporaries;
     382    size_t size = r - registerBase + registerOffset + newCodeBlock->numConstants + newCodeBlock->numTemporaries;
    383383
    384384    if (argc == newCodeBlock->numParameters) { // correct number of arguments
     
    419419    for (Register* it = r - newCodeBlock->numVars; it != r; ++it)
    420420        (*it) = jsUndefined();
     421
     422
     423    for (size_t i = 0; i < newCodeBlock->constantRegisters.size(); ++i)
     424        r[i] = newCodeBlock->constantRegisters[i];
    421425
    422426    return r;
     
    584588}
    585589
    586 NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r)
     590NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock, ScopeChainNode*& scopeChain, Register*& r)
    587591{
    588592    CodeBlock* oldCodeBlock = codeBlock;
     
    617621        return false;
    618622
    619     k = codeBlock->registers.data();
    620623    scopeChain = callFrame[RegisterFile::CallerScopeChain].scopeChain();
    621624    r = callFrame[RegisterFile::CallerRegisters].r();
     
    626629}
    627630
    628 NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue*& exceptionValue, const Instruction* vPC, CodeBlock*& codeBlock, Register*& k, ScopeChainNode*& scopeChain, Register*& r, bool explicitThrow)
     631NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue*& exceptionValue, const Instruction* vPC, CodeBlock*& codeBlock, ScopeChainNode*& scopeChain, Register*& r, bool explicitThrow)
    629632{
    630633    // Set up the exception object
     
    660663           
    661664            if (exception->isWatchdogException()) {
    662                 while (unwindCallFrame(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r)) {
     665                while (unwindCallFrame(exec, exceptionValue, vPC, codeBlock, scopeChain, r)) {
    663666                    // Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
    664667                }
     
    679682
    680683    while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) {
    681         if (!unwindCallFrame(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r))
     684        if (!unwindCallFrame(exec, exceptionValue, vPC, codeBlock, scopeChain, r))
    682685            return 0;
    683686    }
     
    705708
    706709    size_t oldSize = m_registerFile.size();
    707     size_t newSize = oldSize + RegisterFile::CallFrameHeaderSize + codeBlock->numVars + codeBlock->numTemporaries;
     710    size_t newSize = oldSize + RegisterFile::CallFrameHeaderSize + codeBlock->numVars + codeBlock->numConstants + codeBlock->numTemporaries;
    708711    if (!m_registerFile.grow(newSize)) {
    709712        *exception = createStackOverflowError(exec);
     
    722725    Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
    723726    r[codeBlock->thisRegister] = thisObj;
     727
     728    for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i)
     729        r[i] = codeBlock->constantRegisters[i];
    724730
    725731    if (codeBlock->needsFullScopeChain)
     
    840846
    841847    size_t oldSize = m_registerFile.size();
    842     size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numTemporaries + RegisterFile::CallFrameHeaderSize;
     848    size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numConstants + codeBlock->numTemporaries + RegisterFile::CallFrameHeaderSize;
    843849    if (!m_registerFile.grow(newSize)) {
    844850        *exception = createStackOverflowError(exec);
     
    853859    Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
    854860    r[codeBlock->thisRegister] = thisObj;
     861
     862    for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i)
     863        r[i] = codeBlock->constantRegisters[i];
    855864
    856865    if (codeBlock->needsFullScopeChain)
     
    10351044    Register* registerBase = registerFile->base();
    10361045    Instruction* vPC = codeBlock->instructions.begin();
    1037     Register* k = codeBlock->registers.data();
    10381046    Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
    10391047    unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
     
    10771085#endif
    10781086    {
    1079     BEGIN_OPCODE(op_load) {
    1080         /* load dst(r) src(k)
    1081 
    1082            Copies constant src to register dst.
    1083         */
    1084         int dst = (++vPC)->u.operand;
    1085         int src = (++vPC)->u.operand;
    1086         r[dst] = k[src];
    1087 
    1088         ++vPC;
    1089         NEXT_OPCODE;
    1090     }
    10911087    BEGIN_OPCODE(op_new_object) {
    10921088        /* new_object dst(r)
     
    23762372            codeBlock = newCodeBlock;
    23772373            setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
    2378             k = codeBlock->registers.data();
    23792374            vPC = codeBlock->instructions.begin();
    23802375
     
    24472442            return returnValue;
    24482443
    2449         k = codeBlock->registers.data();
    24502444        vPC = callFrame[RegisterFile::ReturnVPC].vPC();
    24512445        setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());
     
    25092503            codeBlock = newCodeBlock;
    25102504            setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, r));
    2511             k = codeBlock->registers.data();
    25122505            vPC = codeBlock->instructions.begin();
    25132506
     
    26722665        exceptionValue = r[ex].jsValue(exec);
    26732666
    2674         handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r, true);
     2667        handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, scopeChain, r, true);
    26752668        if (!handlerVPC) {
    26762669            *exception = exceptionValue;
     
    26902683        NEXT_OPCODE;
    26912684    }
     2685    BEGIN_OPCODE(op_unexpected_load) {
     2686        /* unexpected_load load dst(r) src(k)
     2687
     2688           Copies constant src to register dst.
     2689        */
     2690        int dst = (++vPC)->u.operand;
     2691        int src = (++vPC)->u.operand;
     2692        r[dst] = codeBlock->unexpectedConstants[src];
     2693
     2694        ++vPC;
     2695        NEXT_OPCODE;
     2696    }
    26922697    BEGIN_OPCODE(op_new_error) {
    26932698        /* new_error dst(r) type(n) message(k)
     
    27022707        int message = (++vPC)->u.operand;
    27032708
    2704         r[dst] = Error::create(exec, (ErrorType)type, k[message].jsValue(exec)->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
     2709        r[dst] = Error::create(exec, (ErrorType)type, codeBlock->unexpectedConstants[message]->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
    27052710
    27062711        ++vPC;
     
    28122817            exceptionValue = createInterruptedExecutionException(exec);
    28132818        }
    2814         handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, k, scopeChain, r, false);
     2819        handlerVPC = throwException(exec, exceptionValue, vPC, codeBlock, scopeChain, r, false);
    28152820        if (!handlerVPC) {
    28162821            *exception = exceptionValue;
Note: See TracChangeset for help on using the changeset viewer.