OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2014 Google 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 are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 #include "sky/engine/config.h" | |
32 | |
33 #include "sky/engine/public/web/WebLeakDetector.h" | |
34 | |
35 #include "sky/engine/bindings/core/v8/V8Binding.h" | |
36 #include "sky/engine/bindings/core/v8/V8GCController.h" | |
37 #include "sky/engine/core/dom/Document.h" | |
38 #include "sky/engine/core/fetch/MemoryCache.h" | |
39 #include "sky/engine/core/fetch/ResourceFetcher.h" | |
40 #include "sky/engine/core/inspector/InspectorCounters.h" | |
41 #include "sky/engine/core/rendering/RenderObject.h" | |
42 #include "sky/engine/platform/Timer.h" | |
43 #include "sky/engine/public/web/WebDocument.h" | |
44 #include "sky/engine/public/web/WebLocalFrame.h" | |
45 #include "v8/include/v8.h" | |
46 | |
47 namespace blink { | |
48 | |
49 namespace { | |
50 | |
51 // FIXME: Oilpan: It may take multiple GC to collect on-heap objects referenced
from off-heap objects. | |
52 // Please see comment in Heap::collectAllGarbage() | |
53 static const int kNumberOfGCsToClaimChains = 5; | |
54 | |
55 class WebLeakDetectorImpl final : public WebLeakDetector { | |
56 WTF_MAKE_NONCOPYABLE(WebLeakDetectorImpl); | |
57 public: | |
58 explicit WebLeakDetectorImpl(WebLeakDetectorClient* client) | |
59 : m_client(client) | |
60 , m_delayedGCAndReportTimer(this, &WebLeakDetectorImpl::delayedGCAndRepo
rt) | |
61 , m_delayedReportTimer(this, &WebLeakDetectorImpl::delayedReport) | |
62 , m_numberOfGCNeeded(0) | |
63 { | |
64 ASSERT(m_client); | |
65 } | |
66 | |
67 virtual ~WebLeakDetectorImpl() { } | |
68 | |
69 virtual void collectGarbageAndGetDOMCounts(WebLocalFrame*) override; | |
70 | |
71 private: | |
72 void delayedGCAndReport(Timer<WebLeakDetectorImpl>*); | |
73 void delayedReport(Timer<WebLeakDetectorImpl>*); | |
74 | |
75 WebLeakDetectorClient* m_client; | |
76 Timer<WebLeakDetectorImpl> m_delayedGCAndReportTimer; | |
77 Timer<WebLeakDetectorImpl> m_delayedReportTimer; | |
78 int m_numberOfGCNeeded; | |
79 }; | |
80 | |
81 void WebLeakDetectorImpl::collectGarbageAndGetDOMCounts(WebLocalFrame* frame) | |
82 { | |
83 memoryCache()->evictResources(); | |
84 | |
85 { | |
86 RefPtr<Document> document = PassRefPtr<Document>(frame->document()); | |
87 if (ResourceFetcher* fetcher = document->fetcher()) | |
88 fetcher->garbageCollectDocumentResources(); | |
89 } | |
90 | |
91 // FIXME: HTML5 Notification should be closed because notification affects t
he result of number of DOM objects. | |
92 | |
93 for (int i = 0; i < kNumberOfGCsToClaimChains; ++i) | |
94 V8GCController::collectGarbage(v8::Isolate::GetCurrent()); | |
95 // Note: Oilpan precise GC is scheduled at the end of the event loop. | |
96 | |
97 // Task queue may contain delayed object destruction tasks. | |
98 // This method is called from navigation hook inside FrameLoader, | |
99 // so previous document is still held by the loader until the next event loo
p. | |
100 // Complete all pending tasks before proceeding to gc. | |
101 m_numberOfGCNeeded = 2; | |
102 m_delayedGCAndReportTimer.startOneShot(0, FROM_HERE); | |
103 } | |
104 | |
105 void WebLeakDetectorImpl::delayedGCAndReport(Timer<WebLeakDetectorImpl>*) | |
106 { | |
107 // We do a second and third GC here to address flakiness | |
108 // The second GC is necessary as Resource GC may have postponed clean-up tas
ks to next event loop. | |
109 // The third GC is necessary for cleaning up Document after worker object di
ed. | |
110 | |
111 for (int i = 0; i < kNumberOfGCsToClaimChains; ++i) | |
112 V8GCController::collectGarbage(V8PerIsolateData::mainThreadIsolate()); | |
113 // Note: Oilpan precise GC is scheduled at the end of the event loop. | |
114 | |
115 // Inspect counters on the next event loop. | |
116 if (--m_numberOfGCNeeded) | |
117 m_delayedGCAndReportTimer.startOneShot(0, FROM_HERE); | |
118 else | |
119 m_delayedReportTimer.startOneShot(0, FROM_HERE); | |
120 } | |
121 | |
122 void WebLeakDetectorImpl::delayedReport(Timer<WebLeakDetectorImpl>*) | |
123 { | |
124 ASSERT(m_client); | |
125 | |
126 WebLeakDetectorClient::Result result; | |
127 result.numberOfLiveDocuments = InspectorCounters::counterValue(InspectorCoun
ters::DocumentCounter); | |
128 result.numberOfLiveNodes = InspectorCounters::counterValue(InspectorCounters
::NodeCounter); | |
129 result.numberOfLiveRenderObjects = RenderObject::instanceCount(); | |
130 result.numberOfLiveResources = Resource::instanceCount(); | |
131 | |
132 m_client->onLeakDetectionComplete(result); | |
133 | |
134 #ifndef NDEBUG | |
135 showLiveDocumentInstances(); | |
136 #endif | |
137 } | |
138 | |
139 } // namespace | |
140 | |
141 WebLeakDetector* WebLeakDetector::create(WebLeakDetectorClient* client) | |
142 { | |
143 return new WebLeakDetectorImpl(client); | |
144 } | |
145 | |
146 } // namespace blink | |
OLD | NEW |