/* * Copyright (C) 2008 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "config.h" #import "ProfilerServer.h" #import "JSProfilerPrivate.h" #import "JSRetainPtr.h" #import <Foundation/Foundation.h> #if PLATFORM(IPHONE_SIMULATOR) #import <Foundation/NSDistributedNotificationCenter.h> #endif @interface ProfilerServer : NSObject { @private NSString *_serverName; unsigned _listenerCount; } + (ProfilerServer *)sharedProfileServer; - (void)startProfiling; - (void)stopProfiling; @end @implementation ProfilerServer + (ProfilerServer *)sharedProfileServer { static ProfilerServer *sharedServer; if (!sharedServer) sharedServer = [[ProfilerServer alloc] init]; return sharedServer; } - (id)init { if (!(self = [super init])) return nil; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults boolForKey:@"EnableJSProfiling"]) [self startProfiling]; #if !PLATFORM(IPHONE) || PLATFORM(IPHONE_SIMULATOR) // FIXME: <rdar://problem/6546135> // The catch-all notifications [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:@"ProfilerServerStartNotification" object:nil]; [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:@"ProfilerServerStopNotification" object:nil]; #endif // The specific notifications NSProcessInfo *processInfo = [NSProcessInfo processInfo]; _serverName = [[NSString alloc] initWithFormat:@"ProfilerServer-%d", [processInfo processIdentifier]]; #if !PLATFORM(IPHONE) || PLATFORM(IPHONE_SIMULATOR) // FIXME: <rdar://problem/6546135> [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:[_serverName stringByAppendingString:@"-Start"] object:nil]; [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:[_serverName stringByAppendingString:@"-Stop"] object:nil]; #endif [pool drain]; return self; } - (void)startProfiling { if (++_listenerCount > 1) return; JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String])); JSStartProfiling(0, profileName.get()); } - (void)stopProfiling { if (!_listenerCount || --_listenerCount > 0) return; JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String])); JSEndProfiling(0, profileName.get()); } @end namespace JSC { void startProfilerServerIfNeeded() { [ProfilerServer sharedProfileServer]; } } // namespace JSC