Changeset 90414 in webkit


Ignore:
Timestamp:
Jul 5, 2011 4:18:23 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-07-05 Filip Pizlo <fpizlo@apple.com>

JSC JIT has code duplication for the handling of call and construct
https://bugs.webkit.org/show_bug.cgi?id=63957

Reviewed by Gavin Barraclough.

  • jit/JIT.cpp: (JSC::JIT::linkFor):
  • jit/JIT.h:
  • jit/JITStubs.cpp: (JSC::jitCompileFor): (JSC::DEFINE_STUB_FUNCTION): (JSC::arityCheckFor): (JSC::lazyLinkFor):
  • runtime/Executable.h: (JSC::ExecutableBase::generatedJITCodeFor): (JSC::FunctionExecutable::compileFor): (JSC::FunctionExecutable::isGeneratedFor): (JSC::FunctionExecutable::generatedBytecodeFor): (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor):
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r90404 r90414  
     12011-07-05  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC JIT has code duplication for the handling of call and construct
     4        https://bugs.webkit.org/show_bug.cgi?id=63957
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        * jit/JIT.cpp:
     9        (JSC::JIT::linkFor):
     10        * jit/JIT.h:
     11        * jit/JITStubs.cpp:
     12        (JSC::jitCompileFor):
     13        (JSC::DEFINE_STUB_FUNCTION):
     14        (JSC::arityCheckFor):
     15        (JSC::lazyLinkFor):
     16        * runtime/Executable.h:
     17        (JSC::ExecutableBase::generatedJITCodeFor):
     18        (JSC::FunctionExecutable::compileFor):
     19        (JSC::FunctionExecutable::isGeneratedFor):
     20        (JSC::FunctionExecutable::generatedBytecodeFor):
     21        (JSC::FunctionExecutable::generatedJITCodeWithArityCheckFor):
     22
    1232011-07-05  Gavin Barraclough  <barraclough@apple.com>
    224
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r90371 r90414  
    610610}
    611611
    612 void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
     612void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData, CodeSpecializationKind kind)
    613613{
    614614    RepatchBuffer repatchBuffer(callerCodeBlock);
     
    623623
    624624    // patch the call so we do not continue to try to link.
    625     repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
    626 }
    627 
    628 void JIT::linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JIT::CodePtr code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
    629 {
    630     RepatchBuffer repatchBuffer(callerCodeBlock);
    631 
    632     // Currently we only link calls with the exact number of arguments.
    633     // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
    634     if (!calleeCodeBlock || (callerArgCount == calleeCodeBlock->m_numParameters)) {
    635         ASSERT(!callLinkInfo->isLinked());
    636         callLinkInfo->callee.set(*globalData, callLinkInfo->hotPathBegin, callerCodeBlock->ownerExecutable(), callee);
    637         repatchBuffer.relink(callLinkInfo->hotPathOther, code);
    638     }
    639 
    640     // patch the call so we do not continue to try to link.
     625    if (kind == CodeForCall) {
     626        repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
     627        return;
     628    }
     629
     630    ASSERT(kind == CodeForConstruct);
    641631    repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualConstruct());
    642632}
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r90371 r90414  
    247247        }
    248248
    249         static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
    250         static void linkConstruct(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*);
     249        static void linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, CodePtr, CallLinkInfo*, int callerArgCount, JSGlobalData*, CodeSpecializationKind);
    251250
    252251    private:
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r90401 r90414  
    19031903}
    19041904
     1905inline void* jitCompileFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
     1906{
     1907    JSFunction* function = asFunction(stackFrame.callFrame->callee());
     1908    ASSERT(!function->isHostFunction());
     1909    FunctionExecutable* executable = function->jsExecutable();
     1910    ScopeChainNode* callDataScopeChain = function->scope();
     1911    JSObject* error = executable->compileFor(stackFrame.callFrame, callDataScopeChain, kind);
     1912    if (error) {
     1913        stackFrame.callFrame->globalData().exception = error;
     1914        return 0;
     1915    }
     1916    return function;
     1917}
     1918
    19051919DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
    19061920{
     
    19111925    ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
    19121926#endif
    1913 
    1914     JSFunction* function = asFunction(stackFrame.callFrame->callee());
    1915     ASSERT(!function->isHostFunction());
    1916     FunctionExecutable* executable = function->jsExecutable();
    1917     ScopeChainNode* callDataScopeChain = function->scope();
    1918     JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain);
    1919     if (error) {
    1920         stackFrame.callFrame->globalData().exception = error;
    1921         return 0;
    1922     }
    1923     return function;
     1927   
     1928    return jitCompileFor(stackFrame, CodeForCall);
    19241929}
    19251930
     
    19321937    ASSERT(asFunction(stackFrame.callFrame->callee())->getConstructData(constructData) == ConstructTypeJS);
    19331938#endif
    1934 
    1935     JSFunction* function = asFunction(stackFrame.callFrame->callee());
    1936     ASSERT(!function->isHostFunction());
    1937     FunctionExecutable* executable = function->jsExecutable();
    1938     ScopeChainNode* callDataScopeChain = function->scope();
    1939     JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain);
    1940     if (error) {
    1941         stackFrame.callFrame->globalData().exception = error;
    1942         return 0;
    1943     }
    1944     return function;
    1945 }
    1946 
    1947 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
    1948 {
    1949     STUB_INIT_STACK_FRAME(stackFrame);
    1950 
     1939   
     1940    return jitCompileFor(stackFrame, CodeForConstruct);
     1941}
     1942
     1943inline void* arityCheckFor(JITStackFrame& stackFrame, CodeSpecializationKind kind, ReturnAddressPtr& stubReturnAddress)
     1944{
    19511945    CallFrame* callFrame = stackFrame.callFrame;
    19521946    JSFunction* callee = asFunction(callFrame->callee());
    19531947    ASSERT(!callee->isHostFunction());
    1954     CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForCall();
     1948    CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeFor(kind);
    19551949    int argCount = callFrame->argumentCountIncludingThis();
    19561950    ReturnAddressPtr pc = callFrame->returnPC();
     
    19691963            // moved the call frame forward.
    19701964            ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
    1971             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
     1965            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
    19721966            return handler.callFrame;
    19731967        }
     
    19841978            // moved the call frame forward.
    19851979            ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
    1986             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
     1980            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
    19871981            return handler.callFrame;
    19881982        }
     
    20041998}
    20051999
     2000DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
     2001{
     2002    STUB_INIT_STACK_FRAME(stackFrame);
     2003   
     2004    return arityCheckFor(stackFrame, CodeForCall, STUB_RETURN_ADDRESS);
     2005}
     2006
    20062007DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
    20072008{
    20082009    STUB_INIT_STACK_FRAME(stackFrame);
    20092010
    2010     CallFrame* callFrame = stackFrame.callFrame;
    2011     JSFunction* callee = asFunction(callFrame->callee());
    2012     ASSERT(!callee->isHostFunction());
    2013     CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForConstruct();
    2014     int argCount = callFrame->argumentCountIncludingThis();
    2015     ReturnAddressPtr pc = callFrame->returnPC();
    2016 
    2017     ASSERT(argCount != newCodeBlock->m_numParameters);
    2018 
    2019     CallFrame* oldCallFrame = callFrame->callerFrame();
    2020 
    2021     Register* r;
    2022     if (argCount > newCodeBlock->m_numParameters) {
    2023         size_t numParameters = newCodeBlock->m_numParameters;
    2024         r = callFrame->registers() + numParameters;
    2025         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
    2026         if (!stackFrame.registerFile->grow(newEnd)) {
    2027             // Rewind to the previous call frame because op_call already optimistically
    2028             // moved the call frame forward.
    2029             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
    2030             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
    2031             return handler.callFrame;
    2032         }
    2033 
    2034         Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
    2035         for (size_t i = 0; i < numParameters; ++i)
    2036             argv[i + argCount] = argv[i];
    2037     } else {
    2038         size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
    2039         r = callFrame->registers() + omittedArgCount;
    2040         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
    2041         if (!stackFrame.registerFile->grow(newEnd)) {
    2042             // Rewind to the previous call frame because op_call already optimistically
    2043             // moved the call frame forward.
    2044             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
    2045             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
    2046             return handler.callFrame;
    2047         }
    2048 
    2049         Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
    2050         for (size_t i = 0; i < omittedArgCount; ++i)
    2051             argv[i] = jsUndefined();
    2052     }
    2053 
    2054     callFrame = CallFrame::create(r);
    2055     callFrame->setCallerFrame(oldCallFrame);
    2056     callFrame->setArgumentCountIncludingThis(argCount);
    2057     callFrame->setCallee(callee);
    2058     callFrame->setScopeChain(callee->scope());
    2059     callFrame->setReturnPC(pc.value());
    2060 
    2061     ASSERT((void*)callFrame <= stackFrame.registerFile->end());
    2062     return callFrame;
    2063 }
    2064 
    2065 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
    2066 {
    2067     STUB_INIT_STACK_FRAME(stackFrame);
     2011    return arityCheckFor(stackFrame, CodeForConstruct, STUB_RETURN_ADDRESS);
     2012}
     2013
     2014inline void* lazyLinkFor(JITStackFrame& stackFrame, CodeSpecializationKind kind)
     2015{
    20682016    CallFrame* callFrame = stackFrame.callFrame;
    20692017    JSFunction* callee = asFunction(callFrame->callee());
     
    20732021    CodeBlock* codeBlock = 0;
    20742022    if (executable->isHostFunction())
    2075         codePtr = executable->generatedJITCodeForCall().addressForCall();
     2023        codePtr = executable->generatedJITCodeFor(kind).addressForCall();
    20762024    else {
    20772025        FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    2078         JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope());
     2026        JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind);
    20792027        if (error) {
    20802028            callFrame->globalData().exception = createStackOverflowError(callFrame);
    20812029            return 0;
    20822030        }
    2083         codeBlock = &functionExecutable->generatedBytecodeForCall();
     2031        codeBlock = &functionExecutable->generatedBytecodeFor(kind);
    20842032        if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
    2085             codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
     2033            codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
    20862034        else
    2087             codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
     2035            codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
    20882036    }
    20892037    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
     
    20922040        callLinkInfo->setSeen();
    20932041    else
    2094         JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
     2042        JIT::linkFor(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData, kind);
    20952043
    20962044    return codePtr.executableAddress();
    20972045}
    20982046
     2047DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
     2048{
     2049    STUB_INIT_STACK_FRAME(stackFrame);
     2050   
     2051    return lazyLinkFor(stackFrame, CodeForCall);
     2052}
     2053
    20992054DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
    21002055{
    21012056    STUB_INIT_STACK_FRAME(stackFrame);
    2102     CallFrame* callFrame = stackFrame.callFrame;
    2103     JSFunction* callee = asFunction(callFrame->callee());
    2104     ExecutableBase* executable = callee->executable();
    2105 
    2106     MacroAssemblerCodePtr codePtr;
    2107     CodeBlock* codeBlock = 0;
    2108     if (executable->isHostFunction())
    2109         codePtr = executable->generatedJITCodeForConstruct().addressForCall();
    2110     else {
    2111         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
    2112         JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope());
    2113         if (error) {
    2114             throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
    2115             return 0;
    2116         }
    2117         codeBlock = &functionExecutable->generatedBytecodeForConstruct();
    2118         if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
    2119             codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall();
    2120         else
    2121             codePtr = functionExecutable->generatedJITCodeForConstructWithArityCheck();
    2122     }
    2123     CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
    2124 
    2125     if (!callLinkInfo->seenOnce())
    2126         callLinkInfo->setSeen();
    2127     else
    2128         JIT::linkConstruct(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
    2129 
    2130     return codePtr.executableAddress();
     2057   
     2058    return lazyLinkFor(stackFrame, CodeForConstruct);
    21312059}
    21322060
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r89973 r90414  
    4444
    4545    struct ExceptionInfo;
     46   
     47    enum CodeSpecializationKind { CodeForCall, CodeForConstruct };
    4648
    4749    class ExecutableBase : public JSCell {
     
    9193            ASSERT(m_jitCodeForConstruct);
    9294            return m_jitCodeForConstruct;
     95        }
     96       
     97        JITCode& generatedJITCodeFor(CodeSpecializationKind kind)
     98        {
     99            if (kind == CodeForCall)
     100                return generatedJITCodeForCall();
     101            ASSERT(kind == CodeForConstruct);
     102            return generatedJITCodeForConstruct();
    93103        }
    94104
     
    388398            return *m_codeBlockForConstruct;
    389399        }
     400       
     401        JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind)
     402        {
     403            if (kind == CodeForCall)
     404                return compileForCall(exec, scopeChainNode);
     405            ASSERT(kind == CodeForConstruct);
     406            return compileForConstruct(exec, scopeChainNode);
     407        }
     408       
     409        bool isGeneratedFor(CodeSpecializationKind kind)
     410        {
     411            if (kind == CodeForCall)
     412                return isGeneratedForCall();
     413            ASSERT(kind == CodeForConstruct);
     414            return isGeneratedForConstruct();
     415        }
     416       
     417        FunctionCodeBlock& generatedBytecodeFor(CodeSpecializationKind kind)
     418        {
     419            if (kind == CodeForCall)
     420                return generatedBytecodeForCall();
     421            ASSERT(kind == CodeForConstruct);
     422            return generatedBytecodeForConstruct();
     423        }
    390424
    391425        const Identifier& name() { return m_name; }
     
    437471            ASSERT(m_jitCodeForConstructWithArityCheck);
    438472            return m_jitCodeForConstructWithArityCheck;
     473        }
     474       
     475        MacroAssemblerCodePtr generatedJITCodeWithArityCheckFor(CodeSpecializationKind kind)
     476        {
     477            if (kind == CodeForCall)
     478                return generatedJITCodeForCallWithArityCheck();
     479            ASSERT(kind == CodeForConstruct);
     480            return generatedJITCodeForConstructWithArityCheck();
    439481        }
    440482#endif
Note: See TracChangeset for help on using the changeset viewer.