2 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #import "WebMemorySampler.h"
29 #if ENABLE(MEMORY_SAMPLER)
31 #import <JavaScriptCore/MemoryStatistics.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>
40 using namespace WebCore;
46 struct SystemMallocStats {
47 malloc_statistics_t defaultMallocZoneStats;
48 malloc_statistics_t dispatchContinuationMallocZoneStats;
49 malloc_statistics_t purgeableMallocZoneStats;
52 SystemMallocStats WebMemorySampler::sampleSystemMalloc() const
54 static const char* defaultMallocZoneName = "DefaultMallocZone";
55 static const char* dispatchContinuationMallocZoneName = "DispatchContinuations";
56 static const char* purgeableMallocZoneName = "DefaultPurgeableMallocZone";
57 SystemMallocStats mallocStats;
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;
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;
90 size_t WebMemorySampler::sampleProcessCommittedBytes() const
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;
98 String WebMemorySampler::processName() const
100 NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
102 appName = [[NSProcessInfo processInfo] processName];
103 return String(appName);
106 WebMemoryStatistics WebMemorySampler::sampleWebKit() const
108 size_t totalBytesInUse = 0, totalBytesCommitted = 0;
110 WebMemoryStatistics webKitMemoryStats;
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;
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;
124 GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics();
125 totalBytesInUse += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
126 totalBytesCommitted += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
128 SystemMallocStats systemStats = sampleSystemMalloc();
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;
139 size_t residentSize = sampleProcessCommittedBytes();
141 double now = currentTime();
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);
176 return webKitMemoryStats;