Changeset 103294 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Dec 19, 2011, 7:16:21 PM (13 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=74903
Exceptions not thrown correctly from DFG JIT on 32bit

Reviewed by Oliver Hunt.

Arguments for lookupExceptionHandler are not setup correctly.
In the case of ARMv7 we rely on lr being preserved over a call,
this in invalid. On x86 we don't should be poking the arguments onto the stack!

Source/JavaScriptCore:

  • bytecode/CodeBlock.h:

(JSC::CodeBlock::bytecodeOffsetForCallAtIndex):

  • dfg/DFGAssemblyHelpers.h:

(JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):

  • dfg/DFGGPRInfo.h:
  • dfg/DFGJITCompiler.cpp:

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

  • dfg/DFGJITCompiler.h:

(JSC::DFG::JITCompiler::addExceptionCheck):
(JSC::DFG::JITCompiler::addFastExceptionCheck):

  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:

LayoutTests:

  • fast/js/dfg-exception-expected.txt: Added.
  • fast/js/dfg-exception.html: Added.
  • fast/js/script-tests/dfg-exception.js: Added.

(doesntDFGCompile):
(test):

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r103292 r103294  
     12011-12-19  Gavin Barraclough  <[email protected]>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=74903
     4        Exceptions not thrown correctly from DFG JIT on 32bit
     5
     6        Reviewed by Oliver Hunt.
     7
     8        Arguments for lookupExceptionHandler are not setup correctly.
     9        In the case of ARMv7 we rely on lr being preserved over a call,
     10        this in invalid. On x86 we don't should be poking the arguments onto the stack!
     11
     12        * bytecode/CodeBlock.h:
     13        (JSC::CodeBlock::bytecodeOffsetForCallAtIndex):
     14        * dfg/DFGAssemblyHelpers.h:
     15        (JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
     16        * dfg/DFGGPRInfo.h:
     17        * dfg/DFGJITCompiler.cpp:
     18        (JSC::DFG::JITCompiler::compileBody):
     19        * dfg/DFGJITCompiler.h:
     20        (JSC::DFG::JITCompiler::addExceptionCheck):
     21        (JSC::DFG::JITCompiler::addFastExceptionCheck):
     22        * dfg/DFGOperations.cpp:
     23        * dfg/DFGOperations.h:
     24
    1252011-12-19  Filip Pizlo  <[email protected]>
    226
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r102917 r103294  
    371371        }
    372372
     373        unsigned bytecodeOffsetForCallAtIndex(unsigned index)
     374        {
     375            if (!m_rareData)
     376                return 1;
     377            Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
     378            if (!callIndices.size())
     379                return 1;
     380            ASSERT(index < m_rareData->m_callReturnIndexVector.size());
     381            return m_rareData->m_callReturnIndexVector[index].bytecodeOffset;
     382        }
     383
    373384        void unlinkCalls();
    374385       
  • trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h

    r102743 r103294  
    7676        push(address);
    7777    }
    78 
    79     void getPCAfterCall(GPRReg gpr)
    80     {
    81           peek(gpr, -1);
    82     }
    8378#endif // CPU(X86_64) || CPU(X86)
    8479
     
    9792    {
    9893        loadPtr(address, linkRegister);
    99     }
    100 
    101     ALWAYS_INLINE void getPCAfterCall(GPRReg gpr)
    102     {
    103         move(ARMRegisters::lr, gpr);
    10494    }
    10595#endif
  • trunk/Source/JavaScriptCore/dfg/DFGGPRInfo.h

    r99895 r103294  
    274274    static const GPRReg returnValueGPR = X86Registers::eax; // regT0
    275275    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
     276    static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
    276277
    277278    static GPRReg toRegister(unsigned index)
     
    344345    static const GPRReg returnValueGPR = X86Registers::eax; // regT0
    345346    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
     347    static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
    346348
    347349    static GPRReg toRegister(unsigned index)
     
    416418    static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
    417419    static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
     420    static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2;
    418421
    419422    static GPRReg toRegister(unsigned index)
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp

    r102545 r103294  
    9696    if (didLinkExceptionCheck) {
    9797        // lookupExceptionHandler is passed two arguments, exec (the CallFrame*), and
    98         // an identifier for the operation that threw the exception, which we can use
    99         // to look up handler information. The identifier we use is the return address
    100         // of the call out from JIT code that threw the exception; this is still
    101         // available on the stack, just below the stack pointer!
     98        // the index into the CodeBlock's callReturnIndexVector corresponding to the
     99        // call that threw the exception (this was set in nonPreservedNonReturnGPR, when
     100        // the exception check was planted).
     101        move(GPRInfo::nonPreservedNonReturnGPR, GPRInfo::argumentGPR1);
    102102        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
    103         getPCAfterCall(GPRInfo::argumentGPR1);
     103#if CPU(X86)
     104        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
     105        poke(GPRInfo::argumentGPR0);
     106        poke(GPRInfo::argumentGPR1, 1);
     107#endif
    104108        m_calls.append(CallLinkRecord(call(), lookupExceptionHandler));
    105109        // lookupExceptionHandler leaves the handler CallFrame* in the returnValueGPR,
  • trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h

    r102743 r103294  
    179179    Call addExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
    180180    {
     181        move(TrustedImm32(m_exceptionChecks.size()), GPRInfo::nonPreservedNonReturnGPR);
    181182#if USE(JSVALUE64)
    182183        Jump exceptionCheck = branchTestPtr(NonZero, AbsoluteAddress(&globalData()->exception));
     
    191192    Call addFastExceptionCheck(Call functionCall, CodeOrigin codeOrigin)
    192193    {
     194        move(TrustedImm32(m_exceptionChecks.size()), GPRInfo::nonPreservedNonReturnGPR);
    193195        Jump exceptionCheck = branchTestPtr(Zero, GPRInfo::returnValueGPR);
    194196        m_exceptionChecks.append(CallExceptionRecord(functionCall, exceptionCheck, codeOrigin));
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r103083 r103294  
    794794}
    795795
    796 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, ReturnAddressPtr faultLocation)
     796DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
    797797{
    798798    JSValue exceptionValue = exec->exception();
    799799    ASSERT(exceptionValue);
    800800
    801     unsigned vPCIndex = exec->codeBlock()->bytecodeOffset(faultLocation);
     801    unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
    802802    HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, vPCIndex);
    803803
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r102811 r103294  
    181181}
    182182#endif
    183 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState*, ReturnAddressPtr faultLocation);
     183DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState*, uint32_t);
    184184
    185185// These operations implement the implicitly called ToInt32, ToNumber, and ToBoolean conversions from ES5.
Note: See TracChangeset for help on using the changeset viewer.