Home | History | Annotate | Download | only in profiler
      1 /*
      2  * Copyright (C) 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  * 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. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #import "config.h"
     27 #import "ProfilerServer.h"
     28 
     29 #import "JSProfilerPrivate.h"
     30 #import "JSRetainPtr.h"
     31 #import <Foundation/Foundation.h>
     32 
     33 #if PLATFORM(IPHONE_SIMULATOR)
     34 #import <Foundation/NSDistributedNotificationCenter.h>
     35 #endif
     36 
     37 @interface ProfilerServer : NSObject {
     38 @private
     39     NSString *_serverName;
     40     unsigned _listenerCount;
     41 }
     42 + (ProfilerServer *)sharedProfileServer;
     43 - (void)startProfiling;
     44 - (void)stopProfiling;
     45 @end
     46 
     47 @implementation ProfilerServer
     48 
     49 + (ProfilerServer *)sharedProfileServer
     50 {
     51     static ProfilerServer *sharedServer;
     52     if (!sharedServer)
     53         sharedServer = [[ProfilerServer alloc] init];
     54     return sharedServer;
     55 }
     56 
     57 - (id)init
     58 {
     59     if (!(self = [super init]))
     60         return nil;
     61 
     62     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
     63 
     64     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     65     if ([defaults boolForKey:@"EnableJSProfiling"])
     66         [self startProfiling];
     67 
     68 #if !PLATFORM(IPHONE) || PLATFORM(IPHONE_SIMULATOR)
     69     // FIXME: <rdar://problem/6546135>
     70     // The catch-all notifications
     71     [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:@"ProfilerServerStartNotification" object:nil];
     72     [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:@"ProfilerServerStopNotification" object:nil];
     73 #endif
     74 
     75     // The specific notifications
     76     NSProcessInfo *processInfo = [NSProcessInfo processInfo];
     77     _serverName = [[NSString alloc] initWithFormat:@"ProfilerServer-%d", [processInfo processIdentifier]];
     78 
     79 #if !PLATFORM(IPHONE) || PLATFORM(IPHONE_SIMULATOR)
     80     // FIXME: <rdar://problem/6546135>
     81     [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(startProfiling) name:[_serverName stringByAppendingString:@"-Start"] object:nil];
     82     [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(stopProfiling) name:[_serverName stringByAppendingString:@"-Stop"] object:nil];
     83 #endif
     84 
     85     [pool drain];
     86 
     87     return self;
     88 }
     89 
     90 - (void)startProfiling
     91 {
     92     if (++_listenerCount > 1)
     93         return;
     94     JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String]));
     95     JSStartProfiling(0, profileName.get());
     96 }
     97 
     98 - (void)stopProfiling
     99 {
    100     if (!_listenerCount || --_listenerCount > 0)
    101         return;
    102     JSRetainPtr<JSStringRef> profileName(Adopt, JSStringCreateWithUTF8CString([_serverName UTF8String]));
    103     JSEndProfiling(0, profileName.get());
    104 }
    105 
    106 @end
    107 
    108 namespace JSC {
    109 
    110 void startProfilerServerIfNeeded()
    111 {
    112     [ProfilerServer sharedProfileServer];
    113 }
    114 
    115 } // namespace JSC
    116