Ignore:
Timestamp:
Jun 1, 2010, 4:13:23 PM (15 years ago)
Author:
[email protected]
Message:

Bug 40021 - Refactor bytecode generation for calls so that register for this & args are allocated together

Reviewed by Sam Weinig.

This is a useful stepping stone towards reversing argument order.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::addParameter):
(JSC::BytecodeGenerator::emitCall):
(JSC::BytecodeGenerator::emitCallEval):
(JSC::BytecodeGenerator::emitConstruct):

  • bytecompiler/BytecodeGenerator.h:

(JSC::CallArguments::thisRegister):
(JSC::CallArguments::argumentRegister):
(JSC::CallArguments::callFrame):
(JSC::CallArguments::count):
(JSC::BytecodeGenerator::shouldEmitProfileHooks):

  • bytecompiler/NodesCodegen.cpp:

(JSC::NewExprNode::emitBytecode):
(JSC::CallArguments::CallArguments):
(JSC::EvalFunctionCallNode::emitBytecode):
(JSC::FunctionCallValueNode::emitBytecode):
(JSC::FunctionCallResolveNode::emitBytecode):
(JSC::FunctionCallBracketNode::emitBytecode):
(JSC::FunctionCallDotNode::emitBytecode):
(JSC::CallFunctionCallDotNode::emitBytecode):
(JSC::ApplyFunctionCallDotNode::emitBytecode):

File:
1 edited

Legend:

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

    r60117 r60512  
    358358    FunctionParameters& parameters = *functionBody->parameters();
    359359    size_t parameterCount = parameters.size();
    360     m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
     360    int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
    361361    m_parameters.grow(1 + parameterCount); // reserve space for "this"
    362362
    363363    // Add "this" as a parameter
    364     m_thisRegister.setIndex(m_nextParameterIndex);
    365     ++m_nextParameterIndex;
     364    m_thisRegister.setIndex(nextParameterIndex);
    366365    ++m_codeBlock->m_numParameters;
    367366   
    368367    for (size_t i = 0; i < parameterCount; ++i)
    369         addParameter(parameters[i]);
     368        addParameter(parameters[i], ++nextParameterIndex);
    370369
    371370    preserveLastVar();
     
    432431}
    433432
    434 RegisterID* BytecodeGenerator::addParameter(const Identifier& ident)
     433void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
    435434{
    436435    // Parameters overwrite var declarations, but not function declarations.
    437     RegisterID* result = 0;
    438436    UString::Rep* rep = ident.ustring().rep();
    439437    if (!m_functions.contains(rep)) {
    440         symbolTable().set(rep, m_nextParameterIndex);
    441         RegisterID& parameter = registerFor(m_nextParameterIndex);
    442         parameter.setIndex(m_nextParameterIndex);
    443         result = &parameter;
     438        symbolTable().set(rep, parameterIndex);
     439        RegisterID& parameter = registerFor(parameterIndex);
     440        parameter.setIndex(parameterIndex);
    444441    }
    445442
    446443    // To maintain the calling convention, we have to allocate unique space for
    447444    // each parameter, even if the parameter doesn't make it into the symbol table.
    448     ++m_nextParameterIndex;
    449445    ++m_codeBlock->m_numParameters;
    450     return result;
    451446}
    452447
     
    14161411}
    14171412
    1418 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1419 {
    1420     return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
     1413RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
     1414{
     1415    return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset);
    14211416}
    14221417
     
    14311426}
    14321427
    1433 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
    1434 {
    1435     return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
    1436 }
    1437 
    1438 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1428RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
     1429{
     1430    return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset);
     1431}
     1432
     1433RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
    14391434{
    14401435    ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
    14411436    ASSERT(func->refCount());
    1442     ASSERT(thisRegister->refCount());
    1443 
    1444     RegisterID* originalFunc = func;
    1445     if (m_shouldEmitProfileHooks) {
    1446         // If codegen decided to recycle func as this call's destination register,
    1447         // we need to undo that optimization here so that func will still be around
    1448         // for the sake of op_profile_did_call.
    1449         if (dst == func) {
    1450             RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
    1451             RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
    1452            
    1453             thisRegister = movedThisRegister.release().releaseRef();
    1454             func = movedFunc.release().releaseRef();
    1455         }
    1456     }
     1437
     1438    if (m_shouldEmitProfileHooks)
     1439        emitMove(callArguments.profileHookRegister(), func);
    14571440
    14581441    // Generate code for arguments.
    1459     Vector<RefPtr<RegisterID>, 16> argv;
    1460     argv.append(thisRegister);
    1461     for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) {
    1462         argv.append(newTemporary());
    1463         // op_call requires the arguments to be a sequential range of registers
    1464         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
    1465         emitNode(argv.last().get(), n);
    1466     }
     1442    unsigned argumentIndex = 0;
     1443    for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next)
     1444        emitNode(callArguments.argumentRegister(argumentIndex++), n);
    14671445
    14681446    // Reserve space for call frame.
     
    14731451    if (m_shouldEmitProfileHooks) {
    14741452        emitOpcode(op_profile_will_call);
    1475         instructions().append(func->index());
     1453        instructions().append(callArguments.profileHookRegister()->index());
    14761454
    14771455#if ENABLE(JIT)
    1478         m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());
     1456        m_codeBlock->addFunctionRegisterInfo(instructions().size(), callArguments.profileHookRegister()->index());
    14791457#endif
    14801458    }
     
    14891467    emitOpcode(opcodeID);
    14901468    instructions().append(func->index()); // func
    1491     instructions().append(argv.size()); // argCount
    1492     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
     1469    instructions().append(callArguments.count()); // argCount
     1470    instructions().append(callArguments.callFrame()); // registerOffset
    14931471    if (dst != ignoredResult()) {
    14941472        emitOpcode(op_call_put_result);
     
    14981476    if (m_shouldEmitProfileHooks) {
    14991477        emitOpcode(op_profile_did_call);
    1500         instructions().append(func->index());
    1501 
    1502         if (dst == originalFunc) {
    1503             thisRegister->deref();
    1504             func->deref();
    1505         }
     1478        instructions().append(callArguments.profileHookRegister()->index());
    15061479    }
    15071480
     
    15801553}
    15811554
    1582 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
     1555RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
    15831556{
    15841557    ASSERT(func->refCount());
    15851558
    1586     RegisterID* originalFunc = func;
    1587     if (m_shouldEmitProfileHooks) {
    1588         // If codegen decided to recycle func as this call's destination register,
    1589         // we need to undo that optimization here so that func will still be around
    1590         // for the sake of op_profile_did_call.
    1591         if (dst == func) {
    1592             RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
    1593             func = movedFunc.release().releaseRef();
    1594         }
    1595     }
     1559    if (m_shouldEmitProfileHooks)
     1560        emitMove(callArguments.profileHookRegister(), func);
    15961561
    15971562    // Generate code for arguments.
    1598     Vector<RefPtr<RegisterID>, 16> argv;
    1599     argv.append(newTemporary()); // reserve space for "this"
    1600     for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode : 0; n; n = n->m_next) {
    1601         argv.append(newTemporary());
    1602         // op_construct requires the arguments to be a sequential range of registers
    1603         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
    1604         emitNode(argv.last().get(), n);
     1563    unsigned argumentIndex = 0;
     1564    if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
     1565        for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
     1566            emitNode(callArguments.argumentRegister(argumentIndex++), n);
    16051567    }
    16061568
    16071569    if (m_shouldEmitProfileHooks) {
    16081570        emitOpcode(op_profile_will_call);
    1609         instructions().append(func->index());
     1571        instructions().append(callArguments.profileHookRegister()->index());
    16101572    }
    16111573
     
    16231585    emitOpcode(op_construct);
    16241586    instructions().append(func->index()); // func
    1625     instructions().append(argv.size()); // argCount
    1626     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
     1587    instructions().append(callArguments.count()); // argCount
     1588    instructions().append(callArguments.callFrame()); // registerOffset
    16271589    if (dst != ignoredResult()) {
    16281590        emitOpcode(op_call_put_result);
     
    16321594    if (m_shouldEmitProfileHooks) {
    16331595        emitOpcode(op_profile_did_call);
    1634         instructions().append(func->index());
    1635        
    1636         if (dst == originalFunc)
    1637             func->deref();
     1596        instructions().append(callArguments.profileHookRegister()->index());
    16381597    }
    16391598
Note: See TracChangeset for help on using the changeset viewer.