bf507fad59359d9004dddc513e61abf71f9da595
[WebKit-https.git] / Source / WebCore / inspector / agents / WebHeapAgent.cpp
1 /*
2  * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebHeapAgent.h"
28
29 #include <wtf/RunLoop.h>
30
31
32 namespace WebCore {
33
34 using namespace Inspector;
35
36 struct GarbageCollectionData {
37     Inspector::Protocol::Heap::GarbageCollection::Type type;
38     Seconds startTime;
39     Seconds endTime;
40 };
41
42 class SendGarbageCollectionEventsTask {
43 public:
44     SendGarbageCollectionEventsTask(WebHeapAgent&);
45     void addGarbageCollection(GarbageCollectionData&&);
46     void reset();
47 private:
48     void timerFired();
49
50     WebHeapAgent& m_agent;
51     Vector<GarbageCollectionData> m_collections;
52     RunLoop::Timer<SendGarbageCollectionEventsTask> m_timer;
53     Lock m_mutex;
54 };
55
56 SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask(WebHeapAgent& agent)
57     : m_agent(agent)
58     , m_timer(RunLoop::main(), this, &SendGarbageCollectionEventsTask::timerFired)
59 {
60 }
61
62 void SendGarbageCollectionEventsTask::addGarbageCollection(GarbageCollectionData&& collection)
63 {
64     {
65         std::lock_guard<Lock> lock(m_mutex);
66         m_collections.append(WTFMove(collection));
67     }
68
69     if (!m_timer.isActive())
70         m_timer.startOneShot(0_s);
71 }
72
73 void SendGarbageCollectionEventsTask::reset()
74 {
75     {
76         std::lock_guard<Lock> lock(m_mutex);
77         m_collections.clear();
78     }
79
80     m_timer.stop();
81 }
82
83 void SendGarbageCollectionEventsTask::timerFired()
84 {
85     Vector<GarbageCollectionData> collectionsToSend;
86
87     {
88         std::lock_guard<Lock> lock(m_mutex);
89         m_collections.swap(collectionsToSend);
90     }
91
92     m_agent.dispatchGarbageCollectionEventsAfterDelay(WTFMove(collectionsToSend));
93 }
94
95 WebHeapAgent::WebHeapAgent(Inspector::AgentContext& context)
96     : InspectorHeapAgent(context)
97     , m_sendGarbageCollectionEventsTask(std::make_unique<SendGarbageCollectionEventsTask>(*this))
98 {
99 }
100
101 WebHeapAgent::~WebHeapAgent()
102 {
103     m_sendGarbageCollectionEventsTask->reset();
104 }
105
106 void WebHeapAgent::disable(ErrorString& errorString)
107 {
108     m_sendGarbageCollectionEventsTask->reset();
109
110     InspectorHeapAgent::disable(errorString);
111 }
112
113 void WebHeapAgent::dispatchGarbageCollectedEvent(Inspector::Protocol::Heap::GarbageCollection::Type type, Seconds startTime, Seconds endTime)
114 {
115     // Dispatch the event asynchronously because this method may be
116     // called between collection and sweeping and we don't want to
117     // create unexpected JavaScript allocations that the Sweeper does
118     // not expect to encounter. JavaScript allocations could happen
119     // with WebKitLegacy's in process inspector which shares the same
120     // VM as the inspected page.
121
122     GarbageCollectionData data = {type, startTime, endTime};
123     m_sendGarbageCollectionEventsTask->addGarbageCollection(WTFMove(data));
124 }
125
126 void WebHeapAgent::dispatchGarbageCollectionEventsAfterDelay(Vector<GarbageCollectionData>&& collections)
127 {
128     for (auto& collection : collections)
129         InspectorHeapAgent::dispatchGarbageCollectedEvent(collection.type, collection.startTime, collection.endTime);
130 }
131
132 } // namespace WebCore