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