void InspectorTimelineAgent::internalStart(const int* maxCallStackDepth)
{
    if (m_enabled)
        return;

    if (maxCallStackDepth && *maxCallStackDepth > 0)
        m_maxCallStackDepth = *maxCallStackDepth;
    else
        m_maxCallStackDepth = 5;

    m_instrumentingAgents.setInspectorTimelineAgent(this);

    if (m_scriptDebugServer)
        m_scriptDebugServer->addListener(this);

    m_enabled = true;

    // FIXME: Abstract away platform-specific code once https://bugs.webkit.org/show_bug.cgi?id=142748 is fixed.

#if PLATFORM(COCOA)
    m_frameStartObserver = RunLoopObserver::create(0, [this]() {
        if (!m_enabled || m_scriptDebugServer->isPaused())
            return;

        if (!m_runLoopNestingLevel)
            pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RenderingFrame, false, nullptr);
        m_runLoopNestingLevel++;
    });

    m_frameStopObserver = RunLoopObserver::create(frameStopRunLoopOrder, [this]() {
        if (!m_enabled || m_scriptDebugServer->isPaused())
            return;

        ASSERT(m_runLoopNestingLevel > 0);
        m_runLoopNestingLevel--;
        if (m_runLoopNestingLevel)
            return;

        if (m_startedComposite)
            didComposite();

        didCompleteCurrentRecord(TimelineRecordType::RenderingFrame);
    });

    m_frameStartObserver->schedule(currentRunLoop(), kCFRunLoopEntry | kCFRunLoopAfterWaiting);
    m_frameStopObserver->schedule(currentRunLoop(), kCFRunLoopExit | kCFRunLoopBeforeWaiting);

    // Create a runloop record and increment the runloop nesting level, to capture the current turn of the main runloop
    // (which is the outer runloop if recording started while paused in the debugger).
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RenderingFrame, false, nullptr);

    m_runLoopNestingLevel = 1;
#endif

    m_frontendDispatcher->recordingStarted(timestamp());
}
Example #2
0
bool InspectorTimelineAgent::willDispatchEventOnWindow(const Event& event, DOMWindow* window)
{
    if (!window->hasEventListeners(event.type()))
        return false;
    pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), TimelineRecordType::EventDispatch, false, window->frame());
    return true;
}
Example #3
0
bool InspectorTimelineAgent::willDispatchXHRLoadEvent(ScriptExecutionContext* context, XMLHttpRequest* request)
{
    if (!request->hasEventListeners(eventNames().loadEvent))
        return false;
    pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(request->url().string()), TimelineRecordType::XHRLoad, true, frameForScriptExecutionContext(context));
    return true;
}
Example #4
0
bool InspectorTimelineAgent::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath)
{
    if (!eventHasListeners(event.type(), window, node, eventPath))
       return false;

    pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), TimelineRecordType::EventDispatch, false, document->frame());
    return true;
}
void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame);

    if (frame && !m_callStackDepth)
        startProfiling(frame, ASCIILiteral("Timeline FunctionCall"), m_instrumentingAgents.inspectorEnvironment().executionStopwatch());

    ++m_callStackDepth;
}
void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber, Frame& frame)
{
    pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, &frame);

    if (!m_callStackDepth) {
        ++m_callStackDepth;
        startProfiling(&frame, ASCIILiteral("Timeline EvaluateScript"), m_instrumentingAgents.inspectorEnvironment().executionStopwatch());
    }
}
void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame);

    if (frame && !m_recordingProfile) {
        m_recordingProfile = true;
        startProfiling(frame, ASCIILiteral("Timeline EvaluateScript"));
    }
}
void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame);

    if (frame && !m_recordingProfile) {
        m_recordingProfile = true;
        startProfiling(frame, ASCIILiteral("Timeline FunctionCall"));
    }
}
Example #9
0
void InspectorTimelineAgent::willPaint(RenderObject* renderer)
{
    Frame* frame = renderer->frame();
    TRACE_EVENT_INSTANT2("instrumentation", InstrumentationEvents::Paint,
        InstrumentationEventArguments::PageId, reinterpret_cast<unsigned long long>(frame->page()),
        InstrumentationEventArguments::NodeId, idForNode(renderer->generatingNode()));

    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Paint, true, frame, true);
}
void InspectorTimelineAgent::willLayout(Frame& frame)
{
    auto* root = frame.view()->layoutRoot();
    bool partialLayout = !!root;

    if (!partialLayout)
        root = frame.contentRenderer();

    unsigned dirtyObjects = 0;
    unsigned totalObjects = 0;
    for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) {
        ++totalObjects;
        if (o->needsLayout())
            ++dirtyObjects;
    }
    pushCurrentRecord(TimelineRecordFactory::createLayoutData(dirtyObjects, totalObjects, partialLayout), TimelineRecordType::Layout, true, &frame);
}
void InspectorTimelineAgent::willWriteHTML(unsigned startLine, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createParseHTMLData(startLine), TimelineRecordType::ParseHTML, true, frame);
}
void InspectorTimelineAgent::willScroll(Frame& frame)
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::ScrollLayer, false, &frame);
}
void InspectorTimelineAgent::willPaint(Frame& frame)
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Paint, true, &frame);
}
void InspectorTimelineAgent::willComposite(Frame& frame)
{
    ASSERT(!m_startedComposite);
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Composite, true, &frame);
    m_startedComposite = true;
}
void InspectorTimelineAgent::willRecalculateStyle(Frame* frame)
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::RecalculateStyles, true, frame);
}
Example #16
0
void InspectorTimelineAgent::willResizeImage(bool shouldCache)
{
    pushCurrentRecord(TimelineRecordFactory::createResizeImageData(shouldCache), TimelineRecordType::ResizeImage, true, 0);
}
void InspectorTimelineAgent::willDispatchXHRLoadEvent(const String& url, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(url), TimelineRecordType::XHRLoad, true, frame);
}
void InspectorTimelineAgent::willFireAnimationFrame(int callbackId, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createAnimationFrameData(callbackId), TimelineRecordType::FireAnimationFrame, false, frame);
}
Example #19
0
void InspectorTimelineAgent::willProcessTask()
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Program, false, 0);
}
Example #20
0
void InspectorTimelineAgent::willReceiveResourceResponse(unsigned long identifier, const ResourceResponse& response, Frame* frame)
{
    String requestId = IdentifiersFactory::requestId(identifier);
    pushCurrentRecord(TimelineRecordFactory::createResourceReceiveResponseData(requestId, response), TimelineRecordType::ResourceReceiveResponse, false, frame);
}
Example #21
0
void InspectorTimelineAgent::willReceiveResourceData(unsigned long identifier, Frame* frame, int length)
{
    String requestId = IdentifiersFactory::requestId(identifier);
    pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(requestId, length), TimelineRecordType::ResourceReceivedData, false, frame);
}
Example #22
0
void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame);
}
Example #23
0
void InspectorTimelineAgent::willComposite()
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::CompositeLayers, false, 0);
}
void InspectorTimelineAgent::willFireTimer(int timerId, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createGenericTimerData(timerId), TimelineRecordType::TimerFire, false, frame);
}
void InspectorTimelineAgent::willDispatchXHRReadyStateChangeEvent(const String& url, int readyState, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createXHRReadyStateChangeData(url, readyState), TimelineRecordType::XHRReadyStateChange, false, frame);
}
Example #26
0
void InspectorTimelineAgent::willLayout(Frame* frame)
{
    pushCurrentRecord(InspectorObject::create(), TimelineRecordType::Layout, true, frame);
}
Example #27
0
void InspectorTimelineAgent::willCallFunction(const String& scriptName, int scriptLine, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frame);
}
Example #28
0
void InspectorTimelineAgent::willDecodeImage(const String& imageType)
{
    pushCurrentRecord(TimelineRecordFactory::createDecodeImageData(imageType), TimelineRecordType::DecodeImage, true, 0);
}
void InspectorTimelineAgent::pushCurrentRecord(RefPtr<InspectorObject>&& data, TimelineRecordType type, bool captureCallStack, Frame* frame)
{
    pushCurrentRecord(createRecordEntry(WTF::move(data), type, captureCallStack, frame));
}
void InspectorTimelineAgent::willDispatchEvent(const Event& event, Frame* frame)
{
    pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), TimelineRecordType::EventDispatch, false, frame);
}