From 1bc9d448f57791e736a6e68089505654223639bf Mon Sep 17 00:00:00 2001 From: Alexey Lang Date: Tue, 25 Apr 2017 02:29:29 -0700 Subject: [PATCH] Port perf metrics used in RCTBatchedBridge Reviewed By: javache Differential Revision: D4938279 fbshipit-source-id: c927261ff96c2eb07b7303ae96aae7600f2947f1 --- React/CxxBridge/RCTCxxBridge.mm | 40 +++++++++++++++++++ React/CxxBridge/RCTJSCHelpers.mm | 2 +- .../src/main/jni/xreact/jni/OnLoad.cpp | 24 ++++++++++- ReactCommon/cxxreact/JSCExecutor.cpp | 16 ++++---- ReactCommon/cxxreact/Platform.h | 11 ++++- 5 files changed, 83 insertions(+), 10 deletions(-) diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index 3760fe4ba..5dd8463e9 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -74,6 +74,32 @@ static bool isRAMBundle(NSData *script) { return parseTypeFromHeader(header) == ScriptTag::RAMBundle; } +static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogger) { + __weak RCTPerformanceLogger *weakPerformanceLogger = performanceLogger; + ReactMarker::logMarker = [weakPerformanceLogger](const ReactMarker::ReactMarkerId markerId) { + switch (markerId) { + case ReactMarker::RUN_JS_BUNDLE_START: + [weakPerformanceLogger markStartForTag:RCTPLScriptExecution]; + break; + case ReactMarker::RUN_JS_BUNDLE_STOP: + [weakPerformanceLogger markStopForTag:RCTPLScriptExecution]; + break; + case ReactMarker::NATIVE_REQUIRE_START: + [weakPerformanceLogger appendStartForTag:RCTPLRAMNativeRequires]; + break; + case ReactMarker::NATIVE_REQUIRE_STOP: + [weakPerformanceLogger appendStopForTag:RCTPLRAMNativeRequires]; + [weakPerformanceLogger addValue:1 forTag:RCTPLRAMNativeRequiresCount]; + break; + case ReactMarker::CREATE_REACT_CONTEXT_STOP: + case ReactMarker::JS_BUNDLE_STRING_CONVERT_START: + case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP: + // These are not used on iOS. + break; + } + }; +} + @interface RCTCxxBridge () @property (nonatomic, weak, readonly) RCTBridge *parentBridge; @@ -157,6 +183,8 @@ struct RCTInstanceCallback : public InstanceCallback { _parentBridge = bridge; _performanceLogger = [bridge performanceLogger]; + registerPerformanceLoggerHooks(_performanceLogger); + RCTLogInfo(@"Initializing %@ (parent: %@, executor: %@)", self, bridge, [self executorClass]); /** @@ -931,6 +959,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR - (void)_flushPendingCalls { + // Log metrics about native requires during the bridge startup. + uint64_t nativeRequiresCount = [self->_performanceLogger valueForTag:RCTPLRAMNativeRequiresCount]; + [_performanceLogger setValue:nativeRequiresCount forTag:RCTPLRAMStartupNativeRequiresCount]; + uint64_t nativeRequires = [self->_performanceLogger valueForTag:RCTPLRAMNativeRequires]; + [_performanceLogger setValue:nativeRequires forTag:RCTPLRAMStartupNativeRequires]; + [_performanceLogger markStopForTag:RCTPLBridgeStartup]; RCT_PROFILE_BEGIN_EVENT(0, @"Processing pendingCalls", @{ @"count": @(_pendingCalls.count) }); @@ -1028,8 +1062,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR [self _tryAndHandleError:^{ if (isRAMBundle(script)) { + [self->_performanceLogger markStartForTag:RCTPLRAMBundleLoad]; auto ramBundle = std::make_unique(url.path.UTF8String); std::unique_ptr scriptStr = ramBundle->getStartupCode(); + [self->_performanceLogger markStopForTag:RCTPLRAMBundleLoad]; + [self->_performanceLogger setValue:scriptStr->size() forTag:RCTPLRAMStartupCodeSize]; if (self->_reactInstance) self->_reactInstance->loadUnbundle(std::move(ramBundle), std::move(scriptStr), [[url absoluteString] UTF8String]); @@ -1051,8 +1088,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR { [self _tryAndHandleError:^{ if (isRAMBundle(script)) { + [self->_performanceLogger markStartForTag:RCTPLRAMBundleLoad]; auto ramBundle = std::make_unique(url.path.UTF8String); std::unique_ptr scriptStr = ramBundle->getStartupCode(); + [self->_performanceLogger markStopForTag:RCTPLRAMBundleLoad]; + [self->_performanceLogger setValue:scriptStr->size() forTag:RCTPLRAMStartupCodeSize]; if (self->_reactInstance) { self->_reactInstance->loadUnbundleSync(std::move(ramBundle), std::move(scriptStr), [[url absoluteString] UTF8String]); diff --git a/React/CxxBridge/RCTJSCHelpers.mm b/React/CxxBridge/RCTJSCHelpers.mm index 41651c1c7..831e1534f 100644 --- a/React/CxxBridge/RCTJSCHelpers.mm +++ b/React/CxxBridge/RCTJSCHelpers.mm @@ -45,7 +45,7 @@ JSValueRef nativePerformanceNow( } void RCTPrepareJSCExecutor() { - ReactMarker::logMarker = [](const std::string&) {}; + ReactMarker::logMarker = [](const ReactMarker::ReactMarkerId) {}; PerfLogging::installNativeHooks = RCTFBQuickPerformanceLoggerConfigureHooks; JSNativeHooks::loggingHook = nativeLoggingHook; JSNativeHooks::nowHook = nativePerformanceNow; diff --git a/ReactAndroid/src/main/jni/xreact/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/xreact/jni/OnLoad.cpp index b275df571..3bdff9543 100644 --- a/ReactAndroid/src/main/jni/xreact/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/xreact/jni/OnLoad.cpp @@ -146,7 +146,29 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { return initialize(vm, [] { gloginit::initialize(); // Inject some behavior into react/ - ReactMarker::logMarker = JReactMarker::logMarker; + ReactMarker::logMarker = [](const ReactMarker::ReactMarkerId markerId) { + switch (markerId) { + case ReactMarker::RUN_JS_BUNDLE_START: + JReactMarker::logMarker("RUN_JS_BUNDLE_START"); + break; + case ReactMarker::RUN_JS_BUNDLE_STOP: + JReactMarker::logMarker("RUN_JS_BUNDLE_END"); + break; + case ReactMarker::CREATE_REACT_CONTEXT_STOP: + JReactMarker::logMarker("CREATE_REACT_CONTEXT_END"); + break; + case ReactMarker::JS_BUNDLE_STRING_CONVERT_START: + JReactMarker::logMarker("loadApplicationScript_startStringConvert"); + break; + case ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP: + JReactMarker::logMarker("loadApplicationScript_endStringConvert"); + break; + case ReactMarker::NATIVE_REQUIRE_START: + case ReactMarker::NATIVE_REQUIRE_STOP: + // These are not used on Android. + break; + } + }; WebWorkerUtil::createWebWorkerThread = WebWorkers::createWebWorkerThread; WebWorkerUtil::loadScriptFromAssets = [] (const std::string& assetName) { diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp index 810d0ecfc..f74cc9508 100644 --- a/ReactCommon/cxxreact/JSCExecutor.cpp +++ b/ReactCommon/cxxreact/JSCExecutor.cpp @@ -344,7 +344,7 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr scrip SystraceSection s("JSCExecutor::loadApplicationScript", "sourceURL", sourceURL); - ReactMarker::logMarker("RUN_JS_BUNDLE_START"); + ReactMarker::logMarker(ReactMarker::RUN_JS_BUNDLE_START); String jsSourceURL(m_context, sourceURL.c_str()); // TODO t15069155: reduce the number of overrides here @@ -363,8 +363,8 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr scrip flush(); - ReactMarker::logMarker("CREATE_REACT_CONTEXT_END"); - ReactMarker::logMarker("RUN_JS_BUNDLE_END"); + ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP); + ReactMarker::logMarker(ReactMarker::RUN_JS_BUNDLE_STOP); return; case JSLoadSourceErrorVersionMismatch: @@ -400,9 +400,9 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr scrip "JSCExecutor::loadApplicationScript-createExpectingAscii"); #endif - ReactMarker::logMarker("loadApplicationScript_startStringConvert"); + ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_START); String jsScript = jsStringFromBigString(m_context, *script); - ReactMarker::logMarker("loadApplicationScript_endStringConvert"); + ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP); #ifdef WITH_FBSYSTRACE fbsystrace_end_section(TRACE_TAG_REACT_CXX_BRIDGE); @@ -413,8 +413,8 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr scrip flush(); - ReactMarker::logMarker("CREATE_REACT_CONTEXT_END"); - ReactMarker::logMarker("RUN_JS_BUNDLE_END"); + ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP); + ReactMarker::logMarker(ReactMarker::RUN_JS_BUNDLE_STOP); } void JSCExecutor::setJSModulesUnbundle(std::unique_ptr unbundle) { @@ -784,7 +784,9 @@ JSValueRef JSCExecutor::nativeRequire( Value(m_context, arguments[0]).toString().str())); } + ReactMarker::logMarker(ReactMarker::NATIVE_REQUIRE_START); loadModule(moduleId); + ReactMarker::logMarker(ReactMarker::NATIVE_REQUIRE_STOP); return Value::makeUndefined(m_context); } diff --git a/ReactCommon/cxxreact/Platform.h b/ReactCommon/cxxreact/Platform.h index 39d26e726..dd2ad38cc 100644 --- a/ReactCommon/cxxreact/Platform.h +++ b/ReactCommon/cxxreact/Platform.h @@ -14,7 +14,16 @@ namespace facebook { namespace react { namespace ReactMarker { -using LogMarker = std::function; +enum ReactMarkerId { + NATIVE_REQUIRE_START, + NATIVE_REQUIRE_STOP, + RUN_JS_BUNDLE_START, + RUN_JS_BUNDLE_STOP, + CREATE_REACT_CONTEXT_STOP, + JS_BUNDLE_STRING_CONVERT_START, + JS_BUNDLE_STRING_CONVERT_STOP, +}; +using LogMarker = std::function; extern LogMarker logMarker; };