From 0a98b612aa67f944b22428f7bda39121604e7e81 Mon Sep 17 00:00:00 2001 From: Adam Ernst Date: Mon, 11 Jul 2016 15:43:02 -0700 Subject: [PATCH] Change how native require hook is registered Summary: Instead of two separate dispatches to the JavaScript thread, only do one. Avoid the strongSelf dance entirely. This refactor does mean that the cost of registering the nativeRequire hook on the context is not measured by the `RCTPLRAMBundleLoad` tag. However it should be almost zero-cost to construct and set a single block, so I'm OK with that change. Reviewed By: bnham Differential Revision: D3542940 fbshipit-source-id: d6bd26e478d0d33b56f8116d7efe6aac80c91711 --- React/Executors/RCTJSCExecutor.mm | 68 ++++++++++++++----------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/React/Executors/RCTJSCExecutor.mm b/React/Executors/RCTJSCExecutor.mm index 57512557d..1e920a367 100644 --- a/React/Executors/RCTJSCExecutor.mm +++ b/React/Executors/RCTJSCExecutor.mm @@ -669,10 +669,14 @@ static void installBasicSynchronousHooksOnContext(JSContext *context) [_performanceLogger markStartForTag:RCTPLRAMBundleLoad]; NSError *error; script = loadRAMBundle(sourceURL, &error, _randomAccessBundle); - [self registerNativeRequire]; [_performanceLogger markStopForTag:RCTPLRAMBundleLoad]; [_performanceLogger setValue:script.length forTag:RCTPLRAMStartupCodeSize]; + // Reset the counters that the native require implementation uses + [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequires]; + [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequiresCount]; + [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequiresSize]; + if (error) { if (onComplete) { onComplete(error); @@ -694,6 +698,10 @@ static void installBasicSynchronousHooksOnContext(JSContext *context) if (!self.isValid) { return; } + if (isRAMBundle) { + __weak RCTJSCExecutor *weakSelf = self; + self.context.context[@"nativeRequire"] = ^(NSNumber *moduleID) { [weakSelf _nativeRequire:moduleID]; }; + } [self->_performanceLogger markStartForTag:RCTPLScriptExecution]; NSError *error = executeApplicationScript(self->_jscWrapper, script, sourceURL, self->_context.context.JSGlobalContextRef); [self->_performanceLogger markStopForTag:RCTPLScriptExecution]; @@ -809,48 +817,34 @@ static void executeRandomAccessModule(RCTJSCExecutor *executor, uint32_t moduleI } } -- (void)registerNativeRequire +- (void)_nativeRequire:(NSNumber *)moduleID { - [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequires]; - [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequiresCount]; - [_performanceLogger setValue:0 forTag:RCTPLRAMNativeRequiresSize]; + if (!moduleID) { + return; + } - [self executeBlockOnJavaScriptQueue:^{ - if (!self.valid) { + [_performanceLogger addValue:1 forTag:RCTPLRAMNativeRequiresCount]; + [_performanceLogger appendStartForTag:RCTPLRAMNativeRequires]; + RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, + [@"nativeRequire_" stringByAppendingFormat:@"%@", moduleID], nil); + + const uint32_t ID = [moduleID unsignedIntValue]; + + if (ID < _randomAccessBundle.numTableEntries) { + ModuleData *moduleData = &_randomAccessBundle.table[ID]; + const uint32_t size = NSSwapLittleIntToHost(moduleData->size); + + // sparse entry in the table -- module does not exist or is contained in the startup section + if (size == 0) { return; } - __weak RCTJSCExecutor *weakSelf = self; - self.context.context[@"nativeRequire"] = ^(NSNumber *moduleID) { - RCTJSCExecutor *strongSelf = weakSelf; - if (!strongSelf || !moduleID) { - return; - } + [_performanceLogger addValue:size forTag:RCTPLRAMNativeRequiresSize]; + executeRandomAccessModule(self, ID, NSSwapLittleIntToHost(moduleData->offset), size); + } - [strongSelf->_performanceLogger addValue:1 forTag:RCTPLRAMNativeRequiresCount]; - [strongSelf->_performanceLogger appendStartForTag:RCTPLRAMNativeRequires]; - RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, - [@"nativeRequire_" stringByAppendingFormat:@"%@", moduleID], nil); - - const uint32_t ID = [moduleID unsignedIntValue]; - - if (ID < strongSelf->_randomAccessBundle.numTableEntries) { - ModuleData *moduleData = &strongSelf->_randomAccessBundle.table[ID]; - const uint32_t size = NSSwapLittleIntToHost(moduleData->size); - - // sparse entry in the table -- module does not exist or is contained in the startup section - if (size == 0) { - return; - } - - [strongSelf->_performanceLogger addValue:size forTag:RCTPLRAMNativeRequiresSize]; - executeRandomAccessModule(strongSelf, ID, NSSwapLittleIntToHost(moduleData->offset), size); - } - - RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"js_call", nil); - [strongSelf->_performanceLogger appendStopForTag:RCTPLRAMNativeRequires]; - }; -}]; + RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"js_call", nil); + [_performanceLogger appendStopForTag:RCTPLRAMNativeRequires]; } static RandomAccessBundleStartupCode readRAMBundle(file_ptr bundle, RandomAccessBundleData &randomAccessBundle)