27f15acd34e0c877a1a8d2f159412a476e31309d
[WebKit-https.git] / Source / WebKit / win / WebCoreStatistics.cpp
1 /*
2  * Copyright (C) 2008, 2014-2015 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "WebKitDLL.h"
27 #include "WebCoreStatistics.h"
28
29 #include "COMPropertyBag.h"
30 #include <JavaScriptCore/JSLock.h>
31 #include <JavaScriptCore/MemoryStatistics.h>
32 #include <JavaScriptCore/Profile.h>
33 #include <WebCore/FontCache.h>
34 #include <WebCore/GCController.h>
35 #include <WebCore/GlyphPage.h>
36 #include <WebCore/IconDatabase.h>
37 #include <WebCore/JSDOMWindow.h>
38 #include <WebCore/PageCache.h>
39 #include <WebCore/PageConsoleClient.h>
40 #include <WebCore/RenderView.h>
41 #include <WebCore/SharedBuffer.h>
42
43 using namespace JSC;
44 using namespace WebCore;
45
46 // WebCoreStatistics ---------------------------------------------------------------------------
47
48 WebCoreStatistics::WebCoreStatistics()
49 {
50     gClassCount++;
51     gClassNameCount().add("WebCoreStatistics");
52 }
53
54 WebCoreStatistics::~WebCoreStatistics()
55 {
56     gClassCount--;
57     gClassNameCount().remove("WebCoreStatistics");
58 }
59
60 WebCoreStatistics* WebCoreStatistics::createInstance()
61 {
62     WebCoreStatistics* instance = new WebCoreStatistics();
63     instance->AddRef();
64     return instance;
65 }
66
67 // IUnknown -------------------------------------------------------------------
68
69 HRESULT WebCoreStatistics::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
70 {
71     if (!ppvObject)
72         return E_POINTER;
73     *ppvObject = nullptr;
74     if (IsEqualGUID(riid, IID_IUnknown))
75         *ppvObject = static_cast<WebCoreStatistics*>(this);
76     else if (IsEqualGUID(riid, IID_IWebCoreStatistics))
77         *ppvObject = static_cast<WebCoreStatistics*>(this);
78     else
79         return E_NOINTERFACE;
80
81     AddRef();
82     return S_OK;
83 }
84
85 ULONG WebCoreStatistics::AddRef()
86 {
87     return ++m_refCount;
88 }
89
90 ULONG WebCoreStatistics::Release()
91 {
92     ULONG newRef = --m_refCount;
93     if (!newRef)
94         delete(this);
95
96     return newRef;
97 }
98
99 // IWebCoreStatistics ------------------------------------------------------------------------------
100
101 HRESULT WebCoreStatistics::javaScriptObjectsCount(_Out_ UINT* count)
102 {
103     if (!count)
104         return E_POINTER;
105
106     JSLockHolder lock(JSDOMWindow::commonVM());
107     *count = (UINT)JSDOMWindow::commonVM().heap.objectCount();
108     return S_OK;
109 }
110
111 HRESULT WebCoreStatistics::javaScriptGlobalObjectsCount(_Out_ UINT* count)
112 {
113     if (!count)
114         return E_POINTER;
115
116     JSLockHolder lock(JSDOMWindow::commonVM());
117     *count = (UINT)JSDOMWindow::commonVM().heap.globalObjectCount();
118     return S_OK;
119 }
120
121 HRESULT WebCoreStatistics::javaScriptProtectedObjectsCount(_Out_ UINT* count)
122 {
123     if (!count)
124         return E_POINTER;
125
126     JSLockHolder lock(JSDOMWindow::commonVM());
127     *count = (UINT)JSDOMWindow::commonVM().heap.protectedObjectCount();
128     return S_OK;
129 }
130
131 HRESULT WebCoreStatistics::javaScriptProtectedGlobalObjectsCount(_Out_ UINT* count)
132 {
133     if (!count)
134         return E_POINTER;
135
136     JSLockHolder lock(JSDOMWindow::commonVM());
137     *count = (UINT)JSDOMWindow::commonVM().heap.protectedGlobalObjectCount();
138     return S_OK;
139 }
140
141 HRESULT WebCoreStatistics::javaScriptProtectedObjectTypeCounts(_COM_Outptr_opt_ IPropertyBag2** typeNamesAndCounts)
142 {
143     if (!typeNamesAndCounts)
144         return E_POINTER;
145
146     JSLockHolder lock(JSDOMWindow::commonVM());
147     std::unique_ptr<TypeCountSet> jsObjectTypeNames(JSDOMWindow::commonVM().heap.protectedObjectTypeCounts());
148     typedef TypeCountSet::const_iterator Iterator;
149     Iterator end = jsObjectTypeNames->end();
150     HashMap<String, int> typeCountMap;
151     for (Iterator current = jsObjectTypeNames->begin(); current != end; ++current)
152         typeCountMap.set(current->key, current->value);
153
154     COMPtr<IPropertyBag2> results(AdoptCOM, COMPropertyBag<int>::createInstance(typeCountMap));
155     results.copyRefTo(typeNamesAndCounts);
156     return S_OK;
157 }
158
159 HRESULT WebCoreStatistics::javaScriptObjectTypeCounts(_COM_Outptr_opt_ IPropertyBag2** typeNamesAndCounts)
160 {
161     if (!typeNamesAndCounts)
162         return E_POINTER;
163
164     JSLockHolder lock(JSDOMWindow::commonVM());
165     std::unique_ptr<TypeCountSet> jsObjectTypeNames(JSDOMWindow::commonVM().heap.objectTypeCounts());
166     typedef TypeCountSet::const_iterator Iterator;
167     Iterator end = jsObjectTypeNames->end();
168     HashMap<String, int> typeCountMap;
169     for (Iterator current = jsObjectTypeNames->begin(); current != end; ++current)
170         typeCountMap.set(current->key, current->value);
171
172     COMPtr<IPropertyBag2> results(AdoptCOM, COMPropertyBag<int>::createInstance(typeCountMap));
173     results.copyRefTo(typeNamesAndCounts);
174     return S_OK;
175 }
176
177 HRESULT WebCoreStatistics::iconPageURLMappingCount(_Out_ UINT* count)
178 {
179     if (!count)
180         return E_POINTER;
181     *count = (UINT) iconDatabase().pageURLMappingCount();
182     return S_OK;
183 }
184
185 HRESULT WebCoreStatistics::iconRetainedPageURLCount(_Out_ UINT *count)
186 {
187     if (!count)
188         return E_POINTER;
189     *count = (UINT) iconDatabase().retainedPageURLCount();
190     return S_OK;
191 }
192
193 HRESULT WebCoreStatistics::iconRecordCount(_Out_ UINT *count)
194 {
195     if (!count)
196         return E_POINTER;
197     *count = (UINT) iconDatabase().iconRecordCount();
198     return S_OK;
199 }
200
201 HRESULT WebCoreStatistics::iconsWithDataCount(_Out_ UINT *count)
202 {
203     if (!count)
204         return E_POINTER;
205     *count = (UINT) iconDatabase().iconRecordCountWithData();
206     return S_OK;
207 }
208
209 HRESULT WebCoreStatistics::cachedFontDataCount(_Out_ UINT *count)
210 {
211     if (!count)
212         return E_POINTER;
213     *count = (UINT) FontCache::singleton().fontCount();
214     return S_OK;
215 }
216
217 HRESULT WebCoreStatistics::cachedFontDataInactiveCount(_Out_ UINT *count)
218 {
219     if (!count)
220         return E_POINTER;
221     *count = (UINT) FontCache::singleton().inactiveFontCount();
222     return S_OK;
223 }
224
225 HRESULT WebCoreStatistics::purgeInactiveFontData(void)
226 {
227     FontCache::singleton().purgeInactiveFontData();
228     return S_OK;
229 }
230
231 HRESULT WebCoreStatistics::glyphPageCount(_Out_ UINT *count)
232 {
233     if (!count)
234         return E_POINTER;
235     *count = (UINT) GlyphPage::count();
236     return S_OK;
237 }
238
239 HRESULT WebCoreStatistics::garbageCollectJavaScriptObjects()
240 {
241     GCController::singleton().garbageCollectNow();
242     return S_OK;
243 }
244
245 HRESULT WebCoreStatistics::garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging(BOOL waitUntilDone)
246 {
247     GCController::singleton().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
248     return S_OK;
249 }
250
251 HRESULT WebCoreStatistics::setJavaScriptGarbageCollectorTimerEnabled(BOOL enable)
252 {
253     GCController::singleton().setJavaScriptGarbageCollectorTimerEnabled(enable);
254     return S_OK;
255 }
256
257 HRESULT WebCoreStatistics::shouldPrintExceptions(_Out_ BOOL* shouldPrint)
258 {
259     if (!shouldPrint)
260         return E_POINTER;
261
262     JSLockHolder lock(JSDOMWindow::commonVM());
263     *shouldPrint = PageConsoleClient::shouldPrintExceptions();
264     return S_OK;
265 }
266
267 HRESULT WebCoreStatistics::setShouldPrintExceptions(BOOL print)
268 {
269     JSLockHolder lock(JSDOMWindow::commonVM());
270     PageConsoleClient::setShouldPrintExceptions(print);
271     return S_OK;
272 }
273
274 HRESULT WebCoreStatistics::startIgnoringWebCoreNodeLeaks()
275 {
276     WebCore::Node::startIgnoringLeaks();
277     return S_OK;
278 }
279
280 HRESULT WebCoreStatistics::stopIgnoringWebCoreNodeLeaks()
281 {
282     WebCore::Node::startIgnoringLeaks();
283     return S_OK;
284 }
285
286 HRESULT WebCoreStatistics::memoryStatistics(_COM_Outptr_opt_ IPropertyBag** statistics)
287 {
288     if (!statistics)
289         return E_POINTER;
290
291     WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
292
293     JSLockHolder lock(JSDOMWindow::commonVM());
294     unsigned long long heapSize = JSDOMWindow::commonVM().heap.size();
295     unsigned long long heapFree = JSDOMWindow::commonVM().heap.capacity() - heapSize;
296     GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics();
297
298     HashMap<String, unsigned long long, CaseFoldingHash> fields;
299     fields.add("FastMallocReservedVMBytes", static_cast<unsigned long long>(fastMallocStatistics.reservedVMBytes));
300     fields.add("FastMallocCommittedVMBytes", static_cast<unsigned long long>(fastMallocStatistics.committedVMBytes));
301     fields.add("FastMallocFreeListBytes", static_cast<unsigned long long>(fastMallocStatistics.freeListBytes));
302     fields.add("JavaScriptHeapSize", heapSize);
303     fields.add("JavaScriptFreeSize", heapFree);
304     fields.add("JavaScriptStackSize", static_cast<unsigned long long>(globalMemoryStats.stackBytes));
305     fields.add("JavaScriptJITSize", static_cast<unsigned long long>(globalMemoryStats.JITBytes));
306
307     *statistics = COMPropertyBag<unsigned long long, String, CaseFoldingHash>::adopt(fields);
308
309     return S_OK;
310 }
311
312 HRESULT WebCoreStatistics::returnFreeMemoryToSystem()
313 {
314     WTF::releaseFastMallocFreeMemory();
315     return S_OK;
316 }
317
318 HRESULT WebCoreStatistics::cachedPageCount(_Out_ INT* count)
319 {
320     if (!count)
321         return E_POINTER;
322
323     *count = PageCache::singleton().pageCount();
324     return S_OK;
325 }
326
327 HRESULT WebCoreStatistics::cachedFrameCount(_Out_ INT* count)
328 {
329     if (!count)
330         return E_POINTER;
331
332     *count = PageCache::singleton().frameCount();
333     return S_OK;
334 }