1 /* 2 * Copyright (C) 2005, 2006, 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #import "WebCoreStatistics.h" 30 31 #import "DOMElementInternal.h" 32 #import "WebCache.h" 33 #import "WebFrameInternal.h" 34 #import <JavaScriptCore/JSLock.h> 35 #import <JavaScriptCore/MemoryStatistics.h> 36 #import <WebCore/Console.h> 37 #import <WebCore/FontCache.h> 38 #import <WebCore/Frame.h> 39 #import <WebCore/GCController.h> 40 #import <WebCore/GlyphPageTreeNode.h> 41 #import <WebCore/GraphicsContext.h> 42 #import <WebCore/IconDatabase.h> 43 #import <WebCore/JSDOMWindow.h> 44 #import <WebCore/PageCache.h> 45 #import <WebCore/PrintContext.h> 46 #import <WebCore/RenderTreeAsText.h> 47 #import <WebCore/RenderView.h> 48 49 using namespace JSC; 50 using namespace WebCore; 51 52 @implementation WebCoreStatistics 53 54 + (NSArray *)statistics 55 { 56 return [WebCache statistics]; 57 } 58 59 + (size_t)javaScriptObjectsCount 60 { 61 JSLock lock(SilenceAssertionsOnly); 62 return JSDOMWindow::commonJSGlobalData()->heap.objectCount(); 63 } 64 65 + (size_t)javaScriptGlobalObjectsCount 66 { 67 JSLock lock(SilenceAssertionsOnly); 68 return JSDOMWindow::commonJSGlobalData()->heap.globalObjectCount(); 69 } 70 71 + (size_t)javaScriptProtectedObjectsCount 72 { 73 JSLock lock(SilenceAssertionsOnly); 74 return JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount(); 75 } 76 77 + (size_t)javaScriptProtectedGlobalObjectsCount 78 { 79 JSLock lock(SilenceAssertionsOnly); 80 return JSDOMWindow::commonJSGlobalData()->heap.protectedGlobalObjectCount(); 81 } 82 83 + (NSCountedSet *)javaScriptProtectedObjectTypeCounts 84 { 85 JSLock lock(SilenceAssertionsOnly); 86 87 NSCountedSet *result = [NSCountedSet set]; 88 89 OwnPtr<TypeCountSet> counts(JSDOMWindow::commonJSGlobalData()->heap.protectedObjectTypeCounts()); 90 HashCountedSet<const char*>::iterator end = counts->end(); 91 for (HashCountedSet<const char*>::iterator it = counts->begin(); it != end; ++it) 92 for (unsigned i = 0; i < it->second; ++i) 93 [result addObject:[NSString stringWithUTF8String:it->first]]; 94 95 return result; 96 } 97 98 + (NSCountedSet *)javaScriptObjectTypeCounts 99 { 100 JSLock lock(SilenceAssertionsOnly); 101 102 NSCountedSet *result = [NSCountedSet set]; 103 104 OwnPtr<TypeCountSet> counts(JSDOMWindow::commonJSGlobalData()->heap.objectTypeCounts()); 105 HashCountedSet<const char*>::iterator end = counts->end(); 106 for (HashCountedSet<const char*>::iterator it = counts->begin(); it != end; ++it) 107 for (unsigned i = 0; i < it->second; ++i) 108 [result addObject:[NSString stringWithUTF8String:it->first]]; 109 110 return result; 111 } 112 113 + (void)garbageCollectJavaScriptObjects 114 { 115 gcController().garbageCollectNow(); 116 } 117 118 + (void)garbageCollectJavaScriptObjectsOnAlternateThreadForDebugging:(BOOL)waitUntilDone 119 { 120 gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 121 } 122 123 + (size_t)iconPageURLMappingCount 124 { 125 return iconDatabase().pageURLMappingCount(); 126 } 127 128 + (size_t)iconRetainedPageURLCount 129 { 130 return iconDatabase().retainedPageURLCount(); 131 } 132 133 + (size_t)iconRecordCount 134 { 135 return iconDatabase().iconRecordCount(); 136 } 137 138 + (size_t)iconsWithDataCount 139 { 140 return iconDatabase().iconRecordCountWithData(); 141 } 142 143 + (size_t)cachedFontDataCount 144 { 145 return fontCache()->fontDataCount(); 146 } 147 148 + (size_t)cachedFontDataInactiveCount 149 { 150 return fontCache()->inactiveFontDataCount(); 151 } 152 153 + (void)purgeInactiveFontData 154 { 155 fontCache()->purgeInactiveFontData(); 156 } 157 158 + (size_t)glyphPageCount 159 { 160 return GlyphPageTreeNode::treeGlyphPageCount(); 161 } 162 163 + (BOOL)shouldPrintExceptions 164 { 165 JSLock lock(SilenceAssertionsOnly); 166 return Console::shouldPrintExceptions(); 167 } 168 169 + (void)setShouldPrintExceptions:(BOOL)print 170 { 171 JSLock lock(SilenceAssertionsOnly); 172 Console::setShouldPrintExceptions(print); 173 } 174 175 + (void)emptyCache 176 { 177 [WebCache empty]; 178 } 179 180 + (void)setCacheDisabled:(BOOL)disabled 181 { 182 [WebCache setDisabled:disabled]; 183 } 184 185 + (void)startIgnoringWebCoreNodeLeaks 186 { 187 WebCore::Node::startIgnoringLeaks(); 188 } 189 190 + (void)stopIgnoringWebCoreNodeLeaks 191 { 192 WebCore::Node::stopIgnoringLeaks(); 193 } 194 195 + (NSDictionary *)memoryStatistics 196 { 197 WTF::FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics(); 198 199 JSLock lock(SilenceAssertionsOnly); 200 size_t heapSize = JSDOMWindow::commonJSGlobalData()->heap.size(); 201 size_t heapFree = JSDOMWindow::commonJSGlobalData()->heap.capacity() - heapSize; 202 GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics(); 203 204 return [NSDictionary dictionaryWithObjectsAndKeys: 205 [NSNumber numberWithInt:fastMallocStatistics.reservedVMBytes], @"FastMallocReservedVMBytes", 206 [NSNumber numberWithInt:fastMallocStatistics.committedVMBytes], @"FastMallocCommittedVMBytes", 207 [NSNumber numberWithInt:fastMallocStatistics.freeListBytes], @"FastMallocFreeListBytes", 208 [NSNumber numberWithInt:heapSize], @"JavaScriptHeapSize", 209 [NSNumber numberWithInt:heapFree], @"JavaScriptFreeSize", 210 [NSNumber numberWithUnsignedInt:(unsigned int)globalMemoryStats.stackBytes], @"JavaScriptStackSize", 211 [NSNumber numberWithUnsignedInt:(unsigned int)globalMemoryStats.JITBytes], @"JavaScriptJITSize", 212 nil]; 213 } 214 215 + (void)returnFreeMemoryToSystem 216 { 217 WTF::releaseFastMallocFreeMemory(); 218 } 219 220 + (int)cachedPageCount 221 { 222 return pageCache()->pageCount(); 223 } 224 225 + (int)cachedFrameCount 226 { 227 return pageCache()->frameCount(); 228 } 229 230 + (int)autoreleasedPageCount 231 { 232 return pageCache()->autoreleasedPageCount(); 233 } 234 235 // Deprecated 236 + (size_t)javaScriptNoGCAllowedObjectsCount 237 { 238 return 0; 239 } 240 241 + (size_t)javaScriptReferencedObjectsCount 242 { 243 JSLock lock(SilenceAssertionsOnly); 244 return JSDOMWindow::commonJSGlobalData()->heap.protectedObjectCount(); 245 } 246 247 + (NSSet *)javaScriptRootObjectClasses 248 { 249 return [self javaScriptRootObjectTypeCounts]; 250 } 251 252 + (size_t)javaScriptInterpretersCount 253 { 254 return [self javaScriptProtectedGlobalObjectsCount]; 255 } 256 257 + (NSCountedSet *)javaScriptRootObjectTypeCounts 258 { 259 return [self javaScriptProtectedObjectTypeCounts]; 260 } 261 262 @end 263 264 @implementation WebFrame (WebKitDebug) 265 266 - (NSString *)renderTreeAsExternalRepresentationForPrinting:(BOOL)forPrinting 267 { 268 return externalRepresentation(_private->coreFrame, forPrinting ? RenderAsTextPrintingMode : RenderAsTextBehaviorNormal); 269 } 270 271 - (NSString *)counterValueForElement:(DOMElement*)element 272 { 273 return counterValueForElement(core(element)); 274 } 275 276 - (int)pageNumberForElement:(DOMElement*)element:(float)pageWidthInPixels:(float)pageHeightInPixels 277 { 278 return PrintContext::pageNumberForElement(core(element), FloatSize(pageWidthInPixels, pageHeightInPixels)); 279 } 280 281 - (int)numberOfPages:(float)pageWidthInPixels:(float)pageHeightInPixels 282 { 283 return PrintContext::numberOfPages(_private->coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels)); 284 } 285 286 - (NSString *)pageProperty:(const char *)propertyName:(int)pageNumber 287 { 288 return PrintContext::pageProperty(_private->coreFrame, propertyName, pageNumber); 289 } 290 291 - (bool)isPageBoxVisible:(int)pageNumber 292 { 293 return PrintContext::isPageBoxVisible(_private->coreFrame, pageNumber); 294 } 295 296 - (NSString *)pageSizeAndMarginsInPixels:(int)pageNumber:(int)width:(int)height:(int)marginTop:(int)marginRight:(int)marginBottom:(int)marginLeft 297 { 298 return PrintContext::pageSizeAndMarginsInPixels(_private->coreFrame, pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft); 299 } 300 301 - (void)printToCGContext:(CGContextRef)cgContext:(float)pageWidthInPixels:(float)pageHeightInPixels 302 { 303 Frame* coreFrame = _private->coreFrame; 304 if (!coreFrame) 305 return; 306 307 GraphicsContext graphicsContext(cgContext); 308 PrintContext::spoolAllPagesWithBoundaries(coreFrame, graphicsContext, FloatSize(pageWidthInPixels, pageHeightInPixels)); 309 } 310 311 @end 312