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


Ignore:
Timestamp:
Sep 23, 2008, 5:27:18 PM (17 years ago)
Author:
[email protected]
Message:

2008-09-23 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.


Changed the layout of the call frame from


{ header, parameters, locals | constants, temporaries }


to


{ parameters, header | locals, constants, temporaries }


This simplifies function entry+exit, and enables a number of future
optimizations.


13.5% speedup on empty call benchmark for bytecode; 23.6% speedup on
empty call benchmark for CTI.


SunSpider says no change. SunSpider --v8 says 1% faster.

  • VM/CTI.cpp:


Added a bit of abstraction for calculating whether a register is a
constant, since this patch changes that calculation:
(JSC::CTI::isConstant):
(JSC::CTI::getConstant):
(JSC::CTI::emitGetArg):
(JSC::CTI::emitGetPutArg):
(JSC::CTI::getConstantImmediateNumericArg):

Updated for changes to callframe header location:
(JSC::CTI::emitPutToCallFrameHeader):
(JSC::CTI::emitGetFromCallFrameHeader):
(JSC::CTI::printOpcodeOperandTypes):


Renamed to spite Oliver:
(JSC::CTI::emitInitRegister):


Added an abstraction for emitting a call through a register, so that
calls through registers generate exception info, too:
(JSC::CTI::emitCall):

Updated to match the new callframe header layout, and to support calls
through registers, which have no destination address:
(JSC::CTI::compileOpCall):
(JSC::CTI::privateCompileMainPass):
(JSC::CTI::privateCompileSlowCases):
(JSC::CTI::privateCompile):

  • VM/CTI.h:

More of the above:
(JSC::CallRecord::CallRecord):

  • VM/CodeBlock.cpp:

Updated for new register layout:
(JSC::registerName):
(JSC::CodeBlock::dump):

  • VM/CodeBlock.h:


Updated CodeBlock to track slightly different information about the
register frame, and tweaked the style of an ASSERT_NOT_REACHED.
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::getStubInfo):

  • VM/CodeGenerator.cpp:


Added some abstraction around constant register allocation, since this
patch changes it, changed codegen to account for the new callframe
layout, and added abstraction around register fetching code
that used to assume that all local registers lived at negative indices,
since vars now live at positive indices:
(JSC::CodeGenerator::generate):
(JSC::CodeGenerator::addVar):
(JSC::CodeGenerator::addGlobalVar):
(JSC::CodeGenerator::allocateConstants):
(JSC::CodeGenerator::CodeGenerator):
(JSC::CodeGenerator::addParameter):
(JSC::CodeGenerator::registerFor):
(JSC::CodeGenerator::constRegisterFor):
(JSC::CodeGenerator::newRegister):
(JSC::CodeGenerator::newTemporary):
(JSC::CodeGenerator::highestUsedRegister):
(JSC::CodeGenerator::addConstant):


ASSERT that our caller referenced the registers it passed to us.
Otherwise, we might overwrite them with parameters:
(JSC::CodeGenerator::emitCall):
(JSC::CodeGenerator::emitConstruct):

  • VM/CodeGenerator.h:


Added some abstraction for getting a RegisterID for a given index,
since the rules are a little weird:
(JSC::CodeGenerator::registerFor):

  • VM/Machine.cpp:

Utility function to transform a machine return PC to a virtual machine
return VPC, for the sake of stack unwinding, since both PCs are stored
in the same location now:
(JSC::vPCForPC):

Tweaked to account for new call frame:
(JSC::Machine::initializeCallFrame):


Tweaked to account for registerOffset supplied by caller:
(JSC::slideRegisterWindowForCall):

Tweaked to account for new register layout:
(JSC::scopeChainForCall):
(JSC::Machine::callEval):
(JSC::Machine::dumpRegisters):
(JSC::Machine::unwindCallFrame):
(JSC::Machine::execute):

Changed op_call and op_construct to implement the new calling convention:
(JSC::Machine::privateExecute):

Tweaked to account for the new register layout:
(JSC::Machine::retrieveArguments):
(JSC::Machine::retrieveCaller):
(JSC::Machine::retrieveLastCaller):
(JSC::Machine::callFrame):
(JSC::Machine::getArgumentsData):

Changed CTI call helpers to implement the new calling convention:
(JSC::Machine::cti_op_call_JSFunction):
(JSC::Machine::cti_op_call_NotJSFunction):
(JSC::Machine::cti_op_ret_activation):
(JSC::Machine::cti_op_ret_profiler):
(JSC::Machine::cti_op_construct_JSConstruct):
(JSC::Machine::cti_op_construct_NotJSConstruct):
(JSC::Machine::cti_op_call_eval):

  • VM/Machine.h:
  • VM/Opcode.h:


Renamed op_initialise_locals to op_init, because this opcode
doesn't initialize all locals, and it doesn't initialize only locals.
Also, to spite Oliver.


  • VM/RegisterFile.h:


New call frame enumeration values:
(JSC::RegisterFile::):

Simplified the calculation of whether a RegisterID is a temporary,
since we can no longer assume that all positive non-constant registers
are temporaries:

  • VM/RegisterID.h: (JSC::RegisterID::RegisterID): (JSC::RegisterID::setTemporary): (JSC::RegisterID::isTemporary):

Renamed firstArgumentIndex to firstParameterIndex because the assumption
that this variable pertained to the actual arguments supplied by the
caller caused me to write some buggy code:

  • kjs/Arguments.cpp: (JSC::ArgumentsData::ArgumentsData): (JSC::Arguments::Arguments): (JSC::Arguments::fillArgList): (JSC::Arguments::getOwnPropertySlot): (JSC::Arguments::put):

Updated for new call frame layout:

  • kjs/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::functionName): (JSC::DebuggerCallFrame::type):
  • kjs/DebuggerCallFrame.h:

Changed the activation object to account for the fact that a call frame
header now sits between parameters and local variables. This change
requires all variable objects to do their own marking, since they
now use their register storage differently:

  • kjs/JSActivation.cpp: (JSC::JSActivation::mark): (JSC::JSActivation::copyRegisters): (JSC::JSActivation::createArgumentsObject):
  • kjs/JSActivation.h:

Updated global object to use the new interfaces required by the change
to JSActivation above:

  • kjs/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset): (JSC::JSGlobalObject::mark): (JSC::JSGlobalObject::copyGlobalsFrom): (JSC::JSGlobalObject::copyGlobalsTo):
  • kjs/JSGlobalObject.h: (JSC::JSGlobalObject::addStaticGlobals):

Updated static scope object to use the new interfaces required by the
change to JSActivation above:

  • kjs/JSStaticScopeObject.cpp: (JSC::JSStaticScopeObject::mark): (JSC::JSStaticScopeObject::~JSStaticScopeObject):
  • kjs/JSStaticScopeObject.h: (JSC::JSStaticScopeObject::JSStaticScopeObject): (JSC::JSStaticScopeObject::d):

Updated variable object to use the new interfaces required by the
change to JSActivation above:

  • kjs/JSVariableObject.cpp: (JSC::JSVariableObject::copyRegisterArray): (JSC::JSVariableObject::setRegisters):
  • kjs/JSVariableObject.h:

Changed the bit twiddling in symbol table not to assume that all indices
are negative, since they can be positive now:

  • kjs/SymbolTable.h: (JSC::SymbolTableEntry::SymbolTableEntry): (JSC::SymbolTableEntry::isNull): (JSC::SymbolTableEntry::getIndex): (JSC::SymbolTableEntry::getAttributes): (JSC::SymbolTableEntry::setAttributes): (JSC::SymbolTableEntry::isReadOnly): (JSC::SymbolTableEntry::pack): (JSC::SymbolTableEntry::isValidIndex):

Changed call and construct nodes to ref their functions and/or bases,
so that emitCall/emitConstruct doesn't overwrite them with parameters.
Also, updated for rename to registerFor:

  • kjs/nodes.cpp: (JSC::ResolveNode::emitCode): (JSC::NewExprNode::emitCode): (JSC::EvalFunctionCallNode::emitCode): (JSC::FunctionCallValueNode::emitCode): (JSC::FunctionCallResolveNode::emitCode): (JSC::FunctionCallBracketNode::emitCode): (JSC::FunctionCallDotNode::emitCode): (JSC::PostfixResolveNode::emitCode): (JSC::DeleteResolveNode::emitCode): (JSC::TypeOfResolveNode::emitCode): (JSC::PrefixResolveNode::emitCode): (JSC::ReadModifyResolveNode::emitCode): (JSC::AssignResolveNode::emitCode): (JSC::ConstDeclNode::emitCodeSingle): (JSC::ForInNode::emitCode):

Added abstraction for getting exception info out of a call through a
register:

  • masm/X86Assembler.h: (JSC::X86Assembler::emitCall):


Removed duplicate #if:

  • wtf/Platform.h:
File:
1 edited

Legend:

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

    r36808 r36821  
    8484#endif
    8585
     86#if ENABLE(CTI)
     87
     88ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
     89{
     90    if (pc >= codeBlock->instructions.begin() && pc < codeBlock->instructions.end())
     91        return static_cast<Instruction*>(pc);
     92
     93    ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(pc));
     94    unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(pc);
     95    return codeBlock->instructions.begin() + vPCIndex;
     96}
     97
     98#else // #ENABLE(CTI)
     99
     100ALWAYS_INLINE static Instruction* vPCForPC(CodeBlock*, void* pc)
     101{
     102    return static_cast<Instruction*>(pc);
     103}
     104
     105#endif // #ENABLE(CTI)
     106
    86107// Returns the depth of the scope chain within a given call frame.
    87108static int depth(CodeBlock* codeBlock, ScopeChain& sc)
     
    499520}
    500521
    501 ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argv, int argc, JSValue* function)
     522ALWAYS_INLINE void Machine::initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, Register* r, int returnValueRegister, int argc, JSValue* function)
    502523{
    503524    callFrame[RegisterFile::CallerCodeBlock] = codeBlock;
    504     callFrame[RegisterFile::ReturnVPC] = vPC + 1;
    505525    callFrame[RegisterFile::CallerScopeChain] = scopeChain;
    506526    callFrame[RegisterFile::CallerRegisters] = r;
     527    callFrame[RegisterFile::ReturnPC] = vPC + 1;
    507528    callFrame[RegisterFile::ReturnValueRegister] = returnValueRegister;
    508     callFrame[RegisterFile::ArgumentStartRegister] = argv; // original argument vector (for the sake of the "arguments" object)
    509529    callFrame[RegisterFile::ArgumentCount] = argc; // original argument count (for the sake of the "arguments" object)
    510530    callFrame[RegisterFile::Callee] = function;
     
    512532}
    513533
    514 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* registerBase, Register* r, int argv, int argc, JSValue*& exceptionValue)
    515 {
    516     size_t registerOffset = argv + newCodeBlock->numLocals;
    517     size_t size = r - registerBase + registerOffset + newCodeBlock->numConstants + newCodeBlock->numTemporaries;
     534ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register* registerBase, Register* r, size_t registerOffset, int argc, JSValue*& exceptionValue)
     535{
     536    size_t size = r - registerBase + registerOffset + newCodeBlock->numCalleeRegisters;
    518537
    519538    if (argc == newCodeBlock->numParameters) { // correct number of arguments
     
    524543        r += registerOffset;
    525544    } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
     545        size_t omittedArgCount = newCodeBlock->numParameters - argc;
     546        registerOffset += omittedArgCount;
     547        size += omittedArgCount;
    526548        if (!registerFile->grow(size)) {
    527549            exceptionValue = createStackOverflowError(exec);
     
    530552        r += registerOffset;
    531553
    532         int omittedArgCount = newCodeBlock->numParameters - argc;
    533         Register* endOfParams = r - newCodeBlock->numVars;
    534         for (Register* it = endOfParams - omittedArgCount; it != endOfParams; ++it)
    535             (*it) = jsUndefined();
    536     } else { // too many arguments -- copy return info and expected arguments, leaving the extra arguments behind
    537         int shift = argc + RegisterFile::CallFrameHeaderSize;
    538         registerOffset += shift;
    539         size += shift;
     554        Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
     555        for (size_t i = 0; i < omittedArgCount; ++i)
     556            argv[i] = jsUndefined();
     557    } else { // too many arguments -- copy expected arguments, leaving the extra arguments behind
     558        size_t numParameters = newCodeBlock->numParameters;
     559        registerOffset += numParameters;
     560        size += numParameters;
    540561
    541562        if (!registerFile->grow(size)) {
     
    545566        r += registerOffset;
    546567
    547         Register* it = r - newCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize - shift;
    548         Register* end = it + RegisterFile::CallFrameHeaderSize + newCodeBlock->numParameters;
    549         for ( ; it != end; ++it)
    550             *(it + shift) = *it;
    551     }
    552    
    553     // initialize local variable slots
    554 #if ENABLE(CTI)
    555     if (!newCodeBlock->ctiCode)
    556 #endif
    557     {
    558 
     568        Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argc;
     569        for (size_t i = 0; i < numParameters; ++i)
     570            argv[i + argc] = argv[i];
    559571    }
    560572
     
    566578    if (newCodeBlock->needsFullScopeChain) {
    567579        JSActivation* activation = new (exec) JSActivation(exec, functionBodyNode, r);
    568         r[RegisterFile::OptionalCalleeActivation - RegisterFile::CallFrameHeaderSize - newCodeBlock->numLocals] = activation;
     580        r[RegisterFile::OptionalCalleeActivation] = activation;
    569581
    570582        return callDataScopeChain->copy()->push(activation);
     
    602614    JSValue* result = 0;
    603615    if (evalNode)
    604         result = exec->globalData().machine->execute(evalNode.get(), exec, thisObj, r - registerFile->base() + argv + argc, scopeChain, &exceptionValue);
     616        result = exec->globalData().machine->execute(evalNode.get(), exec, thisObj, r - registerFile->base() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
    605617
    606618    if (*profiler)
     
    684696    }
    685697   
    686     it = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    687     printf("[CallerCodeBlock]          | %10p | %10p \n", it, (*it).v()); ++it;
    688     printf("[ReturnVPC]                | %10p | %10p \n", it, (*it).v()); ++it;
    689     printf("[CallerScopeChain]         | %10p | %10p \n", it, (*it).v()); ++it;
    690     printf("[CallerRegisterOffset]     | %10p | %10p \n", it, (*it).v()); ++it;
    691     printf("[ReturnValueRegister]      | %10p | %10p \n", it, (*it).v()); ++it;
    692     printf("[ArgumentStartRegister]    | %10p | %10p \n", it, (*it).v()); ++it;
    693     printf("[ArgumentCount]            | %10p | %10p \n", it, (*it).v()); ++it;
    694     printf("[Callee]                   | %10p | %10p \n", it, (*it).v()); ++it;
    695     printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it;
    696     printf("----------------------------------------------------\n");
    697 
     698    it = r - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters;
    698699    printf("[this]                     | %10p | %10p \n", it, (*it).v()); ++it;
    699700    end = it + max(codeBlock->numParameters - 1, 0); // - 1 to skip "this"
     
    706707    printf("----------------------------------------------------\n");
    707708
    708     if (codeBlock->codeType != GlobalCode) {
    709         end = it + codeBlock->numVars;
    710         if (it != end) {
    711             do {
    712                 printf("[var]                      | %10p | %10p \n", it, (*it).v());
    713                 ++it;
    714             } while (it != end);
    715         printf("----------------------------------------------------\n");
    716         }
    717     }
    718 
    719     end = it + codeBlock->numTemporaries;
     709    printf("[CallerCodeBlock]          | %10p | %10p \n", it, (*it).v()); ++it;
     710    printf("[CallerScopeChain]         | %10p | %10p \n", it, (*it).v()); ++it;
     711    printf("[CallerRegisters]          | %10p | %10p \n", it, (*it).v()); ++it;
     712    printf("[ReturnPC]                 | %10p | %10p \n", it, (*it).v()); ++it;
     713    printf("[ReturnValueRegister]      | %10p | %10p \n", it, (*it).v()); ++it;
     714    printf("[ArgumentCount]            | %10p | %10p \n", it, (*it).v()); ++it;
     715    printf("[Callee]                   | %10p | %10p \n", it, (*it).v()); ++it;
     716    printf("[OptionalCalleeActivation] | %10p | %10p \n", it, (*it).v()); ++it;
     717    printf("----------------------------------------------------\n");
     718
     719    int registerCount = 0;
     720
     721    end = it + codeBlock->numVars;
    720722    if (it != end) {
    721723        do {
    722             printf("[temp]                     | %10p | %10p \n", it, (*it).v());
     724            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
    723725            ++it;
     726            ++registerCount;
    724727        } while (it != end);
    725728    }
     729    printf("----------------------------------------------------\n");
     730
     731    end = it + codeBlock->numConstants;
     732    if (it != end) {
     733        do {
     734            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
     735            ++it;
     736            ++registerCount;
     737        } while (it != end);
     738    }
     739    printf("----------------------------------------------------\n");
     740
     741    end = it + codeBlock->numCalleeRegisters - codeBlock->numConstants - codeBlock->numVars;
     742    if (it != end) {
     743        do {
     744            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
     745            ++it;
     746            ++registerCount;
     747        } while (it != end);
     748    }
     749    printf("----------------------------------------------------\n");
    726750}
    727751
     
    746770{
    747771    CodeBlock* oldCodeBlock = codeBlock;
    748     Register* callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    749772
    750773    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
    751774        DebuggerCallFrame debuggerCallFrame(exec, exec->dynamicGlobalObject(), codeBlock, scopeChain, r, exceptionValue);
    752         if (callFrame[RegisterFile::Callee].jsValue(exec))
     775        if (r[RegisterFile::Callee].jsValue(exec))
    753776            debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine());
    754777        else
     
    757780
    758781    if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
    759         if (callFrame[RegisterFile::Callee].jsValue(exec))
    760             profiler->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec)));
     782        if (r[RegisterFile::Callee].jsValue(exec))
     783            profiler->didExecute(exec, static_cast<JSObject*>(r[RegisterFile::Callee].jsValue(exec)));
    761784        else
    762785            profiler->didExecute(exec, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo());
     
    767790
    768791    // If this call frame created an activation, tear it off.
    769     if (JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
     792    if (JSActivation* activation = static_cast<JSActivation*>(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
    770793        ASSERT(activation->isActivationObject());
    771794        activation->copyRegisters();
    772795    }
    773796   
    774     codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
     797    codeBlock = r[RegisterFile::CallerCodeBlock].codeBlock();
    775798    if (!codeBlock)
    776799        return false;
    777800
    778     scopeChain = callFrame[RegisterFile::CallerScopeChain].scopeChain();
    779     r = callFrame[RegisterFile::CallerRegisters].r();
    780     exec->m_callFrame = r - oldCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    781     vPC = callFrame[RegisterFile::ReturnVPC].vPC();
     801    scopeChain = r[RegisterFile::CallerScopeChain].scopeChain();
     802    vPC = vPCForPC(codeBlock, r[RegisterFile::ReturnPC].v());
     803    r = r[RegisterFile::CallerRegisters].r();
     804    exec->m_callFrame = r;
    782805
    783806    return true;
     
    863886
    864887    size_t oldSize = m_registerFile.size();
    865     size_t newSize = oldSize + RegisterFile::CallFrameHeaderSize + codeBlock->numVars + codeBlock->numConstants + codeBlock->numTemporaries;
     888    size_t newSize = oldSize + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->numCalleeRegisters;
    866889    if (!m_registerFile.grow(newSize)) {
    867890        *exception = createStackOverflowError(exec);
     
    873896    globalObject->copyGlobalsTo(m_registerFile);
    874897
    875     Register* callFrame = m_registerFile.base() + oldSize;
    876 
    877     // a 0 codeBlock indicates a built-in caller
    878     initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0);
    879 
    880     Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
     898    Register* r = m_registerFile.base() + oldSize + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize;
    881899    r[codeBlock->thisRegister] = thisObj;
    882 
    883     for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i)
    884         r[i] = codeBlock->constantRegisters[i];
     900    initializeCallFrame(r, 0, 0, 0, 0, 0, 0, 0);
    885901
    886902    if (codeBlock->needsFullScopeChain)
     
    922938    }
    923939
    924     int argv = RegisterFile::CallFrameHeaderSize;
    925     int argc = args.size() + 1; // implicit "this" parameter
    926 
    927940    size_t oldSize = m_registerFile.size();
    928     if (!m_registerFile.grow(oldSize + RegisterFile::CallFrameHeaderSize + argc)) {
     941    int argc = 1 + args.size(); // implicit "this" parameter
     942
     943    if (!m_registerFile.grow(oldSize + argc)) {
    929944        *exception = createStackOverflowError(exec);
    930945        return 0;
    931946    }
    932947
    933     Register* callFrame = m_registerFile.base() + oldSize;
    934 
    935     // put args in place, including "this"
    936     Register* dst = callFrame + RegisterFile::CallFrameHeaderSize;
    937     (*dst) = thisObj;
     948    Register* argv = m_registerFile.base() + oldSize;
     949    size_t dst = 0;
     950    argv[dst] = thisObj;
    938951
    939952    ArgList::const_iterator end = args.end();
    940953    for (ArgList::const_iterator it = args.begin(); it != end; ++it)
    941         (*++dst) = *it;
    942 
    943     // a 0 codeBlock indicates a built-in caller
    944     initializeCallFrame(callFrame, 0, 0, 0, callFrame, 0, argv, argc, function);
     954        argv[++dst] = *it;
    945955
    946956    CodeBlock* newCodeBlock = &functionBodyNode->byteCode(scopeChain);
    947     Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), callFrame, argv, argc, *exception);
    948     if (*exception) {
     957    Register* r = slideRegisterWindowForCall(exec, newCodeBlock, &m_registerFile, m_registerFile.base(), argv, argc + RegisterFile::CallFrameHeaderSize, argc, *exception);
     958    if (UNLIKELY(*exception != 0)) {
    949959        m_registerFile.shrink(oldSize);
    950960        return 0;
    951961    }
    952 
    953     ExecState newExec(exec, &m_registerFile, scopeChain, callFrame);
     962    // a 0 codeBlock indicates a built-in caller
     963    initializeCallFrame(r, 0, 0, 0, argv, 0, argc, function);
     964
     965    ExecState newExec(exec, &m_registerFile, scopeChain, r);
    954966
    955967    Profiler** profiler = Profiler::enabledProfilerReference();
     
    974986}
    975987
     988JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception)
     989{
     990    return execute(evalNode, exec, thisObj, m_registerFile.size() + evalNode->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
     991}
     992
    976993JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
    977994{
     
    10161033
    10171034    size_t oldSize = m_registerFile.size();
    1018     size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numConstants + codeBlock->numTemporaries + RegisterFile::CallFrameHeaderSize;
     1035    size_t newSize = registerOffset + codeBlock->numCalleeRegisters;
    10191036    if (!m_registerFile.grow(newSize)) {
    10201037        *exception = createStackOverflowError(exec);
     
    10221039    }
    10231040
    1024     Register* callFrame = m_registerFile.base() + registerOffset;
     1041    Register* r = m_registerFile.base() + registerOffset;
    10251042
    10261043    // a 0 codeBlock indicates a built-in caller
    1027     initializeCallFrame(callFrame, 0, 0, 0, 0, 0, 0, 0, 0);
    1028 
    1029     Register* r = callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numVars;
    10301044    r[codeBlock->thisRegister] = thisObj;
    1031 
    1032     for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i)
    1033         r[i] = codeBlock->constantRegisters[i];
     1045    initializeCallFrame(r, 0, 0, 0, 0, 0, 0, 0);
    10341046
    10351047    if (codeBlock->needsFullScopeChain)
     
    31803192        int firstArg = (++vPC)->u.operand;
    31813193        int argCount = (++vPC)->u.operand;
     3194        ++vPC; // registerOffset
    31823195
    31833196        JSValue* funcVal = r[func].jsValue(exec);
     
    31993212        // this instruction as a normal function call, supplying the proper 'this'
    32003213        // value.
    3201         vPC -= 5;
     3214        vPC -= 6;
    32023215        r[thisVal] = baseVal->toThisObject(exec);
    32033216
     
    32113224    }
    32123225    BEGIN_OPCODE(op_call) {
    3213         /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
     3226        /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n)
    32143227
    32153228           Perform a function call. Specifically, call register func
     
    32523265        int firstArg = (++vPC)->u.operand;
    32533266        int argCount = (++vPC)->u.operand;
     3267        int registerOffset = (++vPC)->u.operand;
    32543268
    32553269        JSValue* v = r[func].jsValue(exec);
     
    32583272        CallType callType = v->getCallData(callData);
    32593273
    3260         if (*enabledProfilerReference)
    3261             (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
    3262 
    3263         Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    3264         initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, v);
    3265         exec->m_callFrame = callFrame;
    3266 
    32673274        if (callType == CallTypeJS) {
    3268 
    32693275            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
    32703276            FunctionBodyNode* functionBodyNode = callData.js.functionBody;
     
    32723278
    32733279            r[firstArg] = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : r[thisVal].jsValue(exec);
    3274 
    3275             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
     3280           
     3281            Register* savedR = r;
     3282
     3283            r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue);
    32763284            if (UNLIKELY(exceptionValue != 0))
    32773285                goto vm_throw;
     3286
     3287            initializeCallFrame(r, codeBlock, vPC, scopeChain, savedR, dst, argCount, v);
     3288            exec->m_callFrame = r;
     3289   
     3290            if (*enabledProfilerReference)
     3291                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
    32783292
    32793293            codeBlock = newCodeBlock;
     
    32843298            OpcodeStats::resetLastInstruction();
    32853299#endif
    3286            
     3300
    32873301            NEXT_OPCODE;
    32883302        }
     
    32923306            ArgList args(r + firstArg + 1, argCount - 1);
    32933307
     3308            initializeCallFrame(r + registerOffset, codeBlock, vPC, scopeChain, r, dst, argCount, v);
     3309            exec->m_callFrame = r + registerOffset;
     3310
     3311            if (*enabledProfilerReference)
     3312                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
     3313
    32943314            MACHINE_SAMPLING_callingHostFunction();
    32953315
    32963316            JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(v), thisValue, args);
    3297             exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
     3317            exec->m_callFrame = r;
    32983318            VM_CHECK_EXCEPTION();
    32993319
     
    33103330
    33113331        exceptionValue = createNotAFunctionError(exec, v, vPC, codeBlock);
    3312         exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    33133332        goto vm_throw;
    33143333    }
     
    33253344        int result = (++vPC)->u.operand;
    33263345
    3327         Register* callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    3328         if (JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
     3346        if (JSActivation* activation = static_cast<JSActivation*>(r[RegisterFile::OptionalCalleeActivation].jsValue(exec))) {
    33293347            ASSERT(!codeBlock->needsFullScopeChain || scopeChain->object == activation);
    33303348            ASSERT(activation->isActivationObject());
     
    33333351
    33343352        if (*enabledProfilerReference)
    3335             (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec)));
     3353            (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(r[RegisterFile::Callee].jsValue(exec)));
    33363354
    33373355        if (codeBlock->needsFullScopeChain)
     
    33403358        JSValue* returnValue = r[result].jsValue(exec);
    33413359
    3342         codeBlock = callFrame[RegisterFile::CallerCodeBlock].codeBlock();
     3360        codeBlock = r[RegisterFile::CallerCodeBlock].codeBlock();
    33433361        if (!codeBlock)
    33443362            return returnValue;
    33453363
    3346         vPC = callFrame[RegisterFile::ReturnVPC].vPC();
    3347         setScopeChain(exec, scopeChain, callFrame[RegisterFile::CallerScopeChain].scopeChain());
    3348         r = callFrame[RegisterFile::CallerRegisters].r();
    3349         exec->m_callFrame = r - codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    3350         int dst = callFrame[RegisterFile::ReturnValueRegister].i();
     3364        vPC = r[RegisterFile::ReturnPC].vPC();
     3365        setScopeChain(exec, scopeChain, r[RegisterFile::CallerScopeChain].scopeChain());
     3366        int dst = r[RegisterFile::ReturnValueRegister].i();
     3367        r = r[RegisterFile::CallerRegisters].r();
     3368        exec->m_callFrame = r;
    33513369        r[dst] = returnValue;
    33523370
    33533371        NEXT_OPCODE;
    33543372    }
    3355     BEGIN_OPCODE(op_initialise_locals) {
    3356         for (Register* it = r - codeBlock->numVars + (codeBlock->codeType == EvalCode); it < r; ++it)
    3357             (*it) = jsUndefined();
    3358         for (size_t i = 0; i < codeBlock->constantRegisters.size(); ++i)
    3359             r[i] = codeBlock->constantRegisters[i];
     3373    BEGIN_OPCODE(op_init) {
     3374        size_t i = 0;
     3375
     3376        for (size_t count = codeBlock->numVars; i < count; ++i)
     3377            r[i] = jsUndefined();
     3378
     3379        for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
     3380            r[i] = codeBlock->constantRegisters[j];
     3381
    33603382        ++vPC;
    33613383        NEXT_OPCODE;
    33623384    }
    33633385    BEGIN_OPCODE(op_construct) {
    3364         /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n)
     3386        /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n)
    33653387
    33663388           Invoke register "constr" as a constructor. For JS
     
    33813403        int firstArg = (++vPC)->u.operand;
    33823404        int argCount = (++vPC)->u.operand;
    3383 
    3384         JSValue* constrVal = r[constr].jsValue(exec);
     3405        int registerOffset = (++vPC)->u.operand;
     3406
     3407        JSValue* v = r[constr].jsValue(exec);
    33853408
    33863409        ConstructData constructData;
    3387         ConstructType constructType = constrVal->getConstructData(constructData);
    3388 
    3389         // Removing this line of code causes a measurable regression on squirrelfish.
    3390         JSObject* constructor = static_cast<JSObject*>(constrVal);
     3410        ConstructType constructType = v->getConstructData(constructData);
    33913411
    33923412        if (constructType == ConstructTypeJS) {
    33933413            if (*enabledProfilerReference)
    3394                 (*enabledProfilerReference)->willExecute(exec, constructor);
     3414                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
    33953415
    33963416            StructureID* structure;
     
    34083428            r[firstArg] = newObject; // "this" value
    34093429
    3410             Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    3411             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, r, dst, firstArg, argCount, constructor);
    3412             exec->m_callFrame = callFrame;
    3413 
    3414             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
    3415             if (exceptionValue)
     3430            Register* savedR = r;
     3431
     3432            r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue);
     3433            if (UNLIKELY(exceptionValue != 0))
    34163434                goto vm_throw;
     3435
     3436            initializeCallFrame(r, codeBlock, vPC, scopeChain, savedR, dst, argCount, v);
     3437            exec->m_callFrame = r;
     3438   
     3439            if (*enabledProfilerReference)
     3440                (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
    34173441
    34183442            codeBlock = newCodeBlock;
     
    34203444            vPC = codeBlock->instructions.begin();
    34213445
     3446#if DUMP_OPCODE_STATS
     3447            OpcodeStats::resetLastInstruction();
     3448#endif
     3449
    34223450            NEXT_OPCODE;
    34233451        }
    34243452
    34253453        if (constructType == ConstructTypeHost) {
     3454            ArgList args(r + firstArg + 1, argCount - 1);
     3455
     3456            initializeCallFrame(r + registerOffset, codeBlock, vPC, scopeChain, r, dst, argCount, v);
     3457            exec->m_callFrame = r + registerOffset;
     3458
    34263459            if (*enabledProfilerReference)
    3427                 (*enabledProfilerReference)->willExecute(exec, constructor);
    3428 
    3429             ArgList args(r + firstArg + 1, argCount - 1);
     3460                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
    34303461
    34313462            MACHINE_SAMPLING_callingHostFunction();
    34323463
    3433             JSValue* returnValue = constructData.native.function(exec, constructor, args);
     3464            JSValue* returnValue = constructData.native.function(exec, static_cast<JSObject*>(v), args);
     3465            exec->m_callFrame = r;
    34343466
    34353467            VM_CHECK_EXCEPTION();
     
    34373469
    34383470            if (*enabledProfilerReference)
    3439                 (*enabledProfilerReference)->didExecute(exec, constructor);
     3471                (*enabledProfilerReference)->didExecute(exec, static_cast<JSObject*>(v));
    34403472
    34413473            ++vPC;
     
    34453477        ASSERT(constructType == ConstructTypeNone);
    34463478
    3447         exceptionValue = createNotAConstructorError(exec, constrVal, vPC, codeBlock);
     3479        exceptionValue = createNotAConstructorError(exec, v, vPC, codeBlock);
    34483480        goto vm_throw;
    34493481    }
     
    37773809    JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec));
    37783810    if (!activation) {
    3779         CodeBlock* codeBlock = &function->m_body->generatedByteCode();
    3780         activation = new (exec) JSActivation(exec, function->m_body, callFrame + RegisterFile::CallFrameHeaderSize + codeBlock->numLocals);
     3811        activation = new (exec) JSActivation(exec, function->m_body, callFrame);
    37813812        callFrame[RegisterFile::OptionalCalleeActivation] = activation;
    37823813    }
     
    37953826        return jsNull();
    37963827
    3797     Register* callerCallFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
     3828    Register* callerCallFrame = callFrame[RegisterFile::CallerRegisters].r();
    37983829    if (JSValue* caller = callerCallFrame[RegisterFile::Callee].jsValue(exec))
    37993830        return caller;
     
    38163847        return;
    38173848
    3818     Instruction* vPC = callFrame[RegisterFile::ReturnVPC].vPC();
     3849    Instruction* vPC = vPCForPC(callerCodeBlock, callFrame[RegisterFile::ReturnPC].v());
    38193850    lineNumber = callerCodeBlock->lineNumberForVPC(vPC - 1);
    38203851    sourceId = callerCodeBlock->ownerNode->sourceId();
     
    38473878        }
    38483879       
    3849         callFrame = callFrame[RegisterFile::CallerRegisters].r() - callerCodeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    3850     }
    3851 }
    3852 
    3853 void Machine::getArgumentsData(Register* callFrame, JSFunction*& function, Register*& argv, int& argc)
     3880        callFrame = callFrame[RegisterFile::CallerRegisters].r();
     3881    }
     3882}
     3883
     3884void Machine::getArgumentsData(Register* callFrame, JSFunction*& function, int& firstParameterIndex, Register*& argv, int& argc)
    38543885{
    38553886    function = static_cast<JSFunction*>(callFrame[RegisterFile::Callee].getJSValue());
    38563887    ASSERT(function->inherits(&JSFunction::info));
    3857 
    3858     argv = callFrame[RegisterFile::CallerRegisters].r() + callFrame[RegisterFile::ArgumentStartRegister].i() + 1; //  + 1 to skip "this"
    3859     argc = callFrame[RegisterFile::ArgumentCount].i() - 1; // - 1 to skip "this"
     3888   
     3889    CodeBlock* codeBlock = &function->m_body->generatedByteCode();
     3890    int numParameters = codeBlock->numParameters;
     3891    argc = callFrame[RegisterFile::ArgumentCount].i();
     3892
     3893    if (argc <= numParameters)
     3894        argv = callFrame - RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
     3895    else
     3896        argv = callFrame - RegisterFile::CallFrameHeaderSize - numParameters - argc + 1; // + 1 to skip "this"
     3897
     3898    argc -= 1; // - 1 to skip "this"
     3899    firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
    38603900}
    38613901
     
    43704410    Register* r = ARG_r;
    43714411
    4372     JSValue* exceptionValue = 0;
    43734412    Register* registerBase = registerFile->base();
    43744413   
    43754414    JSValue* funcVal = ARG_src1;
    4376     JSValue* thisValue = ARG_src2;
    4377     int firstArg = ARG_int3;
    4378     int argCount = ARG_int4;
    4379 
    4380     // In the JIT code before entering this function we wil have checked the vptr,
    4381     // and know this is an object of type JSFunction.
     4415    int registerOffset = ARG_int2;
     4416    int argCount = ARG_int3;
     4417
    43824418#ifndef NDEBUG
    43834419    CallData callData;
     4420    ASSERT(funcVal->getCallData(callData) == CallTypeJS);
    43844421#endif
    4385     ASSERT(funcVal->getCallData(callData) == CallTypeJS);
    43864422
    43874423    if (*ARG_profilerReference)
     
    43924428
    43934429    CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
    4394 
    4395     r[firstArg] = thisValue;
    4396 
    4397     Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    4398     exec->m_callFrame = callFrame;
    4399 
    4400     r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
     4430   
     4431    Register* savedR = r;
     4432
     4433    JSValue* exceptionValue = 0;
     4434    r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue);
    44014435    JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
    4402    
     4436
     4437    // RegisterFile::CallerCodeBlock is set by caller
     4438    r[RegisterFile::CallerScopeChain] = ARG_scopeChain;
     4439    r[RegisterFile::CallerRegisters] = savedR;
     4440    // RegisterFile::ReturnPC is set by callee
     4441    // RegisterFile::ReturnValueRegister is set by caller
     4442    r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object)
     4443    r[RegisterFile::Callee] = funcVal;
     4444    r[RegisterFile::OptionalCalleeActivation] = nullJSValue;
     4445
     4446    exec->m_callFrame = r;
    44034447    exec->m_scopeChain = callDataScopeChain;
    44044448
     
    44344478{
    44354479    ExecState* exec = ARG_exec;
    4436     Register* r = ARG_r;
    44374480
    44384481    JSValue* funcVal = ARG_src1;
    4439     JSValue* thisValue = ARG_src2;
    4440     int firstArg = ARG_int3;
    4441     int argCount = ARG_int4;
    44424482
    44434483    CallData callData;
     
    44474487
    44484488    if (callType == CallTypeHost) {
    4449         Register* oldCallFrame = exec->m_callFrame;
    4450         Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    4451         exec->m_callFrame = callFrame;
     4489        int registerOffset = ARG_int2;
     4490        int argCount = ARG_int3;
     4491        Register* r = ARG_r + registerOffset;
     4492       
     4493        initializeCallFrame(r, ARG_codeBlock, ARG_instr4, ARG_scopeChain, ARG_r, 0, argCount, funcVal);
     4494        exec->m_callFrame = r;
    44524495
    44534496        if (*ARG_profilerReference)
    44544497            (*ARG_profilerReference)->willExecute(exec, static_cast<JSObject*>(funcVal));
    44554498
    4456         ArgList argList(r + firstArg + 1, argCount - 1);
     4499        Register* argv = r - RegisterFile::CallFrameHeaderSize - argCount;
     4500        ArgList argList(argv + 1, argCount - 1);
    44574501
    44584502        CTI_MACHINE_SAMPLING_callingHostFunction();
    44594503
    4460         JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(funcVal), thisValue, argList);
    4461         exec->m_callFrame = oldCallFrame;
     4504        JSValue* returnValue = callData.native.function(exec, static_cast<JSObject*>(funcVal), argv[0].jsValue(exec), argList);
    44624505        VM_CHECK_EXCEPTION(JSValue*);
    44634506
     
    44654508            (*ARG_profilerReference)->didExecute(exec, static_cast<JSObject*>(funcVal));
    44664509
     4510        exec->m_callFrame = ARG_r;
    44674511        return returnValue;
    4468 
    44694512    }
    44704513
    44714514    ASSERT(callType == CallTypeNone);
    44724515
    4473     exec->setException(createNotAFunctionError(exec, funcVal, ARG_instr5, ARG_codeBlock));
     4516    exec->setException(createNotAFunctionError(exec, funcVal, ARG_instr4, ARG_codeBlock));
    44744517    VM_CHECK_EXCEPTION_AT_END();
    44754518    return 0;
     
    44794522{
    44804523    ExecState* exec = ARG_exec;
    4481     Register* callFrame = ARG_r - ARG_codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
     4524    Register* callFrame = ARG_r;
    44824525
    44834526    JSActivation* activation = static_cast<JSActivation*>(callFrame[RegisterFile::OptionalCalleeActivation].jsValue(exec));
     
    44934536    ExecState* exec = ARG_exec;
    44944537
    4495     Register* callFrame = ARG_r - ARG_codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
     4538    Register* callFrame = ARG_r;
    44964539    ASSERT(*ARG_profilerReference);
    44974540    (*ARG_profilerReference)->didExecute(exec, static_cast<JSObject*>(callFrame[RegisterFile::Callee].jsValue(exec)));
     
    45444587    RegisterFile* registerFile = ARG_registerFile;
    45454588    Register* r = ARG_r;
    4546     ScopeChainNode* scopeChain = ARG_scopeChain;
    4547 
    4548     JSValue* exceptionValue = 0;
     4589
    45494590    Register* registerBase = registerFile->base();
    45504591   
     
    45524593    JSValue* constrProtoVal = ARG_src2;
    45534594    int firstArg = ARG_int3;
    4554     int argCount = ARG_int4;
    4555 
     4595    int registerOffset = ARG_int4;
     4596    int argCount = ARG_int5;
     4597
     4598#ifndef NDEBUG
    45564599    ConstructData constructData;
    4557 #ifndef NDEBUG
    4558     ConstructType constructType =
     4600    ASSERT(constrVal->getConstructData(constructData) == ConstructTypeJS);
    45594601#endif
    4560         constrVal->getConstructData(constructData);
    4561 
    4562     // Removing this line of code causes a measurable regression on sunspider.
    4563     JSObject* constructor = static_cast<JSObject*>(constrVal);
    4564 
    4565     ASSERT(constructType == ConstructTypeJS);
     4602
     4603    JSFunction* constructor = static_cast<JSFunction*>(constrVal);
    45664604
    45674605    if (*ARG_profilerReference)
     
    45724610        structure = static_cast<JSObject*>(constrProtoVal)->inheritorID();
    45734611    else
    4574         structure = scopeChain->globalObject()->emptyObjectStructure();
     4612        structure = ARG_scopeChain->globalObject()->emptyObjectStructure();
    45754613    JSObject* newObject = new (exec) JSObject(structure);
    45764614
    4577     ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
    4578     FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
     4615    ScopeChainNode* callDataScopeChain = constructor->m_scopeChain.node();
     4616    FunctionBodyNode* functionBodyNode = constructor->m_body.get();
    45794617    CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
    45804618
    45814619    r[firstArg] = newObject; // "this" value
    45824620
    4583     Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    4584     exec->m_callFrame = callFrame;
    4585 
    4586     r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, firstArg, argCount, exceptionValue);
     4621    Register* savedR = r;
     4622
     4623    JSValue* exceptionValue = 0;
     4624    r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, r, registerOffset, argCount, exceptionValue);
    45874625    JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
    45884626
     4627    // RegisterFile::CallerCodeBlock is set by caller
     4628    r[RegisterFile::CallerScopeChain] = ARG_scopeChain;
     4629    r[RegisterFile::CallerRegisters] = savedR;
     4630    // RegisterFile::ReturnPC is set by callee
     4631    // RegisterFile::ReturnValueRegister is set by caller
     4632    r[RegisterFile::ArgumentCount] = argCount; // original argument count (for the sake of the "arguments" object)
     4633    r[RegisterFile::Callee] = constructor;
     4634    r[RegisterFile::OptionalCalleeActivation] = nullJSValue;
     4635
     4636    exec->m_callFrame = r;
    45894637    exec->m_scopeChain = callDataScopeChain;
    45904638
     
    46024650    JSValue* constrVal = ARG_src1;
    46034651    int firstArg = ARG_int3;
    4604     int argCount = ARG_int4;
     4652    int argCount = ARG_int5;
    46054653
    46064654    ConstructData constructData;
    46074655    ConstructType constructType = constrVal->getConstructData(constructData);
    46084656
    4609     // Removing this line of code causes a measurable regression on squirrelfish.
    46104657    JSObject* constructor = static_cast<JSObject*>(constrVal);
    46114658
    4612     ASSERT(constructType != ConstructTypeJS);
    4613 
    46144659    if (constructType == ConstructTypeHost) {
    4615         Register* oldCallFrame = exec->m_callFrame;
    4616         Register* callFrame = r + firstArg - RegisterFile::CallFrameHeaderSize;
    4617         exec->m_callFrame = callFrame;
    4618 
    46194660        if (*ARG_profilerReference)
    46204661            (*ARG_profilerReference)->willExecute(exec, constructor);
     
    46254666
    46264667        JSValue* returnValue = constructData.native.function(exec, constructor, argList);
    4627         exec->m_callFrame = oldCallFrame;
    46284668        VM_CHECK_EXCEPTION(JSValue*);
    46294669
     
    46364676    ASSERT(constructType == ConstructTypeNone);
    46374677
    4638     exec->setException(createNotAConstructorError(exec, constrVal, ARG_instr5, ARG_codeBlock));
     4678    exec->setException(createNotAConstructorError(exec, constrVal, ARG_instr6, ARG_codeBlock));
    46394679    VM_CHECK_EXCEPTION_AT_END();
    46404680    return 0;
     
    51945234
    51955235    Machine* machine = exec->machine();
    5196     JSValue* exceptionValue = 0;
    51975236   
    51985237    JSValue* funcVal = ARG_src1;
    5199     JSValue* baseVal = ARG_src2;
    5200     int firstArg = ARG_int3;
    5201     int argCount = ARG_int4;
     5238    int registerOffset = ARG_int2;
     5239    int argCount = ARG_int3;
     5240    JSValue* baseVal = ARG_src5;
    52025241
    52035242    if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
    52045243        JSObject* thisObject = static_cast<JSObject*>(r[codeBlock->thisRegister].jsValue(exec));
    5205         JSValue* result = machine->callEval(exec, codeBlock, thisObject, scopeChain, registerFile,  r, firstArg, argCount, exceptionValue);
     5244        JSValue* exceptionValue = 0;
     5245        JSValue* result = machine->callEval(exec, codeBlock, thisObject, scopeChain, registerFile,  r, registerOffset - RegisterFile::CallFrameHeaderSize - argCount, argCount, exceptionValue);
    52065246        JSVALUE_VM_CHECK_EXCEPTION_ARG(exceptionValue);
    52075247        return result;
Note: See TracChangeset for help on using the changeset viewer.