Changeset 93755 in webkit


Ignore:
Timestamp:
Aug 24, 2011 6:25:38 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

Keep track of topCallFrame for Stack traces
https://bugs.webkit.org/show_bug.cgi?id=66571

Patch by Juan C. Montemayor <jmont@apple.com> on 2011-08-24
Reviewed by Geoffrey Garen.

This patch adds a TopCallFrame to JSC in order to have that information
when an error is thrown to create a stack trace. The TopCallFrame is
updated throughout select points in the Interpreter and the JSC.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::throwException):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::privateExecute):

  • interpreter/Interpreter.h:

(JSC::TopCallFrameSetter::TopCallFrameSetter):
(JSC::TopCallFrameSetter::~TopCallFrameSetter):

  • jit/JIT.h:
  • jit/JITInlineMethods.h:

(JSC::JIT::updateTopCallFrame):

  • jit/JITStubCall.h:

(JSC::JITStubCall::call):

  • jit/JITStubs.cpp:

(JSC::throwExceptionFromOpCall):
(JSC::DEFINE_STUB_FUNCTION):
(JSC::arityCheckFor):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):

  • runtime/JSGlobalData.h:
Location:
trunk/Source/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r93710 r93755  
     12011-08-24  Juan C. Montemayor  <jmont@apple.com>
     2
     3        Keep track of topCallFrame for Stack traces
     4        https://bugs.webkit.org/show_bug.cgi?id=66571
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch adds a TopCallFrame to JSC in order to have that information
     9        when an error is thrown to create a stack trace. The TopCallFrame is
     10        updated throughout select points in the Interpreter and the JSC.
     11
     12        * interpreter/Interpreter.cpp:
     13        (JSC::Interpreter::unwindCallFrame):
     14        (JSC::Interpreter::throwException):
     15        (JSC::Interpreter::execute):
     16        (JSC::Interpreter::executeCall):
     17        (JSC::Interpreter::executeConstruct):
     18        (JSC::Interpreter::privateExecute):
     19        * interpreter/Interpreter.h:
     20        (JSC::TopCallFrameSetter::TopCallFrameSetter):
     21        (JSC::TopCallFrameSetter::~TopCallFrameSetter):
     22        * jit/JIT.h:
     23        * jit/JITInlineMethods.h:
     24        (JSC::JIT::updateTopCallFrame):
     25        * jit/JITStubCall.h:
     26        (JSC::JITStubCall::call):
     27        * jit/JITStubs.cpp:
     28        (JSC::throwExceptionFromOpCall):
     29        (JSC::DEFINE_STUB_FUNCTION):
     30        (JSC::arityCheckFor):
     31        * runtime/JSGlobalData.cpp:
     32        (JSC::JSGlobalData::JSGlobalData):
     33        * runtime/JSGlobalData.h:
     34
    1352011-08-24  Filip Pizlo  <fpizlo@apple.com>
    236
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r92797 r93755  
    609609
    610610    CallFrame* callerFrame = callFrame->callerFrame();
     611    callFrame->globalData().topCallFrame = callerFrame;
    611612    if (callerFrame->hasHostCallFrameFlag())
    612613        return false;
     
    882883    newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0);
    883884    newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj);
     885    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
    884886
    885887    Profiler** profiler = Profiler::enabledProfilerReference();
     
    955957        newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
    956958
     959        TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
     960
    957961        Profiler** profiler = Profiler::enabledProfilerReference();
    958962        if (*profiler)
     
    984988    newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
    985989    newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
     990
     991    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
    986992
    987993    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
     
    10491055        newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
    10501056
     1057        TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
     1058
    10511059        Profiler** profiler = Profiler::enabledProfilerReference();
    10521060        if (*profiler)
     
    10811089    newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
    10821090    newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
     1091
     1092    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
    10831093
    10841094    DynamicGlobalObjectScope globalObjectScope(*scopeChain->globalData, scopeChain->globalObject.get());
     
    11441154    }
    11451155    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function); 
     1156    scopeChain->globalData->topCallFrame = newCallFrame;
    11461157    CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
    11471158    return result;
     
    11571168    if (*profiler)
    11581169        (*profiler)->willExecute(closure.oldCallFrame, closure.function);
    1159    
     1170
     1171    TopCallFrameSetter topCallFrame(*closure.globalData, closure.newCallFrame);
     1172
    11601173    JSValue result;
    11611174    {
     
    11771190        m_reentryDepth--;
    11781191    }
    1179    
     1192
    11801193    if (*profiler)
    11811194        (*profiler)->didExecute(closure.oldCallFrame, closure.function);
     
    11851198void Interpreter::endRepeatCall(CallFrameClosure& closure)
    11861199{
     1200    closure.globalData->topCallFrame = closure.oldCallFrame;
    11871201    m_registerFile.shrink(closure.oldEnd);
    11881202}
     
    12631277    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0);
    12641278    newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = thisValue;
     1279
     1280    TopCallFrameSetter topCallFrame(callFrame->globalData(), newCallFrame);
    12651281
    12661282    Profiler** profiler = Profiler::enabledProfilerReference();
     
    15901606#else
    15911607
     1608    ASSERT(callFrame->globalData().topCallFrame == callFrame);
     1609
    15921610    JSGlobalData* globalData = &callFrame->globalData();
    15931611    JSValue exceptionValue;
    15941612    HandlerInfo* handler = 0;
     1613    CallFrame** topCallFrameSlot = &globalData->topCallFrame;
    15951614
    15961615    CodeBlock* codeBlock = callFrame->codeBlock();
     
    42064225            codeBlock = newCodeBlock;
    42074226            ASSERT(codeBlock == callFrame->codeBlock());
     4227            *topCallFrameSlot = callFrame;
    42084228            vPC = newCodeBlock->instructions().begin();
    42094229
     
    42244244
    42254245            newCallFrame->init(0, vPC + OPCODE_LENGTH(op_call), scopeChain, callFrame, argCount, asObject(v));
    4226 
    42274246            JSValue returnValue;
    42284247            {
     4248                *topCallFrameSlot = newCallFrame;
    42294249                SamplingTool::HostCallRecord callRecord(m_sampler.get());
    42304250                returnValue = JSValue::decode(callData.native.function(newCallFrame));
     4251                *topCallFrameSlot = callFrame;
    42314252            }
    42324253            CHECK_FOR_EXCEPTION();
     
    43744395            codeBlock = newCodeBlock;
    43754396            ASSERT(codeBlock == callFrame->codeBlock());
     4397            *topCallFrameSlot = callFrame;
    43764398            vPC = newCodeBlock->instructions().begin();
    43774399           
     
    43944416            JSValue returnValue;
    43954417            {
     4418                *topCallFrameSlot = newCallFrame;
    43964419                SamplingTool::HostCallRecord callRecord(m_sampler.get());
    43974420                returnValue = JSValue::decode(callData.native.function(newCallFrame));
     4421                *topCallFrameSlot = callFrame;
    43984422            }
    43994423            CHECK_FOR_EXCEPTION();
     
    44774501        vPC = callFrame->returnVPC();
    44784502        callFrame = callFrame->callerFrame();
    4479        
     4503
    44804504        if (callFrame->hasHostCallFrameFlag())
    44814505            return returnValue;
    44824506
     4507        *topCallFrameSlot = callFrame;
    44834508        functionReturnValue = returnValue;
    44844509        codeBlock = callFrame->codeBlock();
     
    45224547            return returnValue;
    45234548
     4549        *topCallFrameSlot = callFrame;
    45244550        functionReturnValue = returnValue;
    45254551        codeBlock = callFrame->codeBlock();
     
    46954721            callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_construct), callDataScopeChain, previousCallFrame, argCount, asFunction(v));
    46964722            codeBlock = newCodeBlock;
     4723            *topCallFrameSlot = callFrame;
    46974724            vPC = newCodeBlock->instructions().begin();
    46984725#if ENABLE(OPCODE_STATS)
     
    47144741            JSValue returnValue;
    47154742            {
     4743                *topCallFrameSlot = newCallFrame;
    47164744                SamplingTool::HostCallRecord callRecord(m_sampler.get());
    47174745                returnValue = JSValue::decode(constructData.native.function(newCallFrame));
     4746                *topCallFrameSlot = callFrame;
    47184747            }
    47194748            CHECK_FOR_EXCEPTION();
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r91095 r93755  
    6161        WillLeaveCallFrame,
    6262        WillExecuteStatement
     63    };
     64
     65    class TopCallFrameSetter {
     66    public:
     67        TopCallFrameSetter(JSGlobalData& global, CallFrame* callFrame)
     68            : globalData(global)
     69            , oldCallFrame(global.topCallFrame)
     70        {
     71            global.topCallFrame = callFrame;
     72        }
     73       
     74        ~TopCallFrameSetter()
     75        {
     76            globalData.topCallFrame = oldCallFrame;
     77        }
     78    private:
     79        JSGlobalData& globalData;
     80        CallFrame* oldCallFrame;
    6381    };
    6482
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r93698 r93755  
    371371        static const int patchOffsetGetByIdSlowCaseCall = 37;
    372372#else
    373         static const int patchOffsetGetByIdSlowCaseCall = 27;
     373        static const int patchOffsetGetByIdSlowCaseCall = 33;
    374374#endif
    375375        static const int patchOffsetOpCallCompareToJump = 6;
     
    429429        #error "OPCODE_SAMPLING is not yet supported"
    430430#else
    431         static const int patchOffsetGetByIdSlowCaseCall = 30;
     431        static const int patchOffsetGetByIdSlowCaseCall = 40;
    432432#endif
    433433        static const int patchOffsetOpCallCompareToJump = 16;
     
    607607        static const int patchOffsetGetByIdSlowCaseCall = 64;
    608608#else
    609         static const int patchOffsetGetByIdSlowCaseCall = 41;
     609        static const int patchOffsetGetByIdSlowCaseCall = 54;
    610610#endif
    611611        static const int patchOffsetOpCallCompareToJump = 9;
     
    962962        void restoreArgumentReference();
    963963        void restoreArgumentReferenceForTrampoline();
     964        void updateTopCallFrame();
    964965
    965966        Call emitNakedCall(CodePtr function = CodePtr());
  • trunk/Source/JavaScriptCore/jit/JITInlineMethods.h

    r93466 r93755  
    254254}
    255255
     256ALWAYS_INLINE void JIT::updateTopCallFrame()
     257{
     258    storePtr(callFrameRegister, &m_globalData->topCallFrame);
     259}
     260
    256261ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
    257262{
  • trunk/Source/JavaScriptCore/jit/JITStubCall.h

    r82130 r93755  
    173173
    174174            m_jit->restoreArgumentReference();
     175            m_jit->updateTopCallFrame();
    175176            JIT::Call call = m_jit->call();
    176177            m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeOffset, m_stub.value()));
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r92797 r93755  
    10471047}
    10481048
     1049// Helper function for JIT stubs that may throw an exception in the middle of
     1050// processing a function call. This function rolls back the register file to
     1051// our caller, so exception processing can proceed from a valid state.
     1052static ALWAYS_INLINE ExceptionHandler throwExceptionFromOpCall(CallFrame* oldCallFrame, CallFrame* newCallFrame)
     1053{
     1054    oldCallFrame->globalData().topCallFrame = oldCallFrame;
     1055    return jitThrow(&oldCallFrame->globalData(), oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(newCallFrame->returnPC()));
     1056}
     1057
    10491058#if CPU(ARM_THUMB2) && COMPILER(GCC)
    10501059
     
    13511360
    13521361    if (UNLIKELY(!stackFrame.registerFile->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
    1353         // Rewind to the previous call frame because op_call already optimistically
    1354         // moved the call frame forward.
    1355         CallFrame* oldCallFrame = callFrame->callerFrame();
    1356         ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(callFrame->returnPC()));
     1362        ExceptionHandler handler = throwExceptionFromOpCall(callFrame->callerFrame(), callFrame);
    13571363        STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
    13581364        callFrame = handler.callFrame;
     
    19511957        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
    19521958        if (!stackFrame.registerFile->grow(newEnd)) {
    1953             // Rewind to the previous call frame because op_call already optimistically
    1954             // moved the call frame forward.
    1955             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
     1959            ExceptionHandler handler = throwExceptionFromOpCall(oldCallFrame, callFrame);
    19561960            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
    19571961            return handler.callFrame;
     
    19661970        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
    19671971        if (!stackFrame.registerFile->grow(newEnd)) {
    1968             // Rewind to the previous call frame because op_call already optimistically
    1969             // moved the call frame forward.
    1970             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
     1972            ExceptionHandler handler = throwExceptionFromOpCall(oldCallFrame, callFrame);
    19711973            stubReturnAddress = ReturnAddressPtr(handler.catchRoutine);
    19721974            return handler.callFrame;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r93688 r93755  
    163163    : globalDataType(globalDataType)
    164164    , clientData(0)
     165    , topCallFrame(CallFrame::noCaller())
    165166    , arrayConstructorTable(fastNew<HashTable>(JSC::arrayConstructorTable))
    166167    , arrayPrototypeTable(fastNew<HashTable>(JSC::arrayPrototypeTable))
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r93688 r93755  
    136136        GlobalDataType globalDataType;
    137137        ClientData* clientData;
     138        CallFrame* topCallFrame;
    138139
    139140        const HashTable* arrayConstructorTable;
Note: See TracChangeset for help on using the changeset viewer.