Expose flow events to JS + add JS -> Native flows

Summary:
public

Expose JS hooks to create flow events in systrace (the nice arrows to show async work flow) +
add support to the showing all the work enqueued from the JS thread as added in D2743733

Depends on D2743733

Reviewed By: jspahrsummers

Differential Revision: D2773664

fb-gh-sync-id: 4a8854b17b4741b882f5f2cc425e4237a5e4b3eb
This commit is contained in:
Tadeu Zagallo 2016-01-04 11:05:14 -08:00 committed by facebook-github-bot-9
parent ed4478a4ff
commit 89ae0e040d
4 changed files with 44 additions and 5 deletions

View File

@ -35,7 +35,8 @@
typedef NS_ENUM(NSUInteger, RCTBridgeFields) { typedef NS_ENUM(NSUInteger, RCTBridgeFields) {
RCTBridgeFieldRequestModuleIDs = 0, RCTBridgeFieldRequestModuleIDs = 0,
RCTBridgeFieldMethodIDs, RCTBridgeFieldMethodIDs,
RCTBridgeFieldParamss, RCTBridgeFieldParams,
RCTBridgeFieldCallID,
}; };
RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void); RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
@ -65,6 +66,9 @@ RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
NSUInteger _asyncInitializedModules; NSUInteger _asyncInitializedModules;
} }
@synthesize flowID = _flowID;
@synthesize flowIDMap = _flowIDMap;
- (instancetype)initWithParentBridge:(RCTBridge *)bridge - (instancetype)initWithParentBridge:(RCTBridge *)bridge
{ {
RCTAssertMainThread(); RCTAssertMainThread();
@ -591,6 +595,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
_modulesByName_DEPRECATED = nil; _modulesByName_DEPRECATED = nil;
_frameUpdateObservers = nil; _frameUpdateObservers = nil;
if (_flowIDMap != NULL) {
CFRelease(_flowIDMap);
}
}]; }];
}); });
} }
@ -793,15 +800,22 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
- (void)handleBuffer:(NSArray *)buffer - (void)handleBuffer:(NSArray *)buffer
{ {
NSArray *requestsArray = [RCTConvert NSArray:buffer]; NSArray *requestsArray = [RCTConvert NSArray:buffer];
if (RCT_DEBUG && requestsArray.count <= RCTBridgeFieldParamss) {
if (RCT_DEBUG && requestsArray.count <= RCTBridgeFieldParams) {
RCTLogError(@"Buffer should contain at least %tu sub-arrays. Only found %tu", RCTLogError(@"Buffer should contain at least %tu sub-arrays. Only found %tu",
RCTBridgeFieldParamss + 1, requestsArray.count); RCTBridgeFieldParams + 1, requestsArray.count);
return; return;
} }
NSArray<NSNumber *> *moduleIDs = [RCTConvert NSNumberArray:requestsArray[RCTBridgeFieldRequestModuleIDs]]; NSArray<NSNumber *> *moduleIDs = [RCTConvert NSNumberArray:requestsArray[RCTBridgeFieldRequestModuleIDs]];
NSArray<NSNumber *> *methodIDs = [RCTConvert NSNumberArray:requestsArray[RCTBridgeFieldMethodIDs]]; NSArray<NSNumber *> *methodIDs = [RCTConvert NSNumberArray:requestsArray[RCTBridgeFieldMethodIDs]];
NSArray<NSArray *> *paramsArrays = [RCTConvert NSArrayArray:requestsArray[RCTBridgeFieldParamss]]; NSArray<NSArray *> *paramsArrays = [RCTConvert NSArrayArray:requestsArray[RCTBridgeFieldParams]];
int64_t callID = -1;
if (requestsArray.count > 3) {
callID = [requestsArray[RCTBridgeFieldCallID] longLongValue];
}
if (RCT_DEBUG && (moduleIDs.count != methodIDs.count || moduleIDs.count != paramsArrays.count)) { if (RCT_DEBUG && (moduleIDs.count != methodIDs.count || moduleIDs.count != paramsArrays.count)) {
RCTLogError(@"Invalid data message - all must be length: %zd", moduleIDs.count); RCTLogError(@"Invalid data message - all must be length: %zd", moduleIDs.count);
@ -835,6 +849,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
@autoreleasepool { @autoreleasepool {
for (NSNumber *indexObj in calls) { for (NSNumber *indexObj in calls) {
NSUInteger index = indexObj.unsignedIntegerValue; NSUInteger index = indexObj.unsignedIntegerValue;
if (callID != -1) {
int64_t newFlowID = (int64_t)CFDictionaryGetValue(_flowIDMap, (const void *)(_flowID + index));
_RCTProfileEndFlowEvent(@(newFlowID));
CFDictionaryRemoveValue(_flowIDMap, (const void *)(_flowID + index));
}
[self _handleRequestNumber:index [self _handleRequestNumber:index
moduleID:[moduleIDs[index] integerValue] moduleID:[moduleIDs[index] integerValue]
methodID:[methodIDs[index] integerValue] methodID:[methodIDs[index] integerValue]
@ -853,6 +872,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
dispatch_async(queue, block); dispatch_async(queue, block);
} }
} }
_flowID = callID;
} }
- (void)partialBatchDidFlush - (void)partialBatchDidFlush

View File

@ -13,6 +13,10 @@
@interface RCTBridge () @interface RCTBridge ()
// Used for the profiler flow events between JS and native
@property (nonatomic, assign) int64_t flowID;
@property (nonatomic, assign) CFMutableDictionaryRef flowIDMap;
+ (instancetype)currentBridge; + (instancetype)currentBridge;
+ (void)setCurrentBridge:(RCTBridge *)bridge; + (void)setCurrentBridge:(RCTBridge *)bridge;

View File

@ -283,6 +283,20 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context)
CFDictionaryRemoveValue(cookieMap, (const void *)cookie); CFDictionaryRemoveValue(cookieMap, (const void *)cookie);
}; };
#ifndef __clang_analyzer__
weakBridge.flowIDMap = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
#endif
context[@"nativeTraceBeginAsyncFlow"] = ^(__unused uint64_t tag, __unused NSString *name, int64_t cookie) {
int64_t newCookie = [_RCTProfileBeginFlowEvent() longLongValue];
CFDictionarySetValue(weakBridge.flowIDMap, (const void *)cookie, (const void *)newCookie);
};
context[@"nativeTraceEndAsyncFlow"] = ^(__unused uint64_t tag, __unused NSString *name, int64_t cookie) {
int64_t newCookie = (int64_t)CFDictionaryGetValue(weakBridge.flowIDMap, (const void *)cookie);
_RCTProfileEndFlowEvent(@(newCookie));
CFDictionaryRemoveValue(weakBridge.flowIDMap, (const void *)cookie);
};
context[@"nativeTraceBeginSection"] = ^(NSNumber *tag, NSString *profileName){ context[@"nativeTraceBeginSection"] = ^(NSNumber *tag, NSString *profileName){
static int profileCounter = 1; static int profileCounter = 1;
if (!profileName) { if (!profileName) {

View File

@ -190,7 +190,7 @@ RCT_EXTERN void RCTProfileRegisterCallbacks(RCTProfileCallbacks *);
#define _RCTProfileBeginFlowEvent() @0 #define _RCTProfileBeginFlowEvent() @0
#define RCTProfileEndFlowEvent() #define RCTProfileEndFlowEvent()
#define _RCTProfileEndFlowEvent() #define _RCTProfileEndFlowEvent(...)
#define RCTProfileIsProfiling(...) NO #define RCTProfileIsProfiling(...) NO
#define RCTProfileInit(...) #define RCTProfileInit(...)