Changeset 155075 in webkit


Ignore:
Timestamp:
Sep 4, 2013 3:33:57 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Refining the StackIterator callback interface.
https://bugs.webkit.org/show_bug.cgi?id=120695.

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Introduce CallFrame::iterate() which instantiates a StackIterator and
invoke its iterate() method with the passed in functor. The only place
where the client code gets access to the StackIterator now is as an
argument to the client's functor.

  • API/JSContextRef.cpp:

(JSContextCreateBacktrace):

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

(JSC::ExecState::iterate):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::dumpRegisters):
(JSC::Interpreter::getStackTrace):
(JSC::Interpreter::unwind):

  • interpreter/StackIterator.cpp:

(JSC::StackIterator::StackIterator):
(DebugPrintFrameFunctor::DebugPrintFrameFunctor):
(DebugPrintFrameFunctor::operator()):
(debugPrintCallFrame):
(debugPrintStack):

  • interpreter/StackIterator.h:

(JSC::StackIterator::iterate):

  • jsc.cpp:

(functionJSCStack):

  • profiler/ProfileGenerator.cpp:

(JSC::ProfileGenerator::addParentForConsoleStart):

  • runtime/JSFunction.cpp:

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

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncProtoGetter):
(JSC::globalFuncProtoSetter):

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorGetPrototypeOf):

Source/WebCore:

No new tests.

  • bindings/js/JSXMLHttpRequestCustom.cpp:

(WebCore::SendFunctor::SendFunctor):
(WebCore::SendFunctor::line):
(WebCore::SendFunctor::url):
(WebCore::SendFunctor::operator()):
(WebCore::JSXMLHttpRequest::send):

  • bindings/js/ScriptCallStackFactory.cpp:

(WebCore::createScriptCallStack):

Location:
trunk/Source
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSContextRef.cpp

    r155013 r155075  
    275275    ASSERT(maxStackSize);
    276276    BacktraceFunctor functor(builder, maxStackSize);
    277     StackIterator iter = frame->begin();
    278     iter.iterate(functor);
     277    frame->iterate(functor);
    279278
    280279    return OpaqueJSString::create(builder.toString()).leakRef();
  • trunk/Source/JavaScriptCore/ChangeLog

    r155064 r155075  
     12013-09-04  Mark Lam  <mark.lam@apple.com>
     2
     3        Refining the StackIterator callback interface.
     4        https://bugs.webkit.org/show_bug.cgi?id=120695.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        Introduce CallFrame::iterate() which instantiates a StackIterator and
     9        invoke its iterate() method with the passed in functor. The only place
     10        where the client code gets access to the StackIterator now is as an
     11        argument to the client's functor.
     12
     13        * API/JSContextRef.cpp:
     14        (JSContextCreateBacktrace):
     15        * interpreter/CallFrame.cpp:
     16        * interpreter/CallFrame.h:
     17        (JSC::ExecState::iterate):
     18        * interpreter/Interpreter.cpp:
     19        (JSC::Interpreter::dumpRegisters):
     20        (JSC::Interpreter::getStackTrace):
     21        (JSC::Interpreter::unwind):
     22        * interpreter/StackIterator.cpp:
     23        (JSC::StackIterator::StackIterator):
     24        (DebugPrintFrameFunctor::DebugPrintFrameFunctor):
     25        (DebugPrintFrameFunctor::operator()):
     26        (debugPrintCallFrame):
     27        (debugPrintStack):
     28        * interpreter/StackIterator.h:
     29        (JSC::StackIterator::iterate):
     30        * jsc.cpp:
     31        (functionJSCStack):
     32        * profiler/ProfileGenerator.cpp:
     33        (JSC::ProfileGenerator::addParentForConsoleStart):
     34        * runtime/JSFunction.cpp:
     35        (JSC::retrieveArguments):
     36        (JSC::RetrieveCallerFunctionFunctor::operator()):
     37        (JSC::retrieveCallerFunction):
     38        * runtime/JSGlobalObjectFunctions.cpp:
     39        (JSC::globalFuncProtoGetter):
     40        (JSC::globalFuncProtoSetter):
     41        * runtime/ObjectConstructor.cpp:
     42        (JSC::objectConstructorGetPrototypeOf):
     43
    1442013-09-04  Benjamin Poulain  <benjamin@webkit.org>
    245
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp

    r155013 r155075  
    9898}
    9999
    100 StackIterator CallFrame::begin(StackIterator::FrameFilter filter)
    101 {
    102     ASSERT(this);
    103     return StackIterator(this, filter);
    104 }
    105 
    106100} // namespace JSC
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r155013 r155075  
    284284        CallFrame* callerFrameNoFlags() { return callerFrame()->removeHostCallFrameFlag(); }
    285285
    286         JS_EXPORT_PRIVATE StackIterator begin(StackIterator::FrameFilter = 0);
     286        // CallFrame::iterate() expects a Functor that implements the following method:
     287        //     StackIterator::Status operator()(StackIterator&);
     288
     289        template <typename Functor> void iterate(Functor& functor)
     290        {
     291            StackIterator iter(this);
     292            iter.iterate<Functor>(functor);
     293        }
    287294
    288295    private:
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r155013 r155075  
    340340
    341341    DumpRegisterFunctor functor(it);
    342     StackIterator iter = callFrame->begin();
    343     iter.iterate(functor);
     342    callFrame->iterate(functor);
    344343
    345344    dataLogF("[CodeBlock]                | %10p | %p \n", it, callFrame->codeBlock());
     
    553552
    554553    GetStackTraceFunctor functor(vm, results, maxStackSize);
    555     StackIterator iter = callFrame->begin();
    556     iter.iterate(functor);
     554    callFrame->iterate(functor);
    557555}
    558556
     
    641639    ASSERT(callFrame == vm.topCallFrame);
    642640    UnwindFunctor functor(callFrame, exceptionValue, isTermination, codeBlock, handler);
    643     StackIterator iter = callFrame->begin();
    644     iter.iterate(functor);
     641    callFrame->iterate(functor);
    645642    if (!handler)
    646643        return 0;
  • trunk/Source/JavaScriptCore/interpreter/StackIterator.cpp

    r155013 r155075  
    3636namespace JSC {
    3737
    38 StackIterator::StackIterator(CallFrame* startFrame, StackIterator::FrameFilter filter)
     38StackIterator::StackIterator(CallFrame* startFrame)
    3939    : m_startFrame(startFrame)
    40     , m_filter(filter)
    4140{
    4241    resetIterator();
    43 }
    44 
    45 size_t StackIterator::numberOfFrames()
    46 {
    47     int savedFrameIndex = m_frame.index();
    48     resetIterator();
    49     while (m_frame.callFrame())
    50         gotoNextFrameWithFilter();
    51     size_t numberOfFrames = m_frame.index();
    52 
    53     resetIterator();
    54     gotoFrameAtIndex(savedFrameIndex);
    55 
    56     return numberOfFrames;
    57 }
    58 
    59 void StackIterator::gotoFrameAtIndex(size_t index)
    60 {
    61     while (m_frame.callFrame() && (m_frame.index() != index))
    62         gotoNextFrameWithFilter();
    6342}
    6443
     
    7453#endif // ENABLE(DFG_JIT)
    7554        readFrame(m_frame.callerFrame());
    76 }
    77 
    78 void StackIterator::gotoNextFrameWithFilter()
    79 {
    80     ASSERT(m_frame.callFrame());
    81     while (m_frame.callFrame()) {
    82         gotoNextFrame();
    83         if (!m_frame.callFrame() || !m_filter || !m_filter(&m_frame))
    84             break;
    85     }
    86     m_frame.m_index++;
    8755}
    8856
     
    456424void debugPrintStack(JSC::CallFrame* topCallFrame);
    457425
    458 void debugPrintCallFrame(JSC::CallFrame* callFrame)
    459 {
    460     if (!callFrame)
    461         return;
    462     StackIterator iter = callFrame->begin();
    463     iter->print(2);
    464 }
    465 
    466 class DebugPrintStackFunctor {
     426class DebugPrintFrameFunctor {
    467427public:
     428    enum Action {
     429        PrintOne,
     430        PrintAll
     431    };
     432
     433    DebugPrintFrameFunctor(Action action)
     434        : m_action(action)
     435    {
     436    }
     437
    468438    StackIterator::Status operator()(StackIterator& iter)
    469439    {
    470440        iter->print(2);
    471         return StackIterator::Continue;
    472     }
     441        return m_action == PrintAll ? StackIterator::Continue : StackIterator::Done;
     442    }
     443
     444private:
     445    Action m_action;
    473446};
    474447
     448void debugPrintCallFrame(JSC::CallFrame* callFrame)
     449{
     450    if (!callFrame)
     451        return;
     452    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintOne);
     453    callFrame->iterate(functor);
     454}
     455
    475456void debugPrintStack(JSC::CallFrame* topCallFrame)
    476457{
    477458    if (!topCallFrame)
    478459        return;
    479     DebugPrintStackFunctor functor;
    480     StackIterator iter = topCallFrame->begin();
    481     iter.iterate(functor);
    482 }
     460    DebugPrintFrameFunctor functor(DebugPrintFrameFunctor::PrintAll);
     461    topCallFrame->iterate(functor);
     462}
     463
    483464#endif // !NDEBUG
  • trunk/Source/JavaScriptCore/interpreter/StackIterator.h

    r155013 r155075  
    101101        InlineCallFrame* m_inlineCallFrame;
    102102#endif
    103 
    104103        CallFrame* m_callFrame;
    105104
    106105        friend class StackIterator;
    107106    };
    108 
    109     typedef bool (*FrameFilter)(Frame*);
    110107
    111108    enum Status {
     
    123120            if (status != Continue)
    124121                break;
    125             gotoNextFrameWithFilter();
     122            gotoNextFrame();
    126123        }
    127124    }
    128 
    129     JS_EXPORT_PRIVATE size_t numberOfFrames();
    130125
    131126    Frame& operator*() { return m_frame; }
     
    133128
    134129private:
    135     JS_EXPORT_PRIVATE StackIterator(CallFrame* startFrame, FrameFilter = 0);
     130    JS_EXPORT_PRIVATE StackIterator(CallFrame* startFrame);
    136131
    137     void gotoFrameAtIndex(size_t frameIndex);
    138     void gotoNextFrame();
    139     JS_EXPORT_PRIVATE void gotoNextFrameWithFilter();
     132    JS_EXPORT_PRIVATE void gotoNextFrame();
    140133    void resetIterator();
    141134
     
    147140
    148141    CallFrame* m_startFrame;
    149     FrameFilter m_filter;
    150142    Frame m_frame;
    151143
  • trunk/Source/JavaScriptCore/jsc.cpp

    r155013 r155075  
    350350
    351351    FunctionJSCStackFunctor functor(trace);
    352     StackIterator iter = exec->begin();
    353     iter.iterate(functor);
     352    exec->iterate(functor);
    354353    fprintf(stderr, "%s", trace.toString().utf8().data());
    355354    return JSValue::encode(jsUndefined());
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp

    r155013 r155075  
    9999{
    100100    AddParentForConsoleStartFunctor functor(exec, m_head, m_currentNode);
    101     StackIterator iter = exec->begin();
    102     iter.iterate(functor);
     101    exec->iterate(functor);
    103102
    104103    if (!functor.foundParent()) {
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r155013 r155075  
    211211{
    212212    RetrieveArgumentsFunctor functor(functionObj);
    213     StackIterator iter = exec->begin();
    214     iter.iterate(functor);
     213    exec->iterate(functor);
    215214    return functor.result();
    216215}
     
    222221
    223222    return retrieveArguments(exec, thisObj);
    224 }
    225 
    226 static bool skipOverBoundFunctions(StackIterator::Frame* frame)
    227 {
    228     JSObject* callee = frame->callee();
    229     bool shouldSkip = callee ? callee->inherits(JSBoundFunction::info()) : false;
    230     return shouldSkip;
    231223}
    232224
     
    246238    {
    247239        JSObject* callee = iter->callee();
     240
     241        if (callee && callee->inherits(JSBoundFunction::info()))
     242            return StackIterator::Continue;
     243
    248244        if (!m_hasFoundFrame && (callee != m_targetCallee))
    249245            return StackIterator::Continue;
     
    270266{
    271267    RetrieveCallerFunctionFunctor functor(functionObj);
    272     StackIterator iter = exec->begin(skipOverBoundFunctions);
    273     iter.iterate(functor);
     268    exec->iterate(functor);
    274269    return functor.result();
    275270}
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r155013 r155075  
    745745
    746746    GlobalFuncProtoGetterFunctor functor(thisObject);
    747     StackIterator iter = exec->begin();
    748     iter.iterate(functor);
     747    exec->iterate(functor);
    749748    return functor.result();
    750749}
     
    789788
    790789    GlobalFuncProtoSetterFunctor functor(thisObject);
    791     StackIterator iter = exec->begin();
    792     iter.iterate(functor);
     790    exec->iterate(functor);
    793791    if (!functor.allowsAccess())
    794792        return JSValue::encode(jsUndefined());
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r155013 r155075  
    167167    JSObject* object = asObject(exec->argument(0));
    168168    ObjectConstructorGetPrototypeOfFunctor functor(object);
    169     StackIterator iter = exec->begin();
    170     iter.iterate(functor);
     169    exec->iterate(functor);
    171170    return functor.result();
    172171}
  • trunk/Source/WebCore/ChangeLog

    r155074 r155075  
     12013-09-04  Mark Lam  <mark.lam@apple.com>
     2
     3        Refining the StackIterator callback interface.
     4        https://bugs.webkit.org/show_bug.cgi?id=120695.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        No new tests.
     9
     10        * bindings/js/JSXMLHttpRequestCustom.cpp:
     11        (WebCore::SendFunctor::SendFunctor):
     12        (WebCore::SendFunctor::line):
     13        (WebCore::SendFunctor::url):
     14        (WebCore::SendFunctor::operator()):
     15        (WebCore::JSXMLHttpRequest::send):
     16        * bindings/js/ScriptCallStackFactory.cpp:
     17        (WebCore::createScriptCallStack):
     18
    1192013-09-04  Andreas Kling  <akling@apple.com>
    220
  • trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp

    r155013 r155075  
    117117    SendFunctor()
    118118        : m_hasSkippedFirstFrame(false)
    119         , m_hasViableFrame(false)
     119        , m_line(0)
    120120    {
    121121    }
    122122
    123     bool hasViableFrame() const { return m_hasViableFrame; }
    124 
    125     StackIterator::Status operator()(StackIterator&)
     123    unsigned line() const { return m_line; }
     124    String url() const { return m_url; }
     125
     126    StackIterator::Status operator()(StackIterator& iter)
    126127    {
    127128        if (!m_hasSkippedFirstFrame) {
     
    130131        }
    131132
    132         m_hasViableFrame = true;
     133        unsigned line = 0;
     134        unsigned unusedColumn = 0;
     135        iter->computeLineAndColumn(line, unusedColumn);
     136        m_line = line;
     137        m_url = iter->sourceURL();
    133138        return StackIterator::Done;
    134139    }
     
    136141private:
    137142    bool m_hasSkippedFirstFrame;
    138     bool m_hasViableFrame;
     143    unsigned m_line;
     144    String m_url;
    139145};
    140146
     
    166172
    167173    SendFunctor functor;
    168     StackIterator iter = exec->begin();
    169     iter.iterate(functor);
    170     if (functor.hasViableFrame()) {
    171         unsigned line = 0;
    172         unsigned unusuedColumn = 0;
    173         iter->computeLineAndColumn(line, unusuedColumn);
    174         impl()->setLastSendLineNumber(line);
    175         impl()->setLastSendURL(iter->sourceURL());
    176     } else {
    177         impl()->setLastSendLineNumber(0);
    178         impl()->setLastSendURL(String());
    179     }
     174    exec->iterate(functor);
     175    impl()->setLastSendLineNumber(functor.line());
     176    impl()->setLastSendURL(functor.url());
    180177    setDOMException(exec, ec);
    181178    return jsUndefined();
  • trunk/Source/WebCore/bindings/js/ScriptCallStackFactory.cpp

    r155013 r155075  
    8888        CallFrame* frame = exec->vm().topCallFrame;
    8989        CreateScriptCallStackFunctor functor(frames, maxStackSize);
    90         StackIterator iter = frame->begin();
    91         iter.iterate(functor);
     90        frame->iterate(functor);
    9291    }
    9392    if (frames.isEmpty() && !emptyIsAllowed) {
     
    145144    ASSERT(exec);
    146145    CallFrame* frame = exec->vm().topCallFrame;
    147     StackIterator iter = frame->begin();
    148     size_t numberOfFrames = iter.numberOfFrames();
    149     CreateScriptCallStackForConsoleFunctor functor(numberOfFrames > 1, maxStackSize, frames);
    150     iter.iterate(functor);
     146    CreateScriptCallStackForConsoleFunctor functor(true, maxStackSize, frames);
     147    frame->iterate(functor);
     148    if (frames.isEmpty()) {
     149        CreateScriptCallStackForConsoleFunctor functor(false, maxStackSize, frames);
     150        frame->iterate(functor);
     151    }
    151152    return ScriptCallStack::create(frames);
    152153}
Note: See TracChangeset for help on using the changeset viewer.