⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 98405 in webkit


Ignore:
Timestamp:
Oct 25, 2011, 4:06:13 PM (15 years ago)
Author:
barraclough@apple.com
Message:

Separate out function linking & exception check data structures.
https://bugs.webkit.org/show_bug.cgi?id=70858

Reviewed by Oliver Hunt.

This will make it easier to refactor the callOperation methods to spilt the value
representation specific handling from the cpu/calling-convention implementation.

  • dfg/DFGJITCodeGenerator.h:

(JSC::DFG::appendCallWithExceptionCheck):

  • dfg/DFGJITCodeGenerator32_64.cpp:

(JSC::DFG::JITCodeGenerator::emitCall):

  • dfg/DFGJITCodeGenerator64.cpp:

(JSC::DFG::JITCodeGenerator::emitCall):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):

  • dfg/DFGJITCompiler.h:

(JSC::DFG::CallLinkRecord::CallLinkRecord):
(JSC::DFG::CallExceptionRecord::CallExceptionRecord):
(JSC::DFG::JITCompiler::JITCompiler):
(JSC::DFG::JITCompiler::notifyCall):
(JSC::DFG::JITCompiler::appendCall):
(JSC::DFG::JITCompiler::addExceptionCheck):
(JSC::DFG::JITCompiler::addFastExceptionCheck):

  • dfg/DFGJITCompiler32_64.cpp:

(JSC::DFG::JITCompiler::compileBody):
(JSC::DFG::JITCompiler::link):

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r98398 r98405  
     12011-10-25  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Separate out function linking & exception check data structures.
     4        https://bugs.webkit.org/show_bug.cgi?id=70858
     5
     6        Reviewed by Oliver Hunt.
     7
     8        This will make it easier to refactor the callOperation methods to spilt the value
     9        representation specific handling from the cpu/calling-convention implementation.
     10
     11        * dfg/DFGJITCodeGenerator.h:
     12        (JSC::DFG::appendCallWithExceptionCheck):
     13        * dfg/DFGJITCodeGenerator32_64.cpp:
     14        (JSC::DFG::JITCodeGenerator::emitCall):
     15        * dfg/DFGJITCodeGenerator64.cpp:
     16        (JSC::DFG::JITCodeGenerator::emitCall):
     17        * dfg/DFGJITCompiler.cpp:
     18        (JSC::DFG::JITCompiler::compileBody):
     19        (JSC::DFG::JITCompiler::link):
     20        * dfg/DFGJITCompiler.h:
     21        (JSC::DFG::CallLinkRecord::CallLinkRecord):
     22        (JSC::DFG::CallExceptionRecord::CallExceptionRecord):
     23        (JSC::DFG::JITCompiler::JITCompiler):
     24        (JSC::DFG::JITCompiler::notifyCall):
     25        (JSC::DFG::JITCompiler::appendCall):
     26        (JSC::DFG::JITCompiler::addExceptionCheck):
     27        (JSC::DFG::JITCompiler::addFastExceptionCheck):
     28        * dfg/DFGJITCompiler32_64.cpp:
     29        (JSC::DFG::JITCompiler::compileBody):
     30        (JSC::DFG::JITCompiler::link):
     31
    1322011-10-25  Filip Pizlo  <fpizlo@apple.com>
    233
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h

    r98291 r98405  
    15511551    JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
    15521552    {
    1553         return m_jit.appendCallWithExceptionCheck(function, at(m_compileIndex).codeOrigin);
     1553        return m_jit.addExceptionCheck(m_jit.appendCall(function), at(m_compileIndex).codeOrigin);
    15541554    }
    15551555    JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp

    r98321 r98405  
    13661366    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    13671367    m_jit.poke(GPRInfo::argumentGPR0);
    1368     JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);
     1368    JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin);
    13691369    m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
    13701370    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
  • trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp

    r97410 r98405  
    13121312   
    13131313    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    1314     JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, at(m_compileIndex).codeOrigin);
     1314    JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin);
    13151315    m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
    13161316    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r98179 r98405  
    611611    linkOSRExits(speculative);
    612612
    613     // Iterate over the m_calls vector, checking for exception checks,
    614     // and linking them to here.
    615     for (unsigned i = 0; i < m_calls.size(); ++i) {
    616         Jump& exceptionCheck = m_calls[i].m_exceptionCheck;
     613    // Iterate over the m_calls vector, checking for jumps to link.
     614    bool didLinkExceptionCheck = false;
     615    for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
     616        Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck;
    617617        if (exceptionCheck.isSet()) {
    618618            exceptionCheck.link(this);
    619             ++m_exceptionCheckCount;
    620         }
    621     }
     619            didLinkExceptionCheck = true;
     620        }
     621    }
     622
    622623    // If any exception checks were linked, generate code to lookup a handler.
    623     if (m_exceptionCheckCount) {
     624    if (didLinkExceptionCheck) {
    624625        // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
    625626        // an identifier for the operation that threw the exception, which we can use
     
    629630        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    630631        peek(GPRInfo::argumentGPR1, -1);
    631         m_calls.append(CallRecord(call(), lookupExceptionHandler));
     632        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
    632633        // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
    633634        // and the address of the handler in returnValueGPR2.
     
    644645
    645646    // Link all calls out from the JIT code to their respective functions.
    646     for (unsigned i = 0; i < m_calls.size(); ++i) {
    647         if (m_calls[i].m_function.value())
    648             linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
    649     }
     647    for (unsigned i = 0; i < m_calls.size(); ++i)
     648        linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
    650649
    651650    if (m_codeBlock->needsCallReturnIndices()) {
    652         m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount);
    653         for (unsigned i = 0; i < m_calls.size(); ++i) {
    654             if (m_calls[i].m_handlesExceptions) {
    655                 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
    656                 unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex;
    657                 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
    658             }
     651        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size());
     652        for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
     653            unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call);
     654            unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex;
     655            m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
    659656        }
    660657    }
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r98179 r98405  
    6464#endif
    6565
    66 // === CallRecord ===
     66// === CallLinkRecord ===
    6767//
    68 // A record of a call out from JIT code to a helper function.
    69 // Every CallRecord contains a reference to the call instruction & the function
    70 // that it needs to be linked to. Calls that might throw an exception also record
    71 // the Jump taken on exception (unset if not present), and ExceptionInfo (presently
    72 // an unsigned, bytecode index) used to recover handler/source info.
    73 struct CallRecord {
    74     // Constructor for a call with no exception handler.
    75     CallRecord(MacroAssembler::Call call, FunctionPtr function)
     68// A record of a call out from JIT code that needs linking to a helper function.
     69// Every CallLinkRecord contains a reference to the call instruction & the function
     70// that it needs to be linked to.
     71struct CallLinkRecord {
     72    CallLinkRecord(MacroAssembler::Call call, FunctionPtr function)
    7673        : m_call(call)
    7774        , m_function(function)
    78         , m_handlesExceptions(false)
    79     {
    80     }
    81 
    82     // Constructor for a call with an exception handler.
    83     CallRecord(MacroAssembler::Call call, FunctionPtr function, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin)
     75    {
     76    }
     77
     78    MacroAssembler::Call m_call;
     79    FunctionPtr m_function;
     80};
     81
     82// === CallExceptionRecord ===
     83//
     84// A record of a call out from JIT code that might throw an exception.
     85// Calls that might throw an exception also record the Jump taken on exception
     86// (unset if not present) and code origin used to recover handler/source info.
     87struct CallExceptionRecord {
     88    CallExceptionRecord(MacroAssembler::Call call, CodeOrigin codeOrigin)
    8489        : m_call(call)
    85         , m_function(function)
     90        , m_codeOrigin(codeOrigin)
     91    {
     92    }
     93
     94    CallExceptionRecord(MacroAssembler::Call call, MacroAssembler::Jump exceptionCheck, CodeOrigin codeOrigin)
     95        : m_call(call)
    8696        , m_exceptionCheck(exceptionCheck)
    8797        , m_codeOrigin(codeOrigin)
    88         , m_handlesExceptions(true)
    89     {
    90     }
    91 
    92     // Constructor for a call that may cause exceptions, but which are handled
    93     // through some mechanism other than the in-line exception handler.
    94     CallRecord(MacroAssembler::Call call, FunctionPtr function, CodeOrigin codeOrigin)
    95         : m_call(call)
    96         , m_function(function)
    97         , m_codeOrigin(codeOrigin)
    98         , m_handlesExceptions(true)
    9998    {
    10099    }
    101100
    102101    MacroAssembler::Call m_call;
    103     FunctionPtr m_function;
    104102    MacroAssembler::Jump m_exceptionCheck;
    105103    CodeOrigin m_codeOrigin;
    106     bool m_handlesExceptions;
    107104};
    108105
     
    121118        , m_graph(dfg)
    122119        , m_codeBlock(codeBlock)
    123         , m_exceptionCheckCount(0)
    124120    {
    125121    }
     
    210206
    211207    // Notify the JIT of a call that does not require linking.
    212     void notifyCall(Call call, CodeOrigin codeOrigin)
    213     {
    214         m_calls.append(CallRecord(call, FunctionPtr(), codeOrigin));
     208    void notifyCall(Call functionCall, CodeOrigin codeOrigin)
     209    {
     210        m_exceptionChecks.append(CallExceptionRecord(functionCall, codeOrigin));
    215211    }
    216212
     
    219215    {
    220216        Call functionCall = call();
    221         m_calls.append(CallRecord(functionCall, function));
    222         // FIXME: should be able to JIT_ASSERT here that globalData->exception is null on return back to JIT code.
     217        m_calls.append(CallLinkRecord(functionCall, function));
    223218        return functionCall;
    224219    }
    225220
    226221    // Add a call out from JIT code, with an exception check.
    227     Call appendCallWithExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin)
    228     {
    229         Call functionCall = call();
     222    Call addExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
     223    {
    230224#if USE(JSVALUE64)
    231225        Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception));
     
    233227        Jump exceptionCheck = branch32(NotEqual, AbsoluteAddress(reinterpret_cast<char*>(&globalData()->exception) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
    234228#endif
    235         m_calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));
     229        m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
    236230        return functionCall;
    237231    }
    238232   
    239233    // Add a call out from JIT code, with a fast exception check that tests if the return value is zero.
    240     Call appendCallWithFastExceptionCheck(const FunctionPtr& function, CodeOrigin codeOrigin)
    241     {
    242         Call functionCall = call();
     234    Call addFastExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
     235    {
    243236        Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR);
    244         m_calls.append(CallRecord(functionCall, function, exceptionCheck, codeOrigin));
     237        m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
    245238        return functionCall;
    246239    }
     
    467460    // Vector of calls out from JIT code, including exception handler information.
    468461    // Count of the number of CallRecords with exception handlers.
    469     Vector<CallRecord> m_calls;
    470     unsigned m_exceptionCheckCount;
     462    Vector<CallLinkRecord> m_calls;
     463    Vector<CallExceptionRecord> m_exceptionChecks;
    471464   
    472465    // JIT code map for OSR entrypoints.
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler32_64.cpp

    r98291 r98405  
    569569    linkOSRExits(speculative);
    570570
    571     // Iterate over the m_calls vector, checking for exception checks,
    572     // and linking them to here.
    573     for (unsigned i = 0; i < m_calls.size(); ++i) {
    574         Jump& exceptionCheck = m_calls[i].m_exceptionCheck;
     571    // Iterate over the m_calls vector, checking for jumps to link.
     572    bool didLinkExceptionCheck = false;
     573    for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
     574        Jump& exceptionCheck = m_exceptionChecks[i].m_exceptionCheck;
    575575        if (exceptionCheck.isSet()) {
    576576            exceptionCheck.link(this);
    577             ++m_exceptionCheckCount;
    578         }
    579     }
     577            didLinkExceptionCheck = true;
     578        }
     579    }
     580
    580581    // If any exception checks were linked, generate code to lookup a handler.
    581     if (m_exceptionCheckCount) {
     582    if (didLinkExceptionCheck) {
    582583        // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
    583584        // an identifier for the operation that threw the exception, which we can use
     
    585586        // of the call out from JIT code that threw the exception; this is still
    586587        // available on the stack, just below the stack pointer!
     588        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    587589        peek(GPRInfo::argumentGPR1, -1);
    588         poke(GPRInfo::callFrameRegister);
    589         poke(GPRInfo::argumentGPR1, 1);
    590         m_calls.append(CallRecord(call(), lookupExceptionHandler));
     590        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
    591591        // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
    592592        // and the address of the handler in returnValueGPR2.
     
    603603
    604604    // Link all calls out from the JIT code to their respective functions.
    605     for (unsigned i = 0; i < m_calls.size(); ++i) {
    606         if (m_calls[i].m_function.value())
    607             linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
    608     }
     605    for (unsigned i = 0; i < m_calls.size(); ++i)
     606        linkBuffer.link(m_calls[i].m_call, m_calls[i].m_function);
    609607
    610608    if (m_codeBlock->needsCallReturnIndices()) {
    611         m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionCheckCount);
    612         for (unsigned i = 0; i < m_calls.size(); ++i) {
    613             if (m_calls[i].m_handlesExceptions) {
    614                 unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_calls[i].m_call);
    615                 unsigned exceptionInfo = m_calls[i].m_codeOrigin.bytecodeIndex;
    616                 m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
    617             }
     609        m_codeBlock->callReturnIndexVector().reserveCapacity(m_exceptionChecks.size());
     610        for (unsigned i = 0; i < m_exceptionChecks.size(); ++i) {
     611            unsigned returnAddressOffset = linkBuffer.returnAddressOffset(m_exceptionChecks[i].m_call);
     612            unsigned exceptionInfo = m_exceptionChecks[i].m_codeOrigin.bytecodeIndex;
     613            m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(returnAddressOffset, exceptionInfo));
    618614        }
    619615    }
Note: See TracChangeset for help on using the changeset viewer.