Changeset 202443 in webkit


Ignore:
Timestamp:
Jun 24, 2016 1:30:04 PM (8 years ago)
Author:
BJ Burg
Message:

Web Inspector: CRASH in backend at Inspector::HeapFrontendDispatcher::garbageCollected + 552 when closing frontend/inspected page
https://bugs.webkit.org/show_bug.cgi?id=159075
<rdar://problem/26094341>

Reviewed by Joseph Pecoraro.

Move the asynchronous work to a task class that can be cancelled when the
heap agent is reset, disabled or destroyed.

  • inspector/agents/InspectorHeapAgent.cpp:

(Inspector::SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask):
(Inspector::SendGarbageCollectionEventsTask::addGarbageCollection):
(Inspector::SendGarbageCollectionEventsTask::reset):
(Inspector::SendGarbageCollectionEventsTask::timerFired):
Added. This holds onto GarbageCollection objects that need to be sent asynchronously.
It uses the RunLoop variant of Timer and can queue multiple pending objects to be sent.

(Inspector::InspectorHeapAgent::InspectorHeapAgent):
(Inspector::InspectorHeapAgent::~InspectorHeapAgent):
(Inspector::InspectorHeapAgent::disable):
Reset the task when disabling or tearing down the agent so the timer doesn't fire after destruction.

(Inspector::InspectorHeapAgent::didGarbageCollect):
Send the object to the task to be dispatched asynchronously.

  • inspector/agents/InspectorHeapAgent.h:
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r202435 r202443  
     12016-06-24  Brian Burg  <bburg@apple.com>
     2
     3        Web Inspector: CRASH in backend at Inspector::HeapFrontendDispatcher::garbageCollected + 552 when closing frontend/inspected page
     4        https://bugs.webkit.org/show_bug.cgi?id=159075
     5        <rdar://problem/26094341>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Move the asynchronous work to a task class that can be cancelled when the
     10        heap agent is reset, disabled or destroyed.
     11
     12        * inspector/agents/InspectorHeapAgent.cpp:
     13        (Inspector::SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask):
     14        (Inspector::SendGarbageCollectionEventsTask::addGarbageCollection):
     15        (Inspector::SendGarbageCollectionEventsTask::reset):
     16        (Inspector::SendGarbageCollectionEventsTask::timerFired):
     17        Added. This holds onto GarbageCollection objects that need to be sent asynchronously.
     18        It uses the RunLoop variant of Timer and can queue multiple pending objects to be sent.
     19
     20        (Inspector::InspectorHeapAgent::InspectorHeapAgent):
     21        (Inspector::InspectorHeapAgent::~InspectorHeapAgent):
     22        (Inspector::InspectorHeapAgent::disable):
     23        Reset the task when disabling or tearing down the agent so the timer doesn't fire after destruction.
     24
     25        (Inspector::InspectorHeapAgent::didGarbageCollect):
     26        Send the object to the task to be dispatched asynchronously.
     27
     28        * inspector/agents/InspectorHeapAgent.h:
     29
    1302016-06-24  Commit Queue  <commit-queue@webkit.org>
    231
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.cpp

    r202383 r202443  
    4040namespace Inspector {
    4141
     42class SendGarbageCollectionEventsTask {
     43public:
     44    SendGarbageCollectionEventsTask(HeapFrontendDispatcher&);
     45    void addGarbageCollection(RefPtr<Inspector::Protocol::Heap::GarbageCollection>&&);
     46    void reset();
     47private:
     48    void timerFired();
     49
     50    HeapFrontendDispatcher& m_frontendDispatcher;
     51    Vector<RefPtr<Inspector::Protocol::Heap::GarbageCollection>> m_garbageCollections;
     52    RunLoop::Timer<SendGarbageCollectionEventsTask> m_timer;
     53};
     54
     55SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask(HeapFrontendDispatcher& frontendDispatcher)
     56    : m_frontendDispatcher(frontendDispatcher)
     57    , m_timer(RunLoop::current(), this, &SendGarbageCollectionEventsTask::timerFired)
     58{
     59}
     60
     61void SendGarbageCollectionEventsTask::addGarbageCollection(RefPtr<Inspector::Protocol::Heap::GarbageCollection>&& garbageCollection)
     62{
     63    m_garbageCollections.append(WTFMove(garbageCollection));
     64
     65    if (!m_timer.isActive())
     66        m_timer.startOneShot(0);
     67}
     68
     69void SendGarbageCollectionEventsTask::reset()
     70{
     71    m_timer.stop();
     72    m_garbageCollections.clear();
     73}
     74
     75void SendGarbageCollectionEventsTask::timerFired()
     76{
     77    // The timer is stopped on agent destruction, so this method will never be called after agent has been destroyed.
     78    for (auto& event : m_garbageCollections)
     79        m_frontendDispatcher.garbageCollected(event);
     80
     81    m_garbageCollections.clear();
     82}
     83
    4284InspectorHeapAgent::InspectorHeapAgent(AgentContext& context)
    4385    : InspectorAgentBase(ASCIILiteral("Heap"))
     
    4688    , m_backendDispatcher(HeapBackendDispatcher::create(context.backendDispatcher, this))
    4789    , m_environment(context.environment)
     90    , m_sendGarbageCollectionEventsTask(std::make_unique<SendGarbageCollectionEventsTask>(*m_frontendDispatcher))
    4891{
    4992}
     
    5194InspectorHeapAgent::~InspectorHeapAgent()
    5295{
     96    m_sendGarbageCollectionEventsTask->reset();
    5397}
    5498
     
    82126
    83127    m_environment.vm().heap.removeObserver(this);
     128    m_sendGarbageCollectionEventsTask->reset();
    84129
    85130    clearHeapSnapshots();
     
    277322    // FIXME: Include number of bytes freed by collection.
    278323
    279     double startTime = m_gcStartTime;
    280     double endTime = m_environment.executionStopwatch()->elapsedTime();
    281 
    282324    // Dispatch the event asynchronously because this method may be
    283325    // called between collection and sweeping and we don't want to
     
    287329    // VM as the inspected page.
    288330
    289     RunLoop::current().dispatch([this, startTime, endTime, operation]() {
    290         auto collection = Inspector::Protocol::Heap::GarbageCollection::create()
    291             .setType(protocolTypeForHeapOperation(operation))
    292             .setStartTime(startTime)
    293             .setEndTime(endTime)
    294             .release();
    295 
    296         m_frontendDispatcher->garbageCollected(WTFMove(collection));
    297     });
     331    m_sendGarbageCollectionEventsTask->addGarbageCollection(Inspector::Protocol::Heap::GarbageCollection::create()
     332        .setType(protocolTypeForHeapOperation(operation))
     333        .setStartTime(m_gcStartTime)
     334        .setEndTime(m_environment.executionStopwatch()->elapsedTime())
     335        .release());
    298336
    299337    m_gcStartTime = NAN;
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorHeapAgent.h

    r202383 r202443  
    3838
    3939class InjectedScriptManager;
     40class SendGarbageCollectionEventsTask;
    4041typedef String ErrorString;
    4142
     
    7475    InspectorEnvironment& m_environment;
    7576
     77    std::unique_ptr<SendGarbageCollectionEventsTask> m_sendGarbageCollectionEventsTask;
     78
    7679    bool m_enabled { false };
    7780    bool m_tracking { false };
Note: See TracChangeset for help on using the changeset viewer.