Changeset 47597 in webkit


Ignore:
Timestamp:
Aug 20, 2009, 2:49:07 PM (16 years ago)
Author:
[email protected]
Message:

Remove FunctionCodeBlock.
https://bugs.webkit.org/show_bug.cgi?id=28502

Reviewed by Oliver Hunt.

These only exist to allow JIT code to dereference properties off the
CodeBlock for any callee, regardless of whether it is a host function.

Instead just use the FunctionExecutable. Copy the m_parameters field
from the CodeBlock into the Executable, and use this to distinguish
between host functions, functions that have been bytecompiled, and
functions that have not.

m_parameters is moved to ExecutableBase rather than FunctionExecutable
so that (as a separate change) we can move make a separate class of
executable for host code, which is not devived from FunctionExecutable
(host code does not feature any of the properties that normal executable
do and will provide, such as source, attributes, and a parsed name).

1% win on v8 tests, 0.5% on sunspider.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::derefStructures):
(JSC::CodeBlock::refStructures):
(JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
(JSC::CodeBlock::handlerForBytecodeOffset):
(JSC::CodeBlock::lineNumberForBytecodeOffset):
(JSC::CodeBlock::expressionRangeForBytecodeOffset):
(JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset):
(JSC::CodeBlock::functionRegisterForBytecodeOffset):
(JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset):
(JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):

  • bytecode/CodeBlock.h:

(JSC::):
(JSC::CodeBlock::source):
(JSC::CodeBlock::sourceOffset):
(JSC::CodeBlock::evalCodeCache):
(JSC::CodeBlock::createRareDataIfNecessary):

remove NativeCodeBlocks and the NativeCode code type.


  • jit/JIT.cpp:

(JSC::JIT::linkCall):

Revert to previous behaviour (as currently still commented!) that Hhost functions have a null codeblock.

  • jit/JITCall.cpp:

(JSC::JIT::compileOpCallInitializeCallFrame):
(JSC::JIT::compileOpCallSetupArgs):
(JSC::JIT::compileOpCallVarargsSetupArgs):
(JSC::JIT::compileOpConstructSetupArgs):
(JSC::JIT::compileOpCallVarargs):
(JSC::JIT::compileOpCall):
(JSC::JIT::compileOpCallSlowCase):

Bring the 32_64 & non-32_64 JITs into line with each other, callee in regT0.

  • jit/JITOpcodes.cpp:

(JSC::JIT::privateCompileCTIMachineTrampolines):

Rewrite call trampolines to not use the CodeBlock.

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

Make call_JSFunction & call_arityCheck return the callee, don't expect to be passed the CodeBlock.

  • runtime/Executable.cpp:

(JSC::FunctionExecutable::generateBytecode):
(JSC::FunctionExecutable::recompile):
(JSC::FunctionExecutable::FunctionExecutable):

  • runtime/Executable.h:

(JSC::ExecutableBase::):
(JSC::ExecutableBase::ExecutableBase):
(JSC::FunctionExecutable::isHostFunction):

Add m_numParameters.

  • runtime/JSFunction.cpp:

(JSC::JSFunction::~JSFunction):

Only call generatedBytecode() on JSFunctions non-host FunctionExecutables.

Location:
trunk/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r47592 r47597  
     12009-08-20  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Remove FunctionCodeBlock.
     6        https://bugs.webkit.org/show_bug.cgi?id=28502
     7
     8        These only exist to allow JIT code to dereference properties off the
     9        CodeBlock for any callee, regardless of whether it is a host function.
     10
     11        Instead just use the FunctionExecutable.  Copy the m_parameters field
     12        from the CodeBlock into the Executable, and use this to distinguish
     13        between host functions, functions that have been bytecompiled, and
     14        functions that have not.
     15
     16        m_parameters is moved to ExecutableBase rather than FunctionExecutable
     17        so that (as a separate change) we can move make a separate class of
     18        executable for host code, which is not devived from FunctionExecutable
     19        (host code does not feature any of the properties that normal executable
     20        do and will provide, such as source, attributes, and a parsed name).
     21
     22        1% win on v8 tests, 0.5% on sunspider.
     23
     24        * bytecode/CodeBlock.cpp:
     25        (JSC::CodeBlock::derefStructures):
     26        (JSC::CodeBlock::refStructures):
     27        (JSC::CodeBlock::reparseForExceptionInfoIfNecessary):
     28        (JSC::CodeBlock::handlerForBytecodeOffset):
     29        (JSC::CodeBlock::lineNumberForBytecodeOffset):
     30        (JSC::CodeBlock::expressionRangeForBytecodeOffset):
     31        (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset):
     32        (JSC::CodeBlock::functionRegisterForBytecodeOffset):
     33        (JSC::CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset):
     34        (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset):
     35        * bytecode/CodeBlock.h:
     36        (JSC::):
     37        (JSC::CodeBlock::source):
     38        (JSC::CodeBlock::sourceOffset):
     39        (JSC::CodeBlock::evalCodeCache):
     40        (JSC::CodeBlock::createRareDataIfNecessary):
     41       
     42            remove NativeCodeBlocks and the NativeCode code type.
     43       
     44        * jit/JIT.cpp:
     45        (JSC::JIT::linkCall):
     46
     47            Revert to previous behaviour (as currently still commented!) that Hhost functions have a null codeblock.
     48
     49        * jit/JITCall.cpp:
     50        (JSC::JIT::compileOpCallInitializeCallFrame):
     51        (JSC::JIT::compileOpCallSetupArgs):
     52        (JSC::JIT::compileOpCallVarargsSetupArgs):
     53        (JSC::JIT::compileOpConstructSetupArgs):
     54        (JSC::JIT::compileOpCallVarargs):
     55        (JSC::JIT::compileOpCall):
     56        (JSC::JIT::compileOpCallSlowCase):
     57
     58            Bring the 32_64 & non-32_64 JITs into line with each other, callee in regT0.
     59
     60        * jit/JITOpcodes.cpp:
     61        (JSC::JIT::privateCompileCTIMachineTrampolines):
     62
     63            Rewrite call trampolines to not use the CodeBlock.
     64
     65        * jit/JITStubs.cpp:
     66        (JSC::DEFINE_STUB_FUNCTION):
     67
     68            Make call_JSFunction & call_arityCheck return the callee, don't expect to be passed the CodeBlock.
     69
     70        * runtime/Executable.cpp:
     71        (JSC::FunctionExecutable::generateBytecode):
     72        (JSC::FunctionExecutable::recompile):
     73        (JSC::FunctionExecutable::FunctionExecutable):
     74        * runtime/Executable.h:
     75        (JSC::ExecutableBase::):
     76        (JSC::ExecutableBase::ExecutableBase):
     77        (JSC::FunctionExecutable::isHostFunction):
     78
     79            Add m_numParameters.
     80
     81        * runtime/JSFunction.cpp:
     82        (JSC::JSFunction::~JSFunction):
     83
     84            Only call generatedBytecode() on JSFunctions non-host FunctionExecutables.
     85
    1862009-08-20  Yongjun Zhang  <[email protected]>
    287
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r47412 r47597  
    12491249}
    12501250
    1251 CodeBlock::CodeBlock(ExecutableBase* ownerExecutable)
    1252     : m_numCalleeRegisters(0)
    1253     , m_numVars(0)
    1254     , m_numParameters(0)
    1255     , m_ownerExecutable(ownerExecutable)
    1256     , m_globalData(0)
    1257 #ifndef NDEBUG
    1258     , m_instructionCount(0)
    1259 #endif
    1260     , m_needsFullScopeChain(false)
    1261     , m_usesEval(false)
    1262     , m_isNumericCompareFunction(false)
    1263     , m_codeType(NativeCode)
    1264     , m_source(0)
    1265     , m_sourceOffset(0)
    1266     , m_exceptionInfo(0)
    1267 {
    1268 #if DUMP_CODE_BLOCK_STATISTICS
    1269     liveCodeBlockSet.add(this);
    1270 #endif
    1271 }
    1272 
    12731251CodeBlock::CodeBlock(ExecutableBase* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
    12741252    : m_numCalleeRegisters(0)
     
    13531331void CodeBlock::derefStructures(Instruction* vPC) const
    13541332{
    1355     ASSERT(m_codeType != NativeCode);
    13561333    Interpreter* interpreter = m_globalData->interpreter;
    13571334
     
    13991376void CodeBlock::refStructures(Instruction* vPC) const
    14001377{
    1401     ASSERT(m_codeType != NativeCode);
    14021378    Interpreter* interpreter = m_globalData->interpreter;
    14031379
     
    14461422void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
    14471423{
    1448     ASSERT(m_codeType != NativeCode);
    14491424    if (m_exceptionInfo)
    14501425        return;
     
    14681443HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
    14691444{
    1470     ASSERT(m_codeType != NativeCode);
    14711445    ASSERT(bytecodeOffset < m_instructionCount);
    14721446
     
    14871461int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset)
    14881462{
    1489     ASSERT(m_codeType != NativeCode);
    14901463    ASSERT(bytecodeOffset < m_instructionCount);
    14911464
     
    15131486int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
    15141487{
    1515     ASSERT(m_codeType != NativeCode);
    15161488    ASSERT(bytecodeOffset < m_instructionCount);
    15171489
     
    15531525bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID)
    15541526{
    1555     ASSERT(m_codeType != NativeCode);
    15561527    ASSERT(bytecodeOffset < m_instructionCount);
    15571528
     
    15821553bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex)
    15831554{
    1584     ASSERT(m_codeType != NativeCode);
    15851555    ASSERT(bytecodeOffset < m_instructionCount);
    15861556
     
    16091579bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
    16101580{
    1611     ASSERT(m_codeType != NativeCode);
    16121581    if (m_globalResolveInstructions.isEmpty())
    16131582        return false;
     
    16301599bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
    16311600{
    1632     ASSERT(m_codeType != NativeCode);
    16331601    if (m_globalResolveInfos.isEmpty())
    16341602        return false;
  • trunk/JavaScriptCore/bytecode/CodeBlock.h

    r47519 r47597  
    6262    class ExecState;
    6363
    64     enum CodeType { GlobalCode, EvalCode, FunctionCode, NativeCode };
     64    enum CodeType { GlobalCode, EvalCode, FunctionCode };
    6565
    6666    static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
     
    262262        friend class JIT;
    263263    protected:
    264         CodeBlock(ExecutableBase* ownerExecutable);
    265264        CodeBlock(ExecutableBase* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
    266265    public:
     
    379378        CodeType codeType() const { return m_codeType; }
    380379
    381         SourceProvider* source() const { ASSERT(m_codeType != NativeCode); return m_source.get(); }
    382         unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode); return m_sourceOffset; }
     380        SourceProvider* source() const { return m_source.get(); }
     381        unsigned sourceOffset() const { return m_sourceOffset; }
    383382
    384383        size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
     
    470469        SymbolTable& symbolTable() { return m_symbolTable; }
    471470
    472         EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode); createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
     471        EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
    473472
    474473        void shrinkToFit();
     
    489488        void createRareDataIfNecessary()
    490489        {
    491             ASSERT(m_codeType != NativeCode);
    492490            if (!m_rareData)
    493491                m_rareData.set(new RareData);
     
    620618    };
    621619
    622     class NativeCodeBlock : public CodeBlock {
    623     public:
    624         NativeCodeBlock(FunctionExecutable* ownerExecutable)
    625             : CodeBlock(ownerExecutable)
    626         {
    627         }
    628     };
    629 
    630620    inline Register& ExecState::r(int index)
    631621    {
  • trunk/JavaScriptCore/jit/JIT.cpp

    r47412 r47597  
    588588void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
    589589{
    590     ASSERT(calleeCodeBlock);
    591590    RepatchBuffer repatchBuffer(callerCodeBlock);
    592591
    593592    // Currently we only link calls with the exact number of arguments.
    594593    // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
    595     if (callerArgCount == calleeCodeBlock->m_numParameters || calleeCodeBlock->codeType() == NativeCode) {
     594    if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
    596595        ASSERT(!callLinkInfo->isLinked());
    597596   
  • trunk/JavaScriptCore/jit/JITCall.cpp

    r47186 r47597  
    440440    store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
    441441
    442     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
     442    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
    443443
    444444    storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register))));
    445     storePtr(regT2, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
     445    storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
    446446    storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
    447447}
     
    453453
    454454    // ecx holds func
    455     emitPutJITStubArg(regT2, 1);
     455    emitPutJITStubArg(regT0, 1);
    456456    emitPutJITStubArgConstant(argCount, 3);
    457457    emitPutJITStubArgConstant(registerOffset, 2);
     
    463463   
    464464    // ecx holds func
    465     emitPutJITStubArg(regT2, 1);
     465    emitPutJITStubArg(regT0, 1);
    466466    emitPutJITStubArg(regT1, 3);
    467     addPtr(Imm32(registerOffset), regT1, regT0);
    468     emitPutJITStubArg(regT0, 2);
     467    addPtr(Imm32(registerOffset), regT1, regT2);
     468    emitPutJITStubArg(regT2, 2);
    469469}
    470470
     
    477477
    478478    // ecx holds func
    479     emitPutJITStubArg(regT2, 1);
     479    emitPutJITStubArg(regT0, 1);
    480480    emitPutJITStubArgConstant(registerOffset, 2);
    481481    emitPutJITStubArgConstant(argCount, 3);
    482     emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
     482    emitPutJITStubArgFromVirtualRegister(proto, 4, regT2);
    483483    emitPutJITStubArgConstant(thisRegister, 5);
    484484}
     
    491491
    492492    emitGetVirtualRegister(argCountRegister, regT1);
    493     emitGetVirtualRegister(callee, regT2);
     493    emitGetVirtualRegister(callee, regT0);
    494494    compileOpCallVarargsSetupArgs(instruction);
    495495
    496496    // Check for JSFunctions.
    497     emitJumpSlowCaseIfNotJSCell(regT2);
    498     addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
    499    
     497    emitJumpSlowCaseIfNotJSCell(regT0);
     498    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
     499
    500500    // Speculatively roll the callframe, assuming argCount will match the arity.
    501     mul32(Imm32(sizeof(Register)), regT0, regT0);
     501    mul32(Imm32(sizeof(Register)), regT2, regT2);
    502502    intptr_t offset = (intptr_t)sizeof(Register) * (intptr_t)RegisterFile::CallerFrame;
    503     addPtr(Imm32((int32_t)offset), regT0, regT3);
     503    addPtr(Imm32((int32_t)offset), regT2, regT3);
    504504    addPtr(callFrameRegister, regT3);
    505505    storePtr(callFrameRegister, regT3);
    506     addPtr(regT0, callFrameRegister);
     506    addPtr(regT2, callFrameRegister);
    507507    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
    508508
     
    540540    if (opcodeID == op_call_eval) {
    541541        JITStubCall stubCall(this, cti_op_call_eval);
    542         stubCall.addArgument(callee, regT2);
     542        stubCall.addArgument(callee, regT0);
    543543        stubCall.addArgument(JIT::Imm32(registerOffset));
    544544        stubCall.addArgument(JIT::Imm32(argCount));
     
    547547    }
    548548
    549     emitGetVirtualRegister(callee, regT2);
     549    emitGetVirtualRegister(callee, regT0);
    550550    // The arguments have been set up on the hot path for op_call_eval
    551551    if (opcodeID == op_call)
     
    555555
    556556    // Check for JSFunctions.
    557     emitJumpSlowCaseIfNotJSCell(regT2);
    558     addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
     557    emitJumpSlowCaseIfNotJSCell(regT0);
     558    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
    559559
    560560    // First, in the case of a construct, allocate the new object.
    561561    if (opcodeID == op_construct) {
    562562        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
    563         emitGetVirtualRegister(callee, regT2);
     563        emitGetVirtualRegister(callee, regT0);
    564564    }
    565565
     
    607607    if (opcodeID == op_call_eval) {
    608608        JITStubCall stubCall(this, cti_op_call_eval);
    609         stubCall.addArgument(callee, regT2);
     609        stubCall.addArgument(callee, regT0);
    610610        stubCall.addArgument(JIT::Imm32(registerOffset));
    611611        stubCall.addArgument(JIT::Imm32(argCount));
     
    616616    // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
    617617    // This deliberately leaves the callee in ecx, used when setting up the stack frame below
    618     emitGetVirtualRegister(callee, regT2);
     618    emitGetVirtualRegister(callee, regT0);
    619619    DataLabelPtr addressOfLinkedFunctionCheck;
    620620
    621621    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
    622622
    623     Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT2, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue())));
     623    Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue())));
    624624
    625625    END_UNINTERRUPTED_SEQUENCE(sequenceOpCall);
     
    636636        int thisRegister = instruction[6].u.operand;
    637637
    638         emitPutJITStubArg(regT2, 1);
    639         emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
     638        emitPutJITStubArg(regT0, 1);
     639        emitPutJITStubArgFromVirtualRegister(proto, 4, regT2);
    640640        JITStubCall stubCall(this, cti_op_construct_JSConstruct);
    641641        stubCall.call(thisRegister);
    642         emitGetVirtualRegister(callee, regT2);
     642        emitGetVirtualRegister(callee, regT0);
    643643    }
    644644
     
    646646    // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
    647647    storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register))));
    648     storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
    649     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
     648    storePtr(regT0, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
     649    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
    650650    store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
    651651    storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
     
    681681
    682682    // Fast check for JS function.
    683     Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2);
    684     Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr));
     683    Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT0);
     684    Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr));
    685685
    686686    // First, in the case of a construct, allocate the new object.
    687687    if (opcodeID == op_construct) {
    688688        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
    689         emitGetVirtualRegister(callee, regT2);
     689        emitGetVirtualRegister(callee, regT0);
    690690    }
    691691
     
    694694    addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
    695695    move(Imm32(argCount), regT1);
     696
     697    move(regT0, regT2);
    696698
    697699    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink());
  • trunk/JavaScriptCore/jit/JITOpcodes.cpp

    r47530 r47597  
    6565
    6666#if ENABLE(JIT_OPTIMIZE_CALL)
    67     /* VirtualCallLink Trampoline */
     67    // VirtualCallLink Trampoline
     68    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
    6869    Label virtualCallLinkBegin = align();
    69 
    70     // regT0 holds callee, regT1 holds argCount.
    7170    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    72     loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT2);
    73     Jump hasCodeBlock2 = branchTestPtr(NonZero, regT2);
    74 
    75     // Lazily generate a CodeBlock.
    76     preserveReturnAddressAfterCall(regT3); // return address
     71
     72    Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     73
     74    Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     75    preserveReturnAddressAfterCall(regT3);
    7776    restoreArgumentReference();
    7877    Call callJSFunction2 = call();
    79     move(regT0, regT2);
    80     emitGetJITStubArg(1, regT0); // callee
     78    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    8179    emitGetJITStubArg(5, regT1); // argCount
    82     restoreReturnAddressBeforeReturn(regT3); // return address
     80    restoreReturnAddressBeforeReturn(regT3);
    8381    hasCodeBlock2.link(this);
    8482
    85     // regT2 holds codeBlock.
    86     Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    87 
    8883    // Check argCount matches callee arity.
    89     Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
     84    Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
    9085    preserveReturnAddressAfterCall(regT3);
    9186    emitPutJITStubArg(regT3, 3); // return address
    92     emitPutJITStubArg(regT2, 7); // codeBlock
    9387    restoreArgumentReference();
    9488    Call callArityCheck2 = call();
    9589    move(regT1, callFrameRegister);
    96     emitGetJITStubArg(1, regT0); // callee
    9790    emitGetJITStubArg(5, regT1); // argCount
    98     restoreReturnAddressBeforeReturn(regT3); // return address
    99 
     91    restoreReturnAddressBeforeReturn(regT3);
    10092    arityCheckOkay2.link(this);
     93
    10194    isNativeFunc2.link(this);
    10295
     
    10497
    10598    preserveReturnAddressAfterCall(regT3);
    106     emitPutJITStubArg(regT3, 3);
     99    emitPutJITStubArg(regT3, 3); // return address
    107100    restoreArgumentReference();
    108101    Call callLazyLinkCall = call();
     
    111104#endif // ENABLE(JIT_OPTIMIZE_CALL)
    112105
    113     /* VirtualCall Trampoline */
     106    // VirtualCall Trampoline
     107    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
    114108    Label virtualCallBegin = align();
    115 
    116     // regT0 holds callee, regT1 holds argCount.
    117109    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    118     loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT2);
    119     Jump hasCodeBlock3 = branchTestPtr(NonZero, regT2);
    120 
    121     // Lazily generate a CodeBlock.
    122     preserveReturnAddressAfterCall(regT3); // return address
     110
     111    Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     112
     113    Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     114    preserveReturnAddressAfterCall(regT3);
    123115    restoreArgumentReference();
    124116    Call callJSFunction1 = call();
    125     move(regT0, regT2);
    126     emitGetJITStubArg(1, regT0); // callee
    127117    emitGetJITStubArg(5, regT1); // argCount
    128     restoreReturnAddressBeforeReturn(regT3); // return address
     118    restoreReturnAddressBeforeReturn(regT3);
     119    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    129120    hasCodeBlock3.link(this);
    130121   
    131     // regT2 holds codeBlock.
    132     Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    133    
    134     // Check argCount matches callee.
    135     Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
     122    // Check argCount matches callee arity.
     123    Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
    136124    preserveReturnAddressAfterCall(regT3);
    137125    emitPutJITStubArg(regT3, 3); // return address
    138     emitPutJITStubArg(regT2, 7); // codeBlock
    139126    restoreArgumentReference();
    140127    Call callArityCheck1 = call();
    141128    move(regT1, callFrameRegister);
    142     emitGetJITStubArg(1, regT0); // callee
    143129    emitGetJITStubArg(5, regT1); // argCount
    144     restoreReturnAddressBeforeReturn(regT3); // return address
    145 
     130    restoreReturnAddressBeforeReturn(regT3);
     131    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    146132    arityCheckOkay3.link(this);
     133
    147134    isNativeFunc3.link(this);
     135
    148136    compileOpCallInitializeCallFrame();
    149     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT0);
    150     loadPtr(Address(regT0, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
     137    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
    151138    jump(regT0);
    152139
     
    14851472    COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit);
    14861473
     1474    // VirtualCallLink Trampoline
     1475    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
    14871476    Label virtualCallLinkBegin = align();
    1488 
    1489     // Load the callee CodeBlock* into eax
    1490     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3);
    1491     loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT0);
    1492     Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0);
     1477    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
     1478
     1479    Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     1480
     1481    Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
    14931482    preserveReturnAddressAfterCall(regT3);
    14941483    restoreArgumentReference();
    14951484    Call callJSFunction2 = call();
    1496     emitGetJITStubArg(1, regT2);
    1497     emitGetJITStubArg(3, regT1);
     1485    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
     1486    emitGetJITStubArg(3, regT1); // argCount
    14981487    restoreReturnAddressBeforeReturn(regT3);
    14991488    hasCodeBlock2.link(this);
    15001489
    1501     Jump isNativeFunc2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    1502 
    15031490    // Check argCount matches callee arity.
    1504     Jump arityCheckOkay2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
     1491    Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
    15051492    preserveReturnAddressAfterCall(regT3);
    1506     emitPutJITStubArg(regT3, 2);
    1507     emitPutJITStubArg(regT0, 4);
     1493    emitPutJITStubArg(regT3, 2); // return address
    15081494    restoreArgumentReference();
    15091495    Call callArityCheck2 = call();
    15101496    move(regT1, callFrameRegister);
    1511     emitGetJITStubArg(1, regT2);
    1512     emitGetJITStubArg(3, regT1);
     1497    emitGetJITStubArg(3, regT1); // argCount
    15131498    restoreReturnAddressBeforeReturn(regT3);
    15141499    arityCheckOkay2.link(this);
     1500
    15151501    isNativeFunc2.link(this);
    15161502
    15171503    compileOpCallInitializeCallFrame();
    1518 
    15191504    preserveReturnAddressAfterCall(regT3);
    1520     emitPutJITStubArg(regT3, 2);
     1505    emitPutJITStubArg(regT3, 2); // return address
    15211506    restoreArgumentReference();
    15221507    Call callLazyLinkCall = call();
    15231508    restoreReturnAddressBeforeReturn(regT3);
    1524 
    15251509    jump(regT0);
    15261510
     1511    // VirtualCall Trampoline
     1512    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
    15271513    Label virtualCallBegin = align();
    1528 
    1529     // Load the callee CodeBlock* into eax
    1530     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3);
    1531     loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_codeBlock)), regT0);
    1532     Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0);
     1514    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
     1515
     1516    Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
     1517
     1518    Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
    15331519    preserveReturnAddressAfterCall(regT3);
    15341520    restoreArgumentReference();
    15351521    Call callJSFunction1 = call();
    1536     emitGetJITStubArg(1, regT2);
    1537     emitGetJITStubArg(3, regT1);
     1522    emitGetJITStubArg(3, regT1); // argCount
    15381523    restoreReturnAddressBeforeReturn(regT3);
    1539     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3); // reload the function body nody, so we can reload the code pointer.
     1524    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    15401525    hasCodeBlock3.link(this);
    15411526   
    1542     Jump isNativeFunc3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
    1543 
    15441527    // Check argCount matches callee arity.
    1545     Jump arityCheckOkay3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
     1528    Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
    15461529    preserveReturnAddressAfterCall(regT3);
    1547     emitPutJITStubArg(regT3, 2);
    1548     emitPutJITStubArg(regT0, 4);
     1530    emitPutJITStubArg(regT3, 2); // return address
    15491531    restoreArgumentReference();
    15501532    Call callArityCheck1 = call();
    15511533    move(regT1, callFrameRegister);
    1552     emitGetJITStubArg(1, regT2);
    1553     emitGetJITStubArg(3, regT1);
     1534    emitGetJITStubArg(3, regT1); // argCount
    15541535    restoreReturnAddressBeforeReturn(regT3);
    1555     loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT3); // reload the function body nody, so we can reload the code pointer.
     1536    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
    15561537    arityCheckOkay3.link(this);
     1538
    15571539    isNativeFunc3.link(this);
    15581540
    1559     // load ctiCode from the new codeBlock.
    1560     loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
    1561    
    15621541    compileOpCallInitializeCallFrame();
     1542    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
    15631543    jump(regT0);
    15641544
    1565    
    15661545    Label nativeCallThunk = align();
    15671546    preserveReturnAddressAfterCall(regT0);
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r47412 r47597  
    14861486    executable->jitCode(callDataScopeChain);
    14871487
    1488     return &executable->generatedBytecode();
     1488    return function;
    14891489}
    14901490
     
    14941494
    14951495    CallFrame* callFrame = stackFrame.callFrame;
    1496     CodeBlock* newCodeBlock = stackFrame.args[3].codeBlock();
    1497     ASSERT(newCodeBlock->codeType() != NativeCode);
     1496    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
     1497    CodeBlock* newCodeBlock = &callee->executable()->generatedBytecode();
    14981498    int argCount = stackFrame.args[2].int32();
    14991499
     
    15321532    }
    15331533
    1534     RETURN_POINTER_PAIR(newCodeBlock, callFrame);
     1534    RETURN_POINTER_PAIR(callee, callFrame);
    15351535}
    15361536
     
    15461546    if (!executable->isHostFunction())
    15471547        codeBlock = &executable->bytecode(callee->scope().node());
    1548     else
    1549         codeBlock = &executable->generatedBytecode();
    15501548    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
    15511549
  • trunk/JavaScriptCore/runtime/Executable.cpp

    r47519 r47597  
    8686    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body(), globalObject->debugger(), scopeChain, &m_codeBlock->symbolTable(), m_codeBlock));
    8787    generator->generate();
     88    m_numParameters = m_codeBlock->m_numParameters;
     89    ASSERT(m_numParameters);
    8890
    8991    body()->destroyData();
     
    126128
    127129#endif
    128 
    129 bool FunctionExecutable::isHostFunction() const
    130 {
    131     return m_codeBlock && m_codeBlock->codeType() == NativeCode;
    132 }
    133130
    134131void FunctionExecutable::markAggregate(MarkStack& markStack)
     
    198195    delete m_codeBlock;
    199196    m_codeBlock = 0;
     197    m_numParameters = NUM_PARAMETERS_NOT_COMPILED;
    200198#if ENABLE(JIT)
    201199    m_jitCode = JITCode();
     
    205203#if ENABLE(JIT)
    206204FunctionExecutable::FunctionExecutable(ExecState* exec)
    207     : m_codeBlock(new NativeCodeBlock(this))
     205    : m_codeBlock(0)
    208206    , m_name(Identifier(exec, "<native thunk>"))
    209207{
    210208    m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk()));
     209    m_numParameters = NUM_PARAMETERS_IS_HOST;
    211210}
    212211#endif
  • trunk/JavaScriptCore/runtime/Executable.h

    r47582 r47597  
    4141        friend class JIT;
    4242    public:
     43        enum Mode {
     44            NoJITCode,
     45            HasJITCode,
     46            IsHost
     47        };
     48        static const int NUM_PARAMETERS_IS_HOST = 0;
     49        static const int NUM_PARAMETERS_NOT_COMPILED = -1;
     50   
    4351        virtual ~ExecutableBase() {}
    4452
    4553        ExecutableBase(const SourceCode& source)
    4654            : m_source(source)
     55            , m_numParameters(NUM_PARAMETERS_NOT_COMPILED)
    4756        {
    4857        }
     
    6372        RefPtr<ScopeNode> m_node;
    6473        SourceCode m_source;
     74        int m_numParameters;
    6575
    6676    private:
     
    220230        UString paramString() const { return body()->paramString(); }
    221231
    222         bool isHostFunction() const;
     232        bool isHostFunction() const { return m_numParameters == NUM_PARAMETERS_IS_HOST; }
    223233        bool isGenerated() const
    224234        {
  • trunk/JavaScriptCore/runtime/JSFunction.cpp

    r47412 r47597  
    9090    // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
    9191    // this memory is freed and may be reused (potentially for another, different JSFunction).
     92    if (!isHostFunction()) {
    9293#if ENABLE(JIT_OPTIMIZE_CALL)
    93     if (m_executable && m_executable->isGenerated())
    94         m_executable->generatedBytecode().unlinkCallers();
     94        if (m_executable && m_executable->isGenerated())
     95            m_executable->generatedBytecode().unlinkCallers();
    9596#endif
    96     if (!isHostFunction())
    9797        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
     98    }
    9899}
    99100
Note: See TracChangeset for help on using the changeset viewer.