• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 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'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 */
25
26#import "config.h"
27#import "WebMemorySampler.h"
28
29#if ENABLE(MEMORY_SAMPLER)
30
31#import <JavaScriptCore/MemoryStatistics.h>
32#import <mach/mach.h>
33#import <mach/task.h>
34#import <mach/mach_types.h>
35#import <malloc/malloc.h>
36#import <runtime/JSLock.h>
37#import <WebCore/JSDOMWindow.h>
38#import <wtf/CurrentTime.h>
39
40using namespace WebCore;
41using namespace JSC;
42using namespace WTF;
43
44namespace WebKit {
45
46struct SystemMallocStats {
47    malloc_statistics_t defaultMallocZoneStats;
48    malloc_statistics_t dispatchContinuationMallocZoneStats;
49    malloc_statistics_t purgeableMallocZoneStats;
50};
51
52SystemMallocStats WebMemorySampler::sampleSystemMalloc() const
53{
54    static const char* defaultMallocZoneName = "DefaultMallocZone";
55    static const char* dispatchContinuationMallocZoneName = "DispatchContinuations";
56    static const char* purgeableMallocZoneName = "DefaultPurgeableMallocZone";
57    SystemMallocStats mallocStats;
58    vm_address_t* zones;
59    unsigned count;
60
61    // Zero out the structures in case a zone is missing
62    malloc_statistics_t stats;
63    stats.blocks_in_use = 0;
64    stats.size_in_use = 0;
65    stats.max_size_in_use = 0;
66    stats.size_allocated = 0;
67    mallocStats.defaultMallocZoneStats = stats;
68    mallocStats.dispatchContinuationMallocZoneStats = stats;
69    mallocStats.purgeableMallocZoneStats = stats;
70
71    malloc_get_all_zones(mach_task_self(), 0, &zones, &count);
72    for (unsigned i = 0; i < count; i++) {
73        if (const char* name = malloc_get_zone_name(reinterpret_cast<malloc_zone_t*>(zones[i]))) {
74            stats.blocks_in_use = 0;
75            stats.size_in_use = 0;
76            stats.max_size_in_use = 0;
77            stats.size_allocated = 0;
78            malloc_zone_statistics(reinterpret_cast<malloc_zone_t*>(zones[i]), &stats);
79            if (!strcmp(name, defaultMallocZoneName))
80                mallocStats.defaultMallocZoneStats = stats;
81            else if (!strcmp(name, dispatchContinuationMallocZoneName))
82                mallocStats.dispatchContinuationMallocZoneStats = stats;
83            else if (!strcmp(name, purgeableMallocZoneName))
84                mallocStats.purgeableMallocZoneStats = stats;
85        }
86    }
87    return mallocStats;
88}
89
90size_t WebMemorySampler::sampleProcessCommittedBytes() const
91{
92    task_basic_info_64 taskInfo;
93    mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
94    task_info(mach_task_self(), TASK_BASIC_INFO_64, reinterpret_cast<task_info_t>(&taskInfo), &count);
95    return taskInfo.resident_size;
96}
97
98String WebMemorySampler::processName() const
99{
100    NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
101    if (!appName)
102        appName = [[NSProcessInfo processInfo] processName];
103    return String(appName);
104}
105
106WebMemoryStatistics WebMemorySampler::sampleWebKit() const
107{
108    size_t totalBytesInUse = 0, totalBytesCommitted = 0;
109
110    WebMemoryStatistics webKitMemoryStats;
111
112    FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
113    size_t fastMallocBytesInUse = fastMallocStatistics.committedVMBytes - fastMallocStatistics.freeListBytes;
114    size_t fastMallocBytesCommitted = fastMallocStatistics.committedVMBytes;
115    totalBytesInUse += fastMallocBytesInUse;
116    totalBytesCommitted += fastMallocBytesCommitted;
117
118    JSLock lock(SilenceAssertionsOnly);
119    size_t jscHeapBytesInUse = JSDOMWindow::commonJSGlobalData()->heap.size();
120    size_t jscHeapBytesCommitted = JSDOMWindow::commonJSGlobalData()->heap.capacity();
121    totalBytesInUse += jscHeapBytesInUse;
122    totalBytesCommitted += jscHeapBytesCommitted;
123
124    GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics();
125    totalBytesInUse += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
126    totalBytesCommitted += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
127
128    SystemMallocStats systemStats = sampleSystemMalloc();
129
130    size_t defaultMallocZoneBytesInUse = systemStats.defaultMallocZoneStats.size_in_use;
131    size_t dispatchContinuationMallocZoneBytesInUse = systemStats.dispatchContinuationMallocZoneStats.size_in_use;
132    size_t purgeableMallocZoneBytesInUse = systemStats.purgeableMallocZoneStats.size_in_use;
133    size_t defaultMallocZoneBytesCommitted = systemStats.defaultMallocZoneStats.size_allocated;
134    size_t dispatchContinuationMallocZoneBytesCommitted = systemStats.dispatchContinuationMallocZoneStats.size_allocated;
135    size_t purgeableMallocZoneBytesCommitted = systemStats.purgeableMallocZoneStats.size_allocated;
136    totalBytesInUse += defaultMallocZoneBytesInUse + dispatchContinuationMallocZoneBytesInUse + purgeableMallocZoneBytesInUse;
137    totalBytesCommitted += defaultMallocZoneBytesCommitted + dispatchContinuationMallocZoneBytesCommitted + purgeableMallocZoneBytesCommitted;
138
139    size_t residentSize = sampleProcessCommittedBytes();
140
141    double now = currentTime();
142
143    webKitMemoryStats.keys.append(String("Timestamp"));
144    webKitMemoryStats.values.append(now);
145    webKitMemoryStats.keys.append(String("Total Bytes of Memory In Use"));
146    webKitMemoryStats.values.append(totalBytesInUse);
147    webKitMemoryStats.keys.append(String("Fast Malloc Zone Bytes"));
148    webKitMemoryStats.values.append(fastMallocBytesInUse);
149    webKitMemoryStats.keys.append(String("Default Malloc Zone Bytes"));
150    webKitMemoryStats.values.append(defaultMallocZoneBytesInUse);
151    webKitMemoryStats.keys.append(String("Dispatch Continuation Malloc Zone Bytes"));
152    webKitMemoryStats.values.append(dispatchContinuationMallocZoneBytesInUse);
153    webKitMemoryStats.keys.append(String("Purgeable Malloc Zone Bytes"));
154    webKitMemoryStats.values.append(purgeableMallocZoneBytesInUse);
155    webKitMemoryStats.keys.append(String("JavaScript Heap Bytes"));
156    webKitMemoryStats.values.append(jscHeapBytesInUse);
157    webKitMemoryStats.keys.append(String("Total Bytes of Committed Memory"));
158    webKitMemoryStats.values.append(totalBytesCommitted);
159    webKitMemoryStats.keys.append(String("Fast Malloc Zone Bytes"));
160    webKitMemoryStats.values.append(fastMallocBytesCommitted);
161    webKitMemoryStats.keys.append(String("Default Malloc Zone Bytes"));
162    webKitMemoryStats.values.append(defaultMallocZoneBytesCommitted);
163    webKitMemoryStats.keys.append(String("Dispatch Continuation Malloc Zone Bytes"));
164    webKitMemoryStats.values.append(dispatchContinuationMallocZoneBytesCommitted);
165    webKitMemoryStats.keys.append(String("Purgeable Malloc Zone Bytes"));
166    webKitMemoryStats.values.append(purgeableMallocZoneBytesCommitted);
167    webKitMemoryStats.keys.append(String("JavaScript Heap Bytes"));
168    webKitMemoryStats.values.append(jscHeapBytesCommitted);
169    webKitMemoryStats.keys.append(String("JavaScript Stack Bytes"));
170    webKitMemoryStats.values.append(globalMemoryStats.stackBytes);
171    webKitMemoryStats.keys.append(String("JavaScript JIT Bytes"));
172    webKitMemoryStats.values.append(globalMemoryStats.JITBytes);
173    webKitMemoryStats.keys.append(String("Resident Size"));
174    webKitMemoryStats.values.append(residentSize);
175
176    return webKitMemoryStats;
177}
178
179}
180
181#endif
182
183