From 36ac040877b219b13211a8dd889c2d6f9be0ac7a Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Thu, 11 Jul 2024 02:24:35 -0700 Subject: [PATCH] Simplify Java TurboModule lookup (#45322) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/45322 Instead of using multiple weak_ptr and weak_ref, use a single weak_ref to the Java object and use that to get back to the original C++ instance, without the need for additional shared_ptr. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D59465976 --- .../ReactCommon/TurboModuleManager.cpp | 328 +++++++++--------- .../ReactCommon/TurboModuleManager.h | 39 ++- 2 files changed, 188 insertions(+), 179 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp index 3ea3f3bce2ac..0af10b74fbe6 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp @@ -5,6 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +#include "TurboModuleManager.h" + #include #include #include @@ -18,8 +20,7 @@ #include #include #include - -#include "TurboModuleManager.h" +#include namespace facebook::react { @@ -101,9 +102,7 @@ TurboModuleManager::TurboModuleManager( : runtimeExecutor_(std::move(runtimeExecutor)), jsCallInvoker_(std::move(jsCallInvoker)), nativeMethodCallInvoker_(std::move(nativeMethodCallInvoker)), - delegate_(jni::make_global(delegate)), - turboModuleCache_(std::make_shared()), - legacyModuleCache_(std::make_shared()) {} + delegate_(jni::make_global(delegate)) {} jni::local_ref TurboModuleManager::initHybrid( jni::alias_ref /* unused */, @@ -131,197 +130,198 @@ TurboModuleProviderFunctionType TurboModuleManager::createTurboModuleProvider( jni::alias_ref javaPart, jsi::Runtime* runtime, bool enableSyncVoidMethods) { - return [turboModuleCache_ = std::weak_ptr(turboModuleCache_), - runtime, - jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), - nativeMethodCallInvoker_ = - std::weak_ptr(nativeMethodCallInvoker_), - weakDelegate = jni::make_weak(delegate_), - weakJavaPart = jni::make_weak(javaPart), - enableSyncVoidMethods]( - const std::string& name) -> std::shared_ptr { - const char* moduleName = name.c_str(); - TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); - - auto turboModuleCache = turboModuleCache_.lock(); - if (!turboModuleCache) { - return nullptr; - } + return + [runtime, weakJavaPart = jni::make_weak(javaPart), enableSyncVoidMethods]( + const std::string& name) -> std::shared_ptr { + auto javaPart = weakJavaPart.lockLocal(); + if (!javaPart) { + return nullptr; + } - auto turboModuleLookup = turboModuleCache->find(moduleName); - if (turboModuleLookup != turboModuleCache->end()) { - TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); - TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); - return turboModuleLookup->second; - } + auto cxxPart = javaPart->cthis(); + if (cxxPart == nullptr) { + return nullptr; + } - auto jsCallInvoker = jsCallInvoker_.lock(); - auto nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); - auto delegate = weakDelegate.lockLocal(); - auto javaPart = weakJavaPart.lockLocal(); + return cxxPart->getTurboModule( + javaPart, name, *runtime, enableSyncVoidMethods); + }; +} - if (!jsCallInvoker || !nativeMethodCallInvoker || !delegate || !javaPart) { - return nullptr; - } +std::shared_ptr TurboModuleManager::getTurboModule( + jni::alias_ref javaPart, + const std::string& name, + jsi::Runtime& runtime, + bool enableSyncVoidMethods) { + const char* moduleName = name.c_str(); + TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); + auto turboModuleLookup = turboModuleCache_.find(name); + if (turboModuleLookup != turboModuleCache_.end()) { + TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); + return turboModuleLookup->second; + } - auto cxxModule = delegate->cthis()->getTurboModule(name, jsCallInvoker); - if (cxxModule) { - turboModuleCache->insert({name, cxxModule}); - return cxxModule; - } + TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); - auto& cxxTurboModuleMapProvider = globalExportedCxxTurboModuleMap(); - auto it = cxxTurboModuleMapProvider.find(name); - if (it != cxxTurboModuleMapProvider.end()) { - auto turboModule = it->second(jsCallInvoker); - turboModuleCache->insert({name, turboModule}); - return turboModule; - } + auto cxxDelegate = delegate_->cthis(); - static auto getTurboJavaModule = - javaPart->getClass() - ->getMethod(const std::string&)>( - "getTurboJavaModule"); - auto moduleInstance = getTurboJavaModule(javaPart.get(), name); - if (moduleInstance) { - TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); - JavaTurboModule::InitParams params = { - .moduleName = name, - .instance = moduleInstance, - .jsInvoker = jsCallInvoker, - .nativeMethodCallInvoker = nativeMethodCallInvoker, - .shouldVoidMethodsExecuteSync = enableSyncVoidMethods}; - - auto turboModule = delegate->cthis()->getTurboModule(name, params); - if (moduleInstance->isInstanceOf( - JTurboModuleWithJSIBindings::javaClassStatic())) { - static auto getBindingsInstaller = - JTurboModuleWithJSIBindings::javaClassStatic() - ->getMethod( - "getBindingsInstaller"); - auto installer = getBindingsInstaller(moduleInstance); - if (installer) { - installer->cthis()->installBindings(*runtime); - } - } + auto cxxModule = cxxDelegate->getTurboModule(name, jsCallInvoker_); + if (cxxModule) { + turboModuleCache_.insert({name, cxxModule}); + return cxxModule; + } - turboModuleCache->insert({name, turboModule}); - TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); - return turboModule; - } + auto& cxxTurboModuleMapProvider = globalExportedCxxTurboModuleMap(); + auto it = cxxTurboModuleMapProvider.find(name); + if (it != cxxTurboModuleMapProvider.end()) { + auto turboModule = it->second(jsCallInvoker_); + turboModuleCache_.insert({name, turboModule}); + return turboModule; + } - static auto getTurboLegacyCxxModule = - javaPart->getClass() - ->getMethod( - const std::string&)>("getTurboLegacyCxxModule"); - auto legacyCxxModule = getTurboLegacyCxxModule(javaPart.get(), name); - if (legacyCxxModule) { - TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); - - auto turboModule = std::make_shared( - legacyCxxModule->cthis()->getModule(), jsCallInvoker); - turboModuleCache->insert({name, turboModule}); - - TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); - return turboModule; + static auto getTurboJavaModule = + javaPart->getClass() + ->getMethod(const std::string&)>( + "getTurboJavaModule"); + auto moduleInstance = getTurboJavaModule(javaPart.get(), name); + if (moduleInstance) { + TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); + JavaTurboModule::InitParams params = { + .moduleName = name, + .instance = moduleInstance, + .jsInvoker = jsCallInvoker_, + .nativeMethodCallInvoker = nativeMethodCallInvoker_, + .shouldVoidMethodsExecuteSync = enableSyncVoidMethods}; + + auto turboModule = cxxDelegate->getTurboModule(name, params); + if (moduleInstance->isInstanceOf( + JTurboModuleWithJSIBindings::javaClassStatic())) { + static auto getBindingsInstaller = + JTurboModuleWithJSIBindings::javaClassStatic() + ->getMethod( + "getBindingsInstaller"); + auto installer = getBindingsInstaller(moduleInstance); + if (installer) { + installer->cthis()->installBindings(runtime); + } } - return nullptr; - }; + turboModuleCache_.insert({name, turboModule}); + TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); + return turboModule; + } + + static auto getTurboLegacyCxxModule = + javaPart->getClass() + ->getMethod( + const std::string&)>("getTurboLegacyCxxModule"); + auto legacyCxxModule = getTurboLegacyCxxModule(javaPart.get(), name); + if (legacyCxxModule) { + TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); + + auto turboModule = std::make_shared( + legacyCxxModule->cthis()->getModule(), jsCallInvoker_); + turboModuleCache_.insert({name, turboModule}); + + TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); + return turboModule; + } + + return nullptr; } TurboModuleProviderFunctionType TurboModuleManager::createLegacyModuleProvider( jni::alias_ref javaPart) { - return [legacyModuleCache_ = std::weak_ptr(legacyModuleCache_), - jsCallInvoker_ = std::weak_ptr(jsCallInvoker_), - nativeMethodCallInvoker_ = - std::weak_ptr(nativeMethodCallInvoker_), - weakDelegate = jni::make_weak(delegate_), - weakJavaPart = jni::make_weak(javaPart)]( + return [weakJavaPart = jni::make_weak(javaPart)]( const std::string& name) -> std::shared_ptr { - const char* moduleName = name.c_str(); - TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); - - auto legacyModuleCache = legacyModuleCache_.lock(); - auto legacyModuleLookup = legacyModuleCache->find(name); - if (legacyModuleLookup != legacyModuleCache->end()) { - TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); - TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); - return legacyModuleLookup->second; - } - - auto jsCallInvoker = jsCallInvoker_.lock(); - auto nativeMethodCallInvoker = nativeMethodCallInvoker_.lock(); - auto delegate = weakDelegate.lockLocal(); auto javaPart = weakJavaPart.lockLocal(); + if (!javaPart) { + return nullptr; + } - if (!legacyModuleCache || !jsCallInvoker || !nativeMethodCallInvoker || - !delegate || !javaPart) { + auto cxxPart = javaPart->cthis(); + if (cxxPart == nullptr) { return nullptr; } + return cxxPart->getLegacyModule(javaPart, name); + }; +} + +std::shared_ptr TurboModuleManager::getLegacyModule( + jni::alias_ref javaPart, + const std::string& name) { + const char* moduleName = name.c_str(); + TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName); + + auto legacyModuleLookup = legacyModuleCache_.find(name); + if (legacyModuleLookup != legacyModuleCache_.end()) { + TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName); TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); + return legacyModuleLookup->second; + } - static auto getLegacyCxxModule = - javaPart->getClass() - ->getMethod( - const std::string&)>("getLegacyCxxModule"); - auto legacyCxxModule = getLegacyCxxModule(javaPart.get(), name); + TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName); - if (legacyCxxModule) { - TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); + static auto getLegacyCxxModule = + javaPart->getClass() + ->getMethod( + const std::string&)>("getLegacyCxxModule"); + auto legacyCxxModule = getLegacyCxxModule(javaPart.get(), name); - auto turboModule = std::make_shared( - legacyCxxModule->cthis()->getModule(), jsCallInvoker); - legacyModuleCache->insert({name, turboModule}); + if (legacyCxxModule) { + TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); - TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); - return turboModule; - } + auto turboModule = std::make_shared( + legacyCxxModule->cthis()->getModule(), jsCallInvoker_); + legacyModuleCache_.insert({name, turboModule}); - static auto getLegacyJavaModule = + TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); + return turboModule; + } + + static auto getLegacyJavaModule = + javaPart->getClass() + ->getMethod(const std::string&)>( + "getLegacyJavaModule"); + auto moduleInstance = getLegacyJavaModule(javaPart.get(), name); + + if (moduleInstance) { + TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); + JavaTurboModule::InitParams params = { + .moduleName = name, + .instance = moduleInstance, + .jsInvoker = jsCallInvoker_, + .nativeMethodCallInvoker = nativeMethodCallInvoker_, + .shouldVoidMethodsExecuteSync = false}; + + static auto getMethodDescriptorsFromModule = javaPart->getClass() - ->getMethod(const std::string&)>( - "getLegacyJavaModule"); - auto moduleInstance = getLegacyJavaModule(javaPart.get(), name); - - if (moduleInstance) { - TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName); - JavaTurboModule::InitParams params = { - .moduleName = name, - .instance = moduleInstance, - .jsInvoker = jsCallInvoker, - .nativeMethodCallInvoker = nativeMethodCallInvoker, - .shouldVoidMethodsExecuteSync = false}; - - static auto getMethodDescriptorsFromModule = - javaPart->getClass() - ->getStaticMethod::javaobject>( - jni::alias_ref)>( - "getMethodDescriptorsFromModule"); - - auto javaMethodDescriptors = - getMethodDescriptorsFromModule(javaPart->getClass(), moduleInstance); - - std::vector methodDescriptors; - for (jni::alias_ref javaMethodDescriptor : - *javaMethodDescriptors) { - methodDescriptors.push_back(javaMethodDescriptor->toMethodDescriptor()); - } + ->getStaticMethod::javaobject>( + jni::alias_ref)>( + "getMethodDescriptorsFromModule"); + + auto javaMethodDescriptors = + getMethodDescriptorsFromModule(javaPart->getClass(), moduleInstance); + + std::vector methodDescriptors; + for (jni::alias_ref javaMethodDescriptor : + *javaMethodDescriptors) { + methodDescriptors.push_back(javaMethodDescriptor->toMethodDescriptor()); + } - auto turboModule = - std::make_shared(params, methodDescriptors); + auto turboModule = + std::make_shared(params, methodDescriptors); - legacyModuleCache->insert({name, turboModule}); - TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); - return turboModule; - } + legacyModuleCache_.insert({name, turboModule}); + TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName); + return turboModule; + } - return nullptr; - }; + return nullptr; } void TurboModuleManager::installJSIBindings( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h index 49f28dab0326..c5358cd7e35c 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h @@ -7,19 +7,18 @@ #pragma once +#include +#include +#include +#include + #include #include #include #include #include #include -#include -#include -#include -#include #include -#include -#include namespace facebook::react { @@ -44,7 +43,7 @@ class TurboModuleManager : public jni::HybridClass { jni::global_ref delegate_; using ModuleCache = - std::unordered_map>; + std::unordered_map>; /** * TODO(T48018690): @@ -52,25 +51,35 @@ class TurboModuleManager : public jni::HybridClass { * We need to come up with a mechanism to allow modules to specify whether * they want to be long-lived or short-lived. */ - std::shared_ptr turboModuleCache_; - std::shared_ptr legacyModuleCache_; + ModuleCache turboModuleCache_; + ModuleCache legacyModuleCache_; - static void installJSIBindings( - jni::alias_ref javaPart, - bool shouldCreateLegacyModules, - bool enableSyncVoidMethods); explicit TurboModuleManager( RuntimeExecutor runtimeExecutor, std::shared_ptr jsCallInvoker, std::shared_ptr nativeMethodCallInvoker, jni::alias_ref delegate); - TurboModuleProviderFunctionType createTurboModuleProvider( + static void installJSIBindings( + jni::alias_ref javaPart, + bool shouldCreateLegacyModules, + bool enableSyncVoidMethods); + + static TurboModuleProviderFunctionType createTurboModuleProvider( jni::alias_ref javaPart, jsi::Runtime* runtime, bool enableSyncVoidMethods); - TurboModuleProviderFunctionType createLegacyModuleProvider( + std::shared_ptr getTurboModule( + jni::alias_ref javaPart, + const std::string& name, + jsi::Runtime& runtime, + bool enableSyncVoidMethods); + + static TurboModuleProviderFunctionType createLegacyModuleProvider( jni::alias_ref javaPart); + std::shared_ptr getLegacyModule( + jni::alias_ref javaPart, + const std::string& name); }; } // namespace facebook::react