mirror of
https://github.com/status-im/react-native.git
synced 2025-01-28 10:14:49 +00:00
58738483ab
Summary: We should have 0 logs at startup. In theory it could be useful to know if the profiler is enabled, but in practice 99% of the time you don't care and it ends up spamming you for no good reason. Then more people add logs and not only do the logs are not useful, they prevent people from actually using them when debugging. Closes https://github.com/facebook/react-native/pull/5766 Reviewed By: svcscm Differential Revision: D2902987 Pulled By: androidtrunkagent fb-gh-sync-id: d47f8e58edf5f2c8e2a7a4373fd7d9036d2309a0
136 lines
4.2 KiB
Objective-C
136 lines
4.2 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTJSCProfiler.h"
|
|
#import "RCTLog.h"
|
|
#import <UIKit/UIKit.h>
|
|
|
|
#ifndef RCT_JSC_PROFILER
|
|
#if RCT_DEV
|
|
#define RCT_JSC_PROFILER 1
|
|
#else
|
|
#define RCT_JSC_PROFILER 0
|
|
#endif
|
|
#endif
|
|
|
|
#if RCT_JSC_PROFILER
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#ifndef RCT_JSC_PROFILER_DYLIB
|
|
#define RCT_JSC_PROFILER_DYLIB [[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"RCTJSCProfiler.ios%zd", [[[UIDevice currentDevice] systemVersion] integerValue]] ofType:@"dylib" inDirectory:@"RCTJSCProfiler"] UTF8String]
|
|
#endif
|
|
|
|
static const char *const JSCProfileName = "profile";
|
|
|
|
typedef void (*JSCProfilerStartFunctionType)(JSContextRef, const char *);
|
|
typedef void (*JSCProfilerEndFunctionType)(JSContextRef, const char *, const char *);
|
|
typedef void (*JSCProfilerEnableFunctionType)(void);
|
|
|
|
static NSMutableDictionary<NSValue *, NSNumber *> *RCTJSCProfilerStateMap;
|
|
|
|
static JSCProfilerStartFunctionType RCTNativeProfilerStart = NULL;
|
|
static JSCProfilerEndFunctionType RCTNativeProfilerEnd = NULL;
|
|
|
|
NS_INLINE NSValue *RCTJSContextRefKey(JSContextRef ref) {
|
|
return [NSValue valueWithPointer:ref];
|
|
}
|
|
|
|
static void RCTJSCProfilerStateInit()
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
RCTJSCProfilerStateMap = [NSMutableDictionary new];
|
|
|
|
void *JSCProfiler = dlopen(RCT_JSC_PROFILER_DYLIB, RTLD_NOW);
|
|
|
|
RCTNativeProfilerStart = (JSCProfilerStartFunctionType)dlsym(JSCProfiler, "nativeProfilerStart");
|
|
RCTNativeProfilerEnd = (JSCProfilerEndFunctionType)dlsym(JSCProfiler, "nativeProfilerEnd");
|
|
JSCProfilerEnableFunctionType enableBytecode = (__typeof__(enableBytecode))dlsym(JSCProfiler, "nativeProfilerEnableBytecode");
|
|
|
|
if (RCTNativeProfilerStart && RCTNativeProfilerEnd && enableBytecode) {
|
|
enableBytecode();
|
|
} else {
|
|
RCTNativeProfilerStart = NULL;
|
|
RCTNativeProfilerEnd = NULL;
|
|
}
|
|
});
|
|
}
|
|
|
|
#endif
|
|
|
|
void RCTJSCProfilerStart(JSContextRef ctx)
|
|
{
|
|
#if RCT_JSC_PROFILER
|
|
if (ctx != NULL) {
|
|
if (RCTJSCProfilerIsSupported()) {
|
|
NSValue *key = RCTJSContextRefKey(ctx);
|
|
BOOL isProfiling = [RCTJSCProfilerStateMap[key] boolValue];
|
|
if (!isProfiling) {
|
|
RCTLogInfo(@"Starting JSC profiler for context: %p", ctx);
|
|
RCTJSCProfilerStateMap[key] = @YES;
|
|
RCTNativeProfilerStart(ctx, JSCProfileName);
|
|
} else {
|
|
RCTLogWarn(@"Trying to start JSC profiler on a context which is already profiled.");
|
|
}
|
|
} else {
|
|
RCTLogWarn(@"Cannot start JSC profiler as it's not supported.");
|
|
}
|
|
} else {
|
|
RCTLogWarn(@"Trying to start JSC profiler for NULL context.");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
NSString *RCTJSCProfilerStop(JSContextRef ctx)
|
|
{
|
|
NSString *outputFile = nil;
|
|
#if RCT_JSC_PROFILER
|
|
if (ctx != NULL) {
|
|
RCTJSCProfilerStateInit();
|
|
NSValue *key = RCTJSContextRefKey(ctx);
|
|
BOOL isProfiling = [RCTJSCProfilerStateMap[key] boolValue];
|
|
if (isProfiling) {
|
|
NSString *filename = [NSString stringWithFormat:@"cpu_profile_%ld.json", (long)CFAbsoluteTimeGetCurrent()];
|
|
outputFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
|
|
RCTNativeProfilerEnd(ctx, JSCProfileName, outputFile.UTF8String);
|
|
RCTLogInfo(@"Stopped JSC profiler for context: %p", ctx);
|
|
} else {
|
|
RCTLogWarn(@"Trying to stop JSC profiler on a context which is not being profiled.");
|
|
}
|
|
[RCTJSCProfilerStateMap removeObjectForKey:key];
|
|
} else {
|
|
RCTLogWarn(@"Trying to stop JSC profiler for NULL context.");
|
|
}
|
|
#endif
|
|
return outputFile;
|
|
}
|
|
|
|
BOOL RCTJSCProfilerIsProfiling(JSContextRef ctx)
|
|
{
|
|
BOOL isProfiling = NO;
|
|
#if RCT_JSC_PROFILER
|
|
if (ctx != NULL) {
|
|
RCTJSCProfilerStateInit();
|
|
isProfiling = [RCTJSCProfilerStateMap[RCTJSContextRefKey(ctx)] boolValue];
|
|
}
|
|
#endif
|
|
return isProfiling;
|
|
}
|
|
|
|
BOOL RCTJSCProfilerIsSupported(void)
|
|
{
|
|
BOOL isSupported = NO;
|
|
#if RCT_JSC_PROFILER
|
|
RCTJSCProfilerStateInit();
|
|
isSupported = (RCTNativeProfilerStart != NULL);
|
|
#endif
|
|
return isSupported;
|
|
}
|