Skip to content

Commit

Permalink
Add support for direct events from JS
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoNatan committed Dec 5, 2018
1 parent b981abc commit 0b8775d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
</attribute>
<attribute name="sampleIdentifier" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="sampleType" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="timestamp" optional="YES" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
<attribute name="timestamp" attributeType="Date" usesScalarValueType="NO" syncable="YES"/>
<relationship name="parentGroup" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="SampleGroup" inverseName="samples" inverseEntity="SampleGroup" syncable="YES">
<userInfo>
<entry key="includeKeyPathInDictionaryRepresentation" value="sampleIdentifier"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ 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
srcString = [srcSplit.firstObject stringByAppendingString:[NSString stringWithFormat:@"sourceMappingURL=data:application/json;base64,%@", [sourceMapsData base64EncodedStringWithOptions:0]]];

JSStringRelease(script);

script = JSStringCreateWithCFString((__bridge CFStringRef)srcString);
script = JSStringCreateWithCFString(CF(srcString));
#endif
}
}
Expand All @@ -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);
Expand All @@ -70,10 +70,10 @@ extern void DTXRNGetCurrentWorkingSourceMapsData(void (^completion)(NSData*))

extern NSArray* DTXRNSymbolicateJSCBacktrace(NSArray<NSString*>* 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];
Expand Down
87 changes: 63 additions & 24 deletions Profiler/DTXProfiler/ReactNativeProfiling/DTXReactNativeSampler.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,58 @@ static void installDTXNativeLoggingHook(JSContext* ctx)
};
}

DTX_ALWAYS_INLINE
inline static void __insertEventFromJS(NSDictionary<NSString*, id>* 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<NSString*, id>* 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* () {
Expand All @@ -90,33 +142,20 @@ static void installDTXSignpostHook(JSContext* ctx)

for(NSDictionary<NSString*, id>* sample in samples)
{
NSString* identifier = sample[@"identifier"];
NSUInteger type = [sample[@"type"] unsignedIntegerValue];
NSDate* timestamp = [NSDate dateWithTimeIntervalSince1970:[sample[@"timestamp"] doubleValue] / 1000];
NSDictionary<NSString*, id>* 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<NSString*, id>* sample)
{
dispatch_async(__eventDispatchQueue, ^{
DTXProfilingConfiguration* config = __DTXProfilerGetActiveConfiguration();
BOOL allowJSTimers = config.recordReactNativeTimersAsEvents;

__insertEventFromJS(sample, allowJSTimers, YES);
});
};
}

static void (*orig_runRunLoopThread)(id, SEL) = NULL;
Expand Down
5 changes: 3 additions & 2 deletions Profiler/DTXProfiler/RemoteProfiler/DTXRemoteProfiler.m
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 0b8775d

Please sign in to comment.