diff --git a/Profiler/DTXProfiler/Model/DTXInstruments.xcdatamodeld/DTXInstruments.xcdatamodel/contents b/Profiler/DTXProfiler/Model/DTXInstruments.xcdatamodeld/DTXInstruments.xcdatamodel/contents index e1393d51..061bd546 100644 --- a/Profiler/DTXProfiler/Model/DTXInstruments.xcdatamodeld/DTXInstruments.xcdatamodel/contents +++ b/Profiler/DTXProfiler/Model/DTXInstruments.xcdatamodeld/DTXInstruments.xcdatamodel/contents @@ -149,7 +149,7 @@ - + diff --git a/Profiler/DTXProfiler/ReactNativeProfiling/DTXCustomJSCSupport.m b/Profiler/DTXProfiler/ReactNativeProfiling/DTXCustomJSCSupport.m index 318048f9..d3fdc66b 100644 --- a/Profiler/DTXProfiler/ReactNativeProfiling/DTXCustomJSCSupport.m +++ b/Profiler/DTXProfiler/ReactNativeProfiling/DTXCustomJSCSupport.m @@ -25,7 +25,7 @@ static CFBundleRef __DTXGetCustomJSCBundle() dispatch_once(&onceToken, ^{ NSURL* thisFrameworkURL = [NSBundle bundleForClass:NSClassFromString(@"DTXReactNativeSampler")].bundleURL; NSURL* jscFrameworkURL = [thisFrameworkURL URLByAppendingPathComponent:@"DTX_JSC.framework"]; - bundle = CFBundleCreate(kCFAllocatorDefault, (__bridge CFURLRef)jscFrameworkURL); + bundle = CFBundleCreate(kCFAllocatorDefault, CF(jscFrameworkURL)); }); return bundle; @@ -64,7 +64,7 @@ BOOL DTXLoadJSCWrapper(DTXJSCWrapper* output) if(bundle == NULL) { //Use the system JSC bundle if no custom bundle exists. - bundle = CFBundleCreate(kCFAllocatorDefault, (__bridge CFURLRef)[NSBundle bundleForClass:[JSContext class]].bundleURL); + bundle = CFBundleCreate(kCFAllocatorDefault, CF([NSBundle bundleForClass:[JSContext class]].bundleURL)); } CFErrorRef error = NULL; diff --git a/Profiler/DTXProfiler/ReactNativeProfiling/DTXRNJSCSourceMapsSupport.m b/Profiler/DTXProfiler/ReactNativeProfiling/DTXRNJSCSourceMapsSupport.m index bf175cc7..a7a8671b 100644 --- a/Profiler/DTXProfiler/ReactNativeProfiling/DTXRNJSCSourceMapsSupport.m +++ b/Profiler/DTXProfiler/ReactNativeProfiling/DTXRNJSCSourceMapsSupport.m @@ -31,7 +31,7 @@ static JSValueRef __dtx_JSEvaluateScript(JSContextRef ctx, JSStringRef script, J if(srcSplit.count > 1) { - NSURL* rnSourceURL = (__bridge NSURL*)atomic_load(&__rnSourceURL); + NSURL* rnSourceURL = NS(atomic_load(&__rnSourceURL)); atomic_store(&__sourceMapsURL, CFBridgingRetain([NSURL URLWithString:srcString.lastPathComponent relativeToURL:rnSourceURL])); #ifdef DTX_EMBED_SOURCEMAPS @@ -39,7 +39,7 @@ static JSValueRef __dtx_JSEvaluateScript(JSContextRef ctx, JSStringRef script, J JSStringRelease(script); - script = JSStringCreateWithCFString((__bridge CFStringRef)srcString); + script = JSStringCreateWithCFString(CF(srcString)); #endif } } @@ -57,7 +57,7 @@ static id __dtx_RCTBridge_initWithDelegate_bundleURL_moduleProvider_launchOption extern void DTXRNGetCurrentWorkingSourceMapsData(void (^completion)(NSData*)) { - NSURL* sourceMapsURL = (__bridge NSURL*)atomic_load(&__sourceMapsURL); + NSURL* sourceMapsURL = NS(atomic_load(&__sourceMapsURL)); if(sourceMapsURL == nil) { completion(nil); @@ -70,10 +70,10 @@ extern void DTXRNGetCurrentWorkingSourceMapsData(void (^completion)(NSData*)) extern NSArray* DTXRNSymbolicateJSCBacktrace(NSArray* backtrace, BOOL* currentStackTraceSymbolicated) { - DTXSourceMapsParser* parser = (__bridge DTXSourceMapsParser*)atomic_load(&__rnSourceMapsParser); + DTXSourceMapsParser* parser = NS(atomic_load(&__rnSourceMapsParser)); if(parser == nil) { - NSURL* sourceMapsURL = (__bridge NSURL*)atomic_load(&__sourceMapsURL); + NSURL* sourceMapsURL = NS(atomic_load(&__sourceMapsURL)); if(sourceMapsURL != nil) { NSData* sourceMapsData = [NSData dataWithContentsOfURL:sourceMapsURL]; diff --git a/Profiler/DTXProfiler/ReactNativeProfiling/DTXReactNativeSampler.m b/Profiler/DTXProfiler/ReactNativeProfiling/DTXReactNativeSampler.m index 1be298ef..7079a300 100644 --- a/Profiler/DTXProfiler/ReactNativeProfiling/DTXReactNativeSampler.m +++ b/Profiler/DTXProfiler/ReactNativeProfiling/DTXReactNativeSampler.m @@ -76,6 +76,58 @@ static void installDTXNativeLoggingHook(JSContext* ctx) }; } +DTX_ALWAYS_INLINE +inline static void __insertEventFromJS(NSDictionary* sample, BOOL allowJSTimers, BOOL useNativeTimestamp) +{ + NSString* identifier = sample[@"identifier"]; + NSUInteger type = [sample[@"type"] unsignedIntegerValue]; + NSDate* timestamp = useNativeTimestamp ? [NSDate date] : [NSDate dateWithTimeIntervalSince1970:[sample[@"timestamp"] doubleValue] / 1000]; + NSDictionary* params = sample[@"params"]; + BOOL isFromTimer = [sample[@"isFromJSTimer"] boolValue]; + + if(isFromTimer == YES && allowJSTimers == NO) + { + return; + } + + NSDate* date = NSDate.date; + NSTimeInterval ti = CACurrentMediaTime() * 1000; + + NSLog(@"%.25f %.25f %.25f", date.timeIntervalSinceReferenceDate, date.timeIntervalSince1970, ti); + + switch (type) { + case 0: + { + id additionalInfo = params[@"2"]; + if(additionalInfo == NS(kCFNull)) + { + additionalInfo = nil; + } + __DTXProfilerMarkEventIntervalBeginIdentifier(identifier, timestamp, params[@"0"], params[@"1"], additionalInfo, [params[@"3"] boolValue], [params[@"4"] componentsSeparatedByString:@"\n"]); + } break; + case 1: + { + id additionalInfo = params[@"1"]; + if(additionalInfo == NS(kCFNull)) + { + additionalInfo = nil; + } + __DTXProfilerMarkEventIntervalEnd(timestamp, identifier, [params[@"0"] unsignedIntegerValue], additionalInfo); + } break; + case 10: + { + id additionalInfo = params[@"3"]; + if(additionalInfo == NS(kCFNull)) + { + additionalInfo = nil; + } + __DTXProfilerMarkEventIdentifier(identifier, timestamp, params[@"0"], params[@"1"], [params[@"2"] unsignedIntegerValue], additionalInfo); + } break; + default: + break; + } +} + static void installDTXSignpostHook(JSContext* ctx) { ctx[@"__dtx_getEventsSettings_v1"] = ^ NSDictionary* () { @@ -90,33 +142,20 @@ static void installDTXSignpostHook(JSContext* ctx) for(NSDictionary* sample in samples) { - NSString* identifier = sample[@"identifier"]; - NSUInteger type = [sample[@"type"] unsignedIntegerValue]; - NSDate* timestamp = [NSDate dateWithTimeIntervalSince1970:[sample[@"timestamp"] doubleValue] / 1000]; - NSDictionary* params = sample[@"params"]; - BOOL isFromTimer = [sample[@"isFromJSTimer"] boolValue]; - - if(isFromTimer == YES && allowJSTimers == NO) - { - continue; - } - - switch (type) { - case 0: - __DTXProfilerMarkEventIntervalBeginIdentifier(identifier, timestamp, params[@"0"], params[@"1"], params[@"2"], [params[@"3"] boolValue], [params[@"4"] componentsSeparatedByString:@"\n"]); - break; - case 1: - __DTXProfilerMarkEventIntervalEnd(timestamp, identifier, [params[@"0"] unsignedIntegerValue], params[@"1"]); - break; - case 10: - __DTXProfilerMarkEventIdentifier(identifier, timestamp, params[@"0"], params[@"1"], [params[@"2"] unsignedIntegerValue], params[@"3"]); - break; - default: - break; - } + __insertEventFromJS(sample, allowJSTimers, NO); } }); }; + + ctx[@"__dtx_markEvent_v2"] = ^ (NSDictionary* sample) + { + dispatch_async(__eventDispatchQueue, ^{ + DTXProfilingConfiguration* config = __DTXProfilerGetActiveConfiguration(); + BOOL allowJSTimers = config.recordReactNativeTimersAsEvents; + + __insertEventFromJS(sample, allowJSTimers, YES); + }); + }; } static void (*orig_runRunLoopThread)(id, SEL) = NULL; diff --git a/Profiler/DTXProfiler/RemoteProfiler/DTXRemoteProfiler.m b/Profiler/DTXProfiler/RemoteProfiler/DTXRemoteProfiler.m index b24ccb08..f445fae7 100644 --- a/Profiler/DTXProfiler/RemoteProfiler/DTXRemoteProfiler.m +++ b/Profiler/DTXProfiler/RemoteProfiler/DTXRemoteProfiler.m @@ -109,9 +109,10 @@ - (void)_serializeCommandWithSelector:(SEL)selector entityName:(NSString*)entity NSMutableDictionary* cmd = [@{@"cmdType": @(DTXRemoteProfilingCommandTypeProfilingStoryEvent), @"entityName": entityName, @"selector": NSStringFromSelector(selector), @"object": obj} mutableCopy]; cmd[@"additionalParams"] = additionalParams; - NSData* plistData = [NSPropertyListSerialization dataWithPropertyList:cmd format:NSPropertyListBinaryFormat_v1_0 options:0 error:NULL]; + NSError* err; + NSData* plistData = [NSPropertyListSerialization dataWithPropertyList:cmd format:NSPropertyListBinaryFormat_v1_0 options:0 error:&err]; - NSAssert(plistData != nil, @"Unable to encode data to property list."); + NSAssert(plistData != nil, @"Unable to encode data to property list: %@", err.localizedDescription); [_socketConnection writeData:plistData completionHandler:^(NSError * _Nullable error) { if(error)