diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index f8a35b7364be..74b86e799810 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<049cc0a1aa5ab53ad2ab11c359f49827>> */ /** @@ -444,6 +444,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = accessor.updateRuntimeShadowNodeReferencesOnCommit() + /** + * When enabled, runtime shadow node references will be updated during the commit only on the allowed thread. + */ + @JvmStatic + public fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean = accessor.updateRuntimeShadowNodeReferencesOnCommitThread() + /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index ba177143a0ff..765b88debb10 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9158cc3ba1ea8ea65140b582a02a5112>> + * @generated SignedSource<<6d1fc28e24576c1a63dceaa8c974cc1f>> */ /** @@ -89,6 +89,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null + private var updateRuntimeShadowNodeReferencesOnCommitThreadCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null @@ -721,6 +722,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean { + var cached = updateRuntimeShadowNodeReferencesOnCommitThreadCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.updateRuntimeShadowNodeReferencesOnCommitThread() + updateRuntimeShadowNodeReferencesOnCommitThreadCache = cached + } + return cached + } + override fun useAlwaysAvailableJSErrorHandling(): Boolean { var cached = useAlwaysAvailableJSErrorHandlingCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 845adfa884ac..f25107cc6feb 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8f93f5e6ce460e2337bbdc51bde69558>> + * @generated SignedSource<<26410c9e406969734991456f635be4af>> */ /** @@ -166,6 +166,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean + @DoNotStrip @JvmStatic public external fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean + @DoNotStrip @JvmStatic public external fun useAlwaysAvailableJSErrorHandling(): Boolean @DoNotStrip @JvmStatic public external fun useFabricInterop(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index 6ecf6f204ca5..2bb5cab976f7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -161,6 +161,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = false + override fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean = false + override fun useAlwaysAvailableJSErrorHandling(): Boolean = false override fun useFabricInterop(): Boolean = true diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index e868aeaf90b1..ffe01d0c090f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<377c50a9a022344cba12a1ad6c23b68d>> + * @generated SignedSource<> */ /** @@ -93,6 +93,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var skipActivityIdentityAssertionOnHostPauseCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null + private var updateRuntimeShadowNodeReferencesOnCommitThreadCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null @@ -794,6 +795,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean { + var cached = updateRuntimeShadowNodeReferencesOnCommitThreadCache + if (cached == null) { + cached = currentProvider.updateRuntimeShadowNodeReferencesOnCommitThread() + accessedFeatureFlags.add("updateRuntimeShadowNodeReferencesOnCommitThread") + updateRuntimeShadowNodeReferencesOnCommitThreadCache = cached + } + return cached + } + override fun useAlwaysAvailableJSErrorHandling(): Boolean { var cached = useAlwaysAvailableJSErrorHandlingCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index dc52f2bc89cc..cb9050023baa 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -161,6 +161,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean + @DoNotStrip public fun updateRuntimeShadowNodeReferencesOnCommitThread(): Boolean + @DoNotStrip public fun useAlwaysAvailableJSErrorHandling(): Boolean @DoNotStrip public fun useFabricInterop(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index cd76ee7a11f3..a861c047e82b 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3c268f88d2df4ad8500e29b91f1fecc0>> + * @generated SignedSource<<698b775afb6ad9295c181ea3d12118d3>> */ /** @@ -453,6 +453,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool updateRuntimeShadowNodeReferencesOnCommitThread() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("updateRuntimeShadowNodeReferencesOnCommitThread"); + return method(javaProvider_); + } + bool useAlwaysAvailableJSErrorHandling() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useAlwaysAvailableJSErrorHandling"); @@ -862,6 +868,11 @@ bool JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnComm return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit(); } +bool JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnCommitThread( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommitThread(); +} + bool JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling(); @@ -1150,6 +1161,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "updateRuntimeShadowNodeReferencesOnCommit", JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnCommit), + makeNativeMethod( + "updateRuntimeShadowNodeReferencesOnCommitThread", + JReactNativeFeatureFlagsCxxInterop::updateRuntimeShadowNodeReferencesOnCommitThread), makeNativeMethod( "useAlwaysAvailableJSErrorHandling", JReactNativeFeatureFlagsCxxInterop::useAlwaysAvailableJSErrorHandling), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index e8c1425a8375..260c4f4ea049 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<7be3a44c6ffc2c9d390f66902ef80d30>> */ /** @@ -237,6 +237,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool updateRuntimeShadowNodeReferencesOnCommit( facebook::jni::alias_ref); + static bool updateRuntimeShadowNodeReferencesOnCommitThread( + facebook::jni::alias_ref); + static bool useAlwaysAvailableJSErrorHandling( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 7142531ea712..8c2a06e0224d 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<88b22330e8486a820eb42b59fb7279e4>> */ /** @@ -302,6 +302,10 @@ bool ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit() { return getAccessor().updateRuntimeShadowNodeReferencesOnCommit(); } +bool ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommitThread() { + return getAccessor().updateRuntimeShadowNodeReferencesOnCommitThread(); +} + bool ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling() { return getAccessor().useAlwaysAvailableJSErrorHandling(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index da397f200696..902ac9787e74 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -384,6 +384,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool updateRuntimeShadowNodeReferencesOnCommit(); + /** + * When enabled, runtime shadow node references will be updated during the commit only on the allowed thread. + */ + RN_EXPORT static bool updateRuntimeShadowNodeReferencesOnCommitThread(); + /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index f34c02b3bc0e..5b23711102e9 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7abeb70e59a3c4953c501011bd858479>> + * @generated SignedSource<<65ca2267e4bd81dcc21f35bbfc880ba8>> */ /** @@ -1271,6 +1271,24 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitThread() { + auto flagValue = updateRuntimeShadowNodeReferencesOnCommitThread_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(69, "updateRuntimeShadowNodeReferencesOnCommitThread"); + + flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); + updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { auto flagValue = useAlwaysAvailableJSErrorHandling_.load(); @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(70, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "useFabricInterop"); + markFlagAsAccessed(71, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(72, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "useNestedScrollViewAndroid"); + markFlagAsAccessed(73, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "useSharedAnimatedBackend"); + markFlagAsAccessed(74, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(75, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "useTurboModuleInterop"); + markFlagAsAccessed(76, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "useTurboModules"); + markFlagAsAccessed(77, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1424,7 +1442,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "viewCullingOutsetRatio"); + markFlagAsAccessed(78, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1442,7 +1460,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "virtualViewPrerenderRatio"); + markFlagAsAccessed(79, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index d20f0b9f024c..1c89cab6d623 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<366f2d2074e2af1d9dd4244ac1454ac0>> + * @generated SignedSource<<1aed21628664154ea7f66f15b1f760c2>> */ /** @@ -101,6 +101,7 @@ class ReactNativeFeatureFlagsAccessor { bool skipActivityIdentityAssertionOnHostPause(); bool traceTurboModulePromiseRejectionsOnAndroid(); bool updateRuntimeShadowNodeReferencesOnCommit(); + bool updateRuntimeShadowNodeReferencesOnCommitThread(); bool useAlwaysAvailableJSErrorHandling(); bool useFabricInterop(); bool useNativeViewConfigsInBridgelessMode(); @@ -122,7 +123,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 79> accessedFeatureFlags_; + std::array, 80> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -193,6 +194,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> skipActivityIdentityAssertionOnHostPause_; std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; std::atomic> updateRuntimeShadowNodeReferencesOnCommit_; + std::atomic> updateRuntimeShadowNodeReferencesOnCommitThread_; std::atomic> useAlwaysAvailableJSErrorHandling_; std::atomic> useFabricInterop_; std::atomic> useNativeViewConfigsInBridgelessMode_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 346ad8fe1228..43e9c6556b1c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1c98cfbb8e70c8685faafd078002f866>> + * @generated SignedSource<> */ /** @@ -303,6 +303,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool updateRuntimeShadowNodeReferencesOnCommitThread() override { + return false; + } + bool useAlwaysAvailableJSErrorHandling() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 1365c1992036..293067a1e2a4 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3dfbafd135e89a02524f732bb5914696>> + * @generated SignedSource<> */ /** @@ -666,6 +666,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::updateRuntimeShadowNodeReferencesOnCommit(); } + bool updateRuntimeShadowNodeReferencesOnCommitThread() override { + auto value = values_["updateRuntimeShadowNodeReferencesOnCommitThread"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::updateRuntimeShadowNodeReferencesOnCommitThread(); + } + bool useAlwaysAvailableJSErrorHandling() override { auto value = values_["useAlwaysAvailableJSErrorHandling"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 0186d27441ed..7ec722a2d328 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<5ede2745ad5f87162c36363215bf5c4f>> + * @generated SignedSource<<0308cb63246c4576859383adc3cc9593>> */ /** @@ -94,6 +94,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool skipActivityIdentityAssertionOnHostPause() = 0; virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; virtual bool updateRuntimeShadowNodeReferencesOnCommit() = 0; + virtual bool updateRuntimeShadowNodeReferencesOnCommitThread() = 0; virtual bool useAlwaysAvailableJSErrorHandling() = 0; virtual bool useFabricInterop() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 654dc480c7a8..4a08c4efb5ef 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0301dd1333d9607a0027c0d30ff48140>> + * @generated SignedSource<> */ /** @@ -389,6 +389,11 @@ bool NativeReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit( return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit(); } +bool NativeReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommitThread( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommitThread(); +} + bool NativeReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::useAlwaysAvailableJSErrorHandling(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 85962927e711..70e9f241ad60 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7226a320306724ab7d4ee9836a5d35a2>> + * @generated SignedSource<<1fa17a0bb7f29a34541d362d1ecdc788>> */ /** @@ -174,6 +174,8 @@ class NativeReactNativeFeatureFlags bool updateRuntimeShadowNodeReferencesOnCommit(jsi::Runtime& runtime); + bool updateRuntimeShadowNodeReferencesOnCommitThread(jsi::Runtime& runtime); + bool useAlwaysAvailableJSErrorHandling(jsi::Runtime& runtime); bool useFabricInterop(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp index 8f0420c4d01e..1490d8746549 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp @@ -33,6 +33,10 @@ thread_local bool useRuntimeShadowNodeReferenceUpdateOnThread{false}; // NOLINT useRuntimeShadowNodeReferenceUpdateOnThread = isEnabled; } +/* static */ bool ShadowNode::getUseRuntimeShadowNodeReferenceUpdateOnThread() { + return useRuntimeShadowNodeReferenceUpdateOnThread; +} + ShadowNode::SharedListOfShared ShadowNode::emptySharedShadowNodeSharedList() { static const auto emptySharedShadowNodeSharedList = std::make_shared>>(); @@ -339,7 +343,9 @@ void ShadowNode::transferRuntimeShadowNodeReference( destinationShadowNode->runtimeShadowNodeReference_ = runtimeShadowNodeReference_; - if (!ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit()) { + if (!ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit() && + !ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommitThread()) { updateRuntimeShadowNodeReference(destinationShadowNode); } } @@ -348,6 +354,8 @@ void ShadowNode::transferRuntimeShadowNodeReference( const std::shared_ptr& destinationShadowNode, const ShadowNodeFragment& fragment) const { if ((ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit() || + ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommitThread() || useRuntimeShadowNodeReferenceUpdateOnThread) && fragment.runtimeShadowNodeReference) { transferRuntimeShadowNodeReference(destinationShadowNode); diff --git a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h index 44303d534d92..ca0c1be6762e 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h +++ b/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h @@ -68,6 +68,8 @@ class ShadowNode : public Sealable, public DebugStringConvertible, public jsi::N static void setUseRuntimeShadowNodeReferenceUpdateOnThread(bool isEnabled); + static bool getUseRuntimeShadowNodeReferenceUpdateOnThread(); + #pragma mark - Constructors /* diff --git a/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp b/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp index 48da4ff0c2de..55ab4b7c4cd0 100644 --- a/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp +++ b/packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.cpp @@ -50,8 +50,12 @@ void updateMountedFlag( newChild->setMounted(true); oldChild->setMounted(false); - if (commitSource == ShadowTreeCommitSource::React && - ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit()) { + if ((commitSource == ShadowTreeCommitSource::React && + ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommit()) || + (ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommitThread() && + ShadowNode::getUseRuntimeShadowNodeReferenceUpdateOnThread())) { newChild->updateRuntimeShadowNodeReference(newChild); } @@ -66,8 +70,12 @@ void updateMountedFlag( const auto& newChild = newChildren[index]; newChild->setMounted(true); - if (commitSource == ShadowTreeCommitSource::React && - ReactNativeFeatureFlags::updateRuntimeShadowNodeReferencesOnCommit()) { + if ((commitSource == ShadowTreeCommitSource::React && + ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommit()) || + (ReactNativeFeatureFlags:: + updateRuntimeShadowNodeReferencesOnCommitThread() && + ShadowNode::getUseRuntimeShadowNodeReferenceUpdateOnThread())) { newChild->updateRuntimeShadowNodeReference(newChild); } diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index e8bf4fe37a2f..66e90ed44575 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -785,6 +785,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + updateRuntimeShadowNodeReferencesOnCommitThread: { + defaultValue: false, + metadata: { + dateAdded: '2026-02-11', + description: + 'When enabled, runtime shadow node references will be updated during the commit only on the allowed thread.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, useAlwaysAvailableJSErrorHandling: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 7a461bdf9a9a..222e08e78284 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4680a90fe6a071f6352de95fc1ca01ba>> + * @generated SignedSource<<80f3fba939ccfd246ed809592ac30fad>> * @flow strict * @noformat */ @@ -115,6 +115,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ skipActivityIdentityAssertionOnHostPause: Getter, traceTurboModulePromiseRejectionsOnAndroid: Getter, updateRuntimeShadowNodeReferencesOnCommit: Getter, + updateRuntimeShadowNodeReferencesOnCommitThread: Getter, useAlwaysAvailableJSErrorHandling: Getter, useFabricInterop: Getter, useNativeViewConfigsInBridgelessMode: Getter, @@ -462,6 +463,10 @@ export const traceTurboModulePromiseRejectionsOnAndroid: Getter = creat * When enabled, runtime shadow node references will be updated during the commit. This allows running RSNRU from any thread without corrupting the renderer state. */ export const updateRuntimeShadowNodeReferencesOnCommit: Getter = createNativeFlagGetter('updateRuntimeShadowNodeReferencesOnCommit', false); +/** + * When enabled, runtime shadow node references will be updated during the commit only on the allowed thread. + */ +export const updateRuntimeShadowNodeReferencesOnCommitThread: Getter = createNativeFlagGetter('updateRuntimeShadowNodeReferencesOnCommitThread', false); /** * In Bridgeless mode, use the always available javascript error reporting pipeline. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 5cc6227520b1..01ef6a7f3a4e 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<52a7b2aed229778e887fd25d25982250>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -94,6 +94,7 @@ export interface Spec extends TurboModule { +skipActivityIdentityAssertionOnHostPause?: () => boolean; +traceTurboModulePromiseRejectionsOnAndroid?: () => boolean; +updateRuntimeShadowNodeReferencesOnCommit?: () => boolean; + +updateRuntimeShadowNodeReferencesOnCommitThread?: () => boolean; +useAlwaysAvailableJSErrorHandling?: () => boolean; +useFabricInterop?: () => boolean; +useNativeViewConfigsInBridgelessMode?: () => boolean;