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 49using namespace JSC; 50using 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