1/*
2 * Copyright (C) 2008 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 "config.h"
27#include "WebKitDLL.h"
28#include "WebCoreStatistics.h"
29
30#include "COMPropertyBag.h"
31#include <JavaScriptCore/JSLock.h>
32#include <WebCore/FontCache.h>
33#include <WebCore/GlyphPageTreeNode.h>
34#include <WebCore/IconDatabase.h>
35#include <WebCore/JSDOMWindow.h>
36#include <WebCore/SharedBuffer.h>
37
38using namespace JSC;
39using namespace WebCore;
40
41// WebCoreStatistics ---------------------------------------------------------------------------
42
43WebCoreStatistics::WebCoreStatistics()
44: m_refCount(0)
45{
46    gClassCount++;
47    gClassNameCount.add("WebCoreStatistics");
48}
49
50WebCoreStatistics::~WebCoreStatistics()
51{
52    gClassCount--;
53    gClassNameCount.remove("WebCoreStatistics");
54}
55
56WebCoreStatistics* WebCoreStatistics::createInstance()
57{
58    WebCoreStatistics* instance = new WebCoreStatistics();
59    instance->AddRef();
60    return instance;
61}
62
63// IUnknown -------------------------------------------------------------------
64
65HRESULT STDMETHODCALLTYPE WebCoreStatistics::QueryInterface(REFIID riid, void** ppvObject)
66{
67    *ppvObject = 0;
68    if (IsEqualGUID(riid, IID_IUnknown))
69        *ppvObject = static_cast<WebCoreStatistics*>(this);
70    else if (IsEqualGUID(riid, IID_IWebCoreStatistics))
71        *ppvObject = static_cast<WebCoreStatistics*>(this);
72    else
73        return E_NOINTERFACE;
74
75    AddRef();
76    return S_OK;
77}
78
79ULONG STDMETHODCALLTYPE WebCoreStatistics::AddRef(void)
80{
81    return ++m_refCount;
82}
83
84ULONG STDMETHODCALLTYPE WebCoreStatistics::Release(void)
85{
86    ULONG newRef = --m_refCount;
87    if (!newRef)
88        delete(this);
89
90    return newRef;
91}
92
93// IWebCoreStatistics ------------------------------------------------------------------------------
94
95HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptObjectsCount(
96    /* [retval][out] */ UINT* count)
97{
98    if (!count)
99        return E_POINTER;
100
101    JSLock lock(SilenceAssertionsOnly);
102    *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.objectCount();
103    return S_OK;
104}
105
106HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptGlobalObjectsCount(
107    /* [retval][out] */ UINT* count)
108{
109    if (!count)
110        return E_POINTER;
111
112    JSLock lock(SilenceAssertionsOnly);
113    *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount();
114    return S_OK;
115}
116
117HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedObjectsCount(
118    /* [retval][out] */ UINT* count)
119{
120    if (!count)
121        return E_POINTER;
122
123    JSLock lock(SilenceAssertionsOnly);
124    *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount();
125    return S_OK;
126}
127
128HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedGlobalObjectsCount(
129    /* [retval][out] */ UINT* count)
130{
131    if (!count)
132        return E_POINTER;
133
134    JSLock lock(SilenceAssertionsOnly);
135    *count = (UINT)JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount();
136    return S_OK;
137}
138
139HRESULT STDMETHODCALLTYPE WebCoreStatistics::javaScriptProtectedObjectTypeCounts(
140    /* [retval][out] */ IPropertyBag2** typeNamesAndCounts)
141{
142    JSLock lock(SilenceAssertionsOnly);
143    OwnPtr<TypeCountSet> jsObjectTypeNames(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts());
144    typedef TypeCountSet::const_iterator Iterator;
145    Iterator end = jsObjectTypeNames->end();
146    HashMap<String, int> typeCountMap;
147    for (Iterator current = jsObjectTypeNames->begin(); current != end; ++current)
148        typeCountMap.set(current->first, current->second);
149
150    COMPtr<IPropertyBag2> results(AdoptCOM, COMPropertyBag<int>::createInstance(typeCountMap));
151    results.copyRefTo(typeNamesAndCounts);
152    return S_OK;
153}
154
155HRESULT STDMETHODCALLTYPE WebCoreStatistics::iconPageURLMappingCount(
156    /* [retval][out] */ UINT* count)
157{
158    if (!count)
159        return E_POINTER;
160    *count = (UINT) iconDatabase().pageURLMappingCount();
161    return S_OK;
162}
163
164HRESULT STDMETHODCALLTYPE WebCoreStatistics::iconRetainedPageURLCount(
165    /* [retval][out] */ UINT *count)
166{
167    if (!count)
168        return E_POINTER;
169    *count = (UINT) iconDatabase().retainedPageURLCount();
170    return S_OK;
171}
172
173HRESULT STDMETHODCALLTYPE WebCoreStatistics::iconRecordCount(
174    /* [retval][out] */ UINT *count)
175{
176    if (!count)
177        return E_POINTER;
178    *count = (UINT) iconDatabase().iconRecordCount();
179    return S_OK;
180}
181
182HRESULT STDMETHODCALLTYPE WebCoreStatistics::iconsWithDataCount(
183    /* [retval][out] */ UINT *count)
184{
185    if (!count)
186        return E_POINTER;
187    *count = (UINT) iconDatabase().iconRecordCountWithData();
188    return S_OK;
189}
190
191HRESULT STDMETHODCALLTYPE WebCoreStatistics::cachedFontDataCount(
192    /* [retval][out] */ UINT *count)
193{
194    if (!count)
195        return E_POINTER;
196    *count = (UINT) fontCache()->fontDataCount();
197    return S_OK;
198}
199
200HRESULT STDMETHODCALLTYPE WebCoreStatistics::cachedFontDataInactiveCount(
201    /* [retval][out] */ UINT *count)
202{
203    if (!count)
204        return E_POINTER;
205    *count = (UINT) fontCache()->inactiveFontDataCount();
206    return S_OK;
207}
208
209HRESULT STDMETHODCALLTYPE WebCoreStatistics::purgeInactiveFontData(void)
210{
211    fontCache()->purgeInactiveFontData();
212    return S_OK;
213}
214
215HRESULT STDMETHODCALLTYPE WebCoreStatistics::glyphPageCount(
216    /* [retval][out] */ UINT *count)
217{
218    if (!count)
219        return E_POINTER;
220    *count = (UINT) GlyphPageTreeNode::treeGlyphPageCount();
221    return S_OK;
222}
223