From c3783b5da66e1c6f69d81e5140cdd5f994765eef Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Wed, 13 May 2020 20:24:37 -0700 Subject: [PATCH] Instrument module create Summary: `RCTModuleData instance` is the entry-point for creating and initializing NativeModules on iOS. This diff instruments module-create for the legacy NativeModule system. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D21415435 fbshipit-source-id: 8554e41cba9105ef528a9a63c49042b99ebf8751 --- React/Base/RCTModuleData.mm | 52 +++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/React/Base/RCTModuleData.mm b/React/Base/RCTModuleData.mm index b4e48ae5e1..4ac10bfa48 100644 --- a/React/Base/RCTModuleData.mm +++ b/React/Base/RCTModuleData.mm @@ -8,7 +8,10 @@ #import "RCTModuleData.h" #import -#include +#import +#import + +#import #import "RCTBridge+Private.h" #import "RCTBridge.h" @@ -17,6 +20,16 @@ #import "RCTProfile.h" #import "RCTUtils.h" +using namespace facebook::react; + +namespace { +int32_t getUniqueId() +{ + static std::atomic counter{0}; + return counter++; +} +} + @implementation RCTModuleData { NSDictionary *_constantsToExport; NSString *_queueName; @@ -110,22 +123,29 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init); #pragma mark - private setup methods -- (void)setUpInstanceAndBridge +- (void)setUpInstanceAndBridge:(int32_t)requestId { + NSString *moduleName = [self name]; + RCT_PROFILE_BEGIN_EVENT( RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge]", @{@"moduleClass" : NSStringFromClass(_moduleClass)}); { std::unique_lock lock(_instanceLock); + BOOL shouldSetup = !_setupComplete && _bridge.valid; - if (!_setupComplete && _bridge.valid) { + if (shouldSetup) { if (!_instance) { if (RCT_DEBUG && _requiresMainQueueSetup) { RCTAssertMainQueue(); } RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil); + + NativeModulePerfLogger::getInstance().moduleCreateConstructStart([moduleName UTF8String], requestId); _instance = _moduleProvider ? _moduleProvider() : nil; + NativeModulePerfLogger::getInstance().moduleCreateConstructEnd([moduleName UTF8String], requestId); + RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); if (!_instance) { // Module init returned nil, probably because automatic instantiation @@ -143,7 +163,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init); if (_instance && RCTProfileIsProfiling()) { RCTProfileHookInstance(_instance); } + } + if (_instance) { + NativeModulePerfLogger::getInstance().moduleCreateSetUpStart([moduleName UTF8String], requestId); + } + + if (shouldSetup) { // Bridge must be set before methodQueue is set up, as methodQueue // initialization requires it (View Managers get their queue by calling // self.bridge.uiManager.methodQueue) @@ -171,6 +197,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init); // thread. _requiresMainQueueSetup = NO; } + + if (_instance) { + NativeModulePerfLogger::getInstance().moduleCreateSetUpEnd([moduleName UTF8String], requestId); + } } - (void)setBridgeForInstance @@ -286,6 +316,10 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init); - (id)instance { + NSString *moduleName = [self name]; + int32_t requestId = getUniqueId(); + NativeModulePerfLogger::getInstance().moduleCreateStart([moduleName UTF8String], requestId); + if (!_setupComplete) { RCT_PROFILE_BEGIN_EVENT( RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass]), nil); @@ -301,13 +335,21 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init); } RCTUnsafeExecuteOnMainQueueSync(^{ - [self setUpInstanceAndBridge]; + [self setUpInstanceAndBridge:requestId]; }); RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); } else { - [self setUpInstanceAndBridge]; + [self setUpInstanceAndBridge:requestId]; } RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); + } else { + NativeModulePerfLogger::getInstance().moduleCreateCacheHit([moduleName UTF8String], requestId); + } + + if (_instance) { + NativeModulePerfLogger::getInstance().moduleCreateEnd([moduleName UTF8String], requestId); + } else { + NativeModulePerfLogger::getInstance().moduleCreateFail([moduleName UTF8String], requestId); } return _instance; }