Ignore:
Timestamp:
Sep 3, 2013, 5:26:57 PM (12 years ago)
Author:
[email protected]
Message:

Converting StackIterator to a callback interface.
https://bugs.webkit.org/show_bug.cgi?id=120564.

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

  • API/JSContextRef.cpp:

(BacktraceFunctor::BacktraceFunctor):
(BacktraceFunctor::operator()):
(JSContextCreateBacktrace):

  • interpreter/CallFrame.cpp:
  • interpreter/CallFrame.h:
  • interpreter/Interpreter.cpp:

(JSC::DumpRegisterFunctor::DumpRegisterFunctor):
(JSC::DumpRegisterFunctor::operator()):
(JSC::Interpreter::dumpRegisters):
(JSC::unwindCallFrame):
(JSC::GetStackTraceFunctor::GetStackTraceFunctor):
(JSC::GetStackTraceFunctor::operator()):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::stackTraceAsString):
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::Interpreter::unwind):

  • interpreter/Interpreter.h:
  • interpreter/StackIterator.cpp:

(JSC::StackIterator::numberOfFrames):
(JSC::StackIterator::gotoFrameAtIndex):
(JSC::StackIterator::gotoNextFrameWithFilter):
(JSC::StackIterator::resetIterator):
(JSC::StackIterator::Frame::print):
(debugPrintCallFrame):
(DebugPrintStackFunctor::operator()):
(debugPrintStack): Added for debugging convenience.

  • interpreter/StackIterator.h:

(JSC::StackIterator::Frame::index):
(JSC::StackIterator::iterate):

  • jsc.cpp:

(FunctionJSCStackFunctor::FunctionJSCStackFunctor):
(FunctionJSCStackFunctor::operator()):
(functionJSCStack):

  • profiler/ProfileGenerator.cpp:

(JSC::AddParentForConsoleStartFunctor::AddParentForConsoleStartFunctor):
(JSC::AddParentForConsoleStartFunctor::foundParent):
(JSC::AddParentForConsoleStartFunctor::operator()):
(JSC::ProfileGenerator::addParentForConsoleStart):

  • runtime/JSFunction.cpp:

(JSC::RetrieveArgumentsFunctor::RetrieveArgumentsFunctor):
(JSC::RetrieveArgumentsFunctor::result):
(JSC::RetrieveArgumentsFunctor::operator()):
(JSC::retrieveArguments):
(JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
(JSC::RetrieveCallerFunctionFunctor::result):
(JSC::RetrieveCallerFunctionFunctor::operator()):
(JSC::retrieveCallerFunction):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::GlobalFuncProtoGetterFunctor::GlobalFuncProtoGetterFunctor):
(JSC::GlobalFuncProtoGetterFunctor::result):
(JSC::GlobalFuncProtoGetterFunctor::operator()):
(JSC::globalFuncProtoGetter):
(JSC::GlobalFuncProtoSetterFunctor::GlobalFuncProtoSetterFunctor):
(JSC::GlobalFuncProtoSetterFunctor::allowsAccess):
(JSC::GlobalFuncProtoSetterFunctor::operator()):
(JSC::globalFuncProtoSetter):

  • runtime/ObjectConstructor.cpp:

(JSC::ObjectConstructorGetPrototypeOfFunctor::ObjectConstructorGetPrototypeOfFunctor):
(JSC::ObjectConstructorGetPrototypeOfFunctor::result):
(JSC::ObjectConstructorGetPrototypeOfFunctor::operator()):
(JSC::objectConstructorGetPrototypeOf):

Source/WebCore:

No new tests.

  • bindings/js/JSXMLHttpRequestCustom.cpp:

(WebCore::SendFunctor::SendFunctor):
(WebCore::SendFunctor::hasViableFrame):
(WebCore::SendFunctor::operator()):
(WebCore::JSXMLHttpRequest::send):

  • bindings/js/ScriptCallStackFactory.cpp:

(WebCore::CreateScriptCallStackFunctor::CreateScriptCallStackFunctor):
(WebCore::CreateScriptCallStackFunctor::operator()):
(WebCore::createScriptCallStack):
(WebCore::CreateScriptCallStackForConsoleFunctor::CreateScriptCallStackForConsoleFunctor):
(WebCore::CreateScriptCallStackForConsoleFunctor::operator()):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r154935 r155013  
    275275}
    276276
     277class DumpRegisterFunctor {
     278public:
     279    DumpRegisterFunctor(const Register*& it)
     280        : m_hasSkippedFirstFrame(false)
     281        , m_it(it)
     282    {
     283    }
     284
     285    StackIterator::Status operator()(StackIterator& iter)
     286    {
     287        if (!m_hasSkippedFirstFrame) {
     288            m_hasSkippedFirstFrame = true;
     289            return StackIterator::Continue;
     290        }
     291
     292        unsigned line = 0;
     293        unsigned unusedColumn = 0;
     294        iter->computeLineAndColumn(line, unusedColumn);
     295        dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", m_it, iter->bytecodeOffset(), line);
     296        ++m_it;
     297        return StackIterator::Done;
     298    }
     299
     300private:
     301    bool m_hasSkippedFirstFrame;
     302    const Register*& m_it;
     303};
     304
    277305void Interpreter::dumpRegisters(CallFrame* callFrame)
    278306{
     
    310338        dataLogF("[ReturnJITPC]              | %10p | %p \n", it, pc.jitReturnAddress().value());
    311339#endif
     340
     341    DumpRegisterFunctor functor(it);
    312342    StackIterator iter = callFrame->begin();
    313     ++iter;
    314     if (iter != callFrame->end()) {
    315         unsigned line = 0;
    316         unsigned unusedColumn = 0;
    317         iter->computeLineAndColumn(line, unusedColumn);
    318         dataLogF("[ReturnVPC]                | %10p | %d (line %d)\n", it, iter->bytecodeOffset(), line);
    319         ++it;
    320     }
     343    iter.iterate(functor);
     344
    321345    dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
    322346    ++it;
     
    367391}
    368392
    369 NEVER_INLINE bool Interpreter::unwindCallFrame(StackIterator& iter, JSValue exceptionValue)
     393static bool unwindCallFrame(StackIterator& iter, JSValue exceptionValue)
    370394{
    371395    CallFrame* callFrame = iter->callFrame();
     
    475499}
    476500
     501class GetStackTraceFunctor {
     502public:
     503    GetStackTraceFunctor(VM& vm, Vector<StackFrame>& results, size_t remainingCapacity)
     504        : m_vm(vm)
     505        , m_results(results)
     506        , m_remainingCapacityForFrameCapture(remainingCapacity)
     507    {
     508    }
     509
     510    StackIterator::Status operator()(StackIterator& iter)
     511    {
     512        VM& vm = m_vm;
     513        if (m_remainingCapacityForFrameCapture) {
     514            if (iter->isJSFrame()) {
     515                CodeBlock* codeBlock = iter->codeBlock();
     516                StackFrame s = {
     517                    Strong<JSObject>(vm, iter->callee()),
     518                    getStackFrameCodeType(iter),
     519                    Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
     520                    Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
     521                    codeBlock->source(),
     522                    codeBlock->ownerExecutable()->lineNo(),
     523                    codeBlock->firstLineColumnOffset(),
     524                    codeBlock->sourceOffset(),
     525                    iter->bytecodeOffset(),
     526                    iter->sourceURL()
     527                };
     528                m_results.append(s);
     529            } else {
     530                StackFrame s = { Strong<JSObject>(vm, iter->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
     531                m_results.append(s);
     532            }
     533   
     534            m_remainingCapacityForFrameCapture--;
     535            return StackIterator::Continue;
     536        }
     537        return StackIterator::Done;
     538    }
     539
     540private:
     541    VM& m_vm;
     542    Vector<StackFrame>& m_results;
     543    size_t m_remainingCapacityForFrameCapture;
     544};
     545
    477546void Interpreter::getStackTrace(Vector<StackFrame>& results, size_t maxStackSize)
    478547{
     
    482551    if (!callFrame)
    483552        return;
     553
     554    GetStackTraceFunctor functor(vm, results, maxStackSize);
    484555    StackIterator iter = callFrame->begin();
    485     for (; iter != callFrame->end() && maxStackSize--; ++iter) {
    486         if (iter->isJSFrame()) {
    487             CodeBlock* codeBlock = iter->codeBlock();
    488             StackFrame s = {
    489                 Strong<JSObject>(vm, iter->callee()),
    490                 getStackFrameCodeType(iter),
    491                 Strong<ExecutableBase>(vm, codeBlock->ownerExecutable()),
    492                 Strong<UnlinkedCodeBlock>(vm, codeBlock->unlinkedCodeBlock()),
    493                 codeBlock->source(),
    494                 codeBlock->ownerExecutable()->lineNo(),
    495                 codeBlock->firstLineColumnOffset(),
    496                 codeBlock->sourceOffset(),
    497                 iter->bytecodeOffset(),
    498                 iter->sourceURL()
    499             };
    500             results.append(s);
    501         } else {
    502             StackFrame s = { Strong<JSObject>(vm, iter->callee()), StackFrameNativeCode, Strong<ExecutableBase>(), Strong<UnlinkedCodeBlock>(), 0, 0, 0, 0, 0, String()};
    503             results.append(s);
    504         }
    505     }
    506 }
    507 JSString* Interpreter:: stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
     556    iter.iterate(functor);
     557}
     558
     559JSString* Interpreter::stackTraceAsString(ExecState* exec, Vector<StackFrame> stackTrace)
    508560{
    509561    // FIXME: JSStringJoiner could be more efficient than StringBuilder here.
     
    516568    return jsString(&exec->vm(), builder.toString());
    517569}
     570
     571class UnwindFunctor {
     572public:
     573    UnwindFunctor(CallFrame*& callFrame, JSValue& exceptionValue, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)
     574        : m_callFrame(callFrame)
     575        , m_exceptionValue(exceptionValue)
     576        , m_isTermination(isTermination)
     577        , m_codeBlock(codeBlock)
     578        , m_handler(handler)
     579    {
     580    }
     581
     582    StackIterator::Status operator()(StackIterator& iter)
     583    {
     584        VM& vm = m_callFrame->vm();
     585        m_callFrame = iter->callFrame();
     586        m_codeBlock = iter->codeBlock();
     587        unsigned bytecodeOffset = iter->bytecodeOffset();
     588
     589        if (m_isTermination || !(m_handler = m_codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
     590        if (!unwindCallFrame(iter, m_exceptionValue)) {
     591            if (LegacyProfiler* profiler = vm.enabledProfiler())
     592                profiler->exceptionUnwind(m_callFrame);
     593            return StackIterator::Done;
     594        }
     595    } else
     596        return StackIterator::Done;
     597
     598    return StackIterator::Continue;
     599}
     600
     601private:
     602    CallFrame*& m_callFrame;
     603    JSValue& m_exceptionValue;
     604    bool m_isTermination;
     605    CodeBlock*& m_codeBlock;
     606    HandlerInfo*& m_handler;
     607};
    518608
    519609NEVER_INLINE HandlerInfo* Interpreter::unwind(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
     
    550640    VM& vm = callFrame->vm();
    551641    ASSERT(callFrame == vm.topCallFrame);
    552     for (StackIterator iter = callFrame->begin(); iter != callFrame->end(); ++iter) {
    553         callFrame = iter->callFrame();
    554         codeBlock = iter->codeBlock();
    555         bytecodeOffset = iter->bytecodeOffset();
    556 
    557         if (isTermination || !(handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset))) {
    558             if (!unwindCallFrame(iter, exceptionValue)) {
    559                 if (LegacyProfiler* profiler = vm.enabledProfiler())
    560                     profiler->exceptionUnwind(callFrame);
    561                 return 0;
    562             }
    563         } else
    564             break;
    565     }
    566 
    567     if (LegacyProfiler* profiler = callFrame->vm().enabledProfiler())
     642    UnwindFunctor functor(callFrame, exceptionValue, isTermination, codeBlock, handler);
     643    StackIterator iter = callFrame->begin();
     644    iter.iterate(functor);
     645    if (!handler)
     646        return 0;
     647
     648    if (LegacyProfiler* profiler = vm.enabledProfiler())
    568649        profiler->exceptionUnwind(callFrame);
    569650
Note: See TracChangeset for help on using the changeset viewer.