From 0839bbeb7c125194cc02a88ac51dd92c3a6f8bfa Mon Sep 17 00:00:00 2001 From: Nicola Corti Date: Mon, 28 Jul 2025 12:05:53 +0100 Subject: [PATCH] [LOCAL] Correctly sort preventShadowTreeCommitExhaustion after merge conflict --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +++- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +++++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +++++- ...agsOverrides_RNOSS_Experimental_Android.kt | 4 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++++++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 ++- .../featureflags/ReactNativeFeatureFlags.cpp | 6 ++- .../featureflags/ReactNativeFeatureFlags.h | 7 +++- .../ReactNativeFeatureFlagsAccessor.cpp | 42 +++++++++++++------ .../ReactNativeFeatureFlagsAccessor.h | 6 ++- .../ReactNativeFeatureFlagsDefaults.h | 6 ++- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 ++++- ...tiveFeatureFlagsOverridesOSSExperimental.h | 6 ++- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +++- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 22 +++++----- .../featureflags/ReactNativeFeatureFlags.js | 13 +++--- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 22 files changed, 154 insertions(+), 52 deletions(-) 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 da0fefc85cc..b2fb68f5d37 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<<3e4d74a17c15742d35db9e4247f3e1c1>> */ /** @@ -312,6 +312,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun preparedTextCacheSize(): Double = accessor.preparedTextCacheSize() + /** + * Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again. + */ + @JvmStatic + public fun preventShadowTreeCommitExhaustion(): Boolean = accessor.preventShadowTreeCommitExhaustion() + /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ 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 98b94a42ab9..9edc477ef4f 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<<9b6d83d6ea0acbc13bce19d869699079>> + * @generated SignedSource<> */ /** @@ -67,6 +67,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null private var preparedTextCacheSizeCache: Double? = null + private var preventShadowTreeCommitExhaustionCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null @@ -502,6 +503,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun preventShadowTreeCommitExhaustion(): Boolean { + var cached = preventShadowTreeCommitExhaustionCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.preventShadowTreeCommitExhaustion() + preventShadowTreeCommitExhaustionCache = cached + } + return cached + } + override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean { var cached = traceTurboModulePromiseRejectionsOnAndroidCache 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 005c34d70c1..afd221a4bf2 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<<75760457dea789ab0951d3a22be3341c>> + * @generated SignedSource<> */ /** @@ -122,6 +122,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun preparedTextCacheSize(): Double + @DoNotStrip @JvmStatic public external fun preventShadowTreeCommitExhaustion(): Boolean + @DoNotStrip @JvmStatic public external fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean @DoNotStrip @JvmStatic public external fun updateRuntimeShadowNodeReferencesOnCommit(): 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 8fb7c868f42..e59da172aba 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<<48fa8921cc2947a713974c9926e1d806>> + * @generated SignedSource<<12c2727291b635ef7c3163d153669c2c>> */ /** @@ -117,6 +117,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun preparedTextCacheSize(): Double = 200.0 + override fun preventShadowTreeCommitExhaustion(): Boolean = false + override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean = false override fun updateRuntimeShadowNodeReferencesOnCommit(): Boolean = false 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 40f18199004..baa7b54af77 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<<356261385b837def94ac5a4ca7ffd05d>> + * @generated SignedSource<<3ea9946ef21c8ac8bb9bb63712636e89>> */ /** @@ -71,6 +71,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var fuseboxNetworkInspectionEnabledCache: Boolean? = null private var hideOffscreenVirtualViewsOnIOSCache: Boolean? = null private var preparedTextCacheSizeCache: Double? = null + private var preventShadowTreeCommitExhaustionCache: Boolean? = null private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null @@ -553,6 +554,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun preventShadowTreeCommitExhaustion(): Boolean { + var cached = preventShadowTreeCommitExhaustionCache + if (cached == null) { + cached = currentProvider.preventShadowTreeCommitExhaustion() + accessedFeatureFlags.add("preventShadowTreeCommitExhaustion") + preventShadowTreeCommitExhaustionCache = cached + } + return cached + } + override fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean { var cached = traceTurboModulePromiseRejectionsOnAndroidCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt index 32dc0a1e2d0..2d32fcd900e 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.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<<58da46268043f086730132430735b720>> */ /** @@ -23,5 +23,5 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android : // We could use JNI to get the defaults from C++, // but that is more expensive than just duplicating the defaults here. - + override fun preventShadowTreeCommitExhaustion(): Boolean = true } 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 e7c491089b2..1da19692aed 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<<8abf9bfb81265ae0c840457eb6c199bd>> + * @generated SignedSource<<1e81de36735c6c9286b228c75c9a0228>> */ /** @@ -117,6 +117,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun preparedTextCacheSize(): Double + @DoNotStrip public fun preventShadowTreeCommitExhaustion(): Boolean + @DoNotStrip public fun traceTurboModulePromiseRejectionsOnAndroid(): Boolean @DoNotStrip public fun updateRuntimeShadowNodeReferencesOnCommit(): 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 ea1b239441a..0bcbbc10fc9 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<<5effd7d4ac8034424144ea68c82b61a7>> + * @generated SignedSource<> */ /** @@ -321,6 +321,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool preventShadowTreeCommitExhaustion() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("preventShadowTreeCommitExhaustion"); + return method(javaProvider_); + } + bool traceTurboModulePromiseRejectionsOnAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("traceTurboModulePromiseRejectionsOnAndroid"); @@ -626,6 +632,11 @@ double JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize( return ReactNativeFeatureFlags::preparedTextCacheSize(); } +bool JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion(); +} + bool JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); @@ -853,6 +864,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "preparedTextCacheSize", JReactNativeFeatureFlagsCxxInterop::preparedTextCacheSize), + makeNativeMethod( + "preventShadowTreeCommitExhaustion", + JReactNativeFeatureFlagsCxxInterop::preventShadowTreeCommitExhaustion), makeNativeMethod( "traceTurboModulePromiseRejectionsOnAndroid", JReactNativeFeatureFlagsCxxInterop::traceTurboModulePromiseRejectionsOnAndroid), 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 9e894e24978..42312d4bf22 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<> */ /** @@ -171,6 +171,9 @@ class JReactNativeFeatureFlagsCxxInterop static double preparedTextCacheSize( facebook::jni::alias_ref); + static bool preventShadowTreeCommitExhaustion( + facebook::jni::alias_ref); + static bool traceTurboModulePromiseRejectionsOnAndroid( 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 3d5ae99d1fb..1feef568183 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<<20c25bf5541e37cd5c918684925726df>> + * @generated SignedSource<> */ /** @@ -214,6 +214,10 @@ double ReactNativeFeatureFlags::preparedTextCacheSize() { return getAccessor().preparedTextCacheSize(); } +bool ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion() { + return getAccessor().preventShadowTreeCommitExhaustion(); +} + bool ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid() { return getAccessor().traceTurboModulePromiseRejectionsOnAndroid(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 632a9878a1b..6663518acd8 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<<20809734183aa7bfd7aad9b8d01ea080>> + * @generated SignedSource<> */ /** @@ -274,6 +274,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static double preparedTextCacheSize(); + /** + * Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again. + */ + RN_EXPORT static bool preventShadowTreeCommitExhaustion(); + /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index cc991214e13..877131981d2 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<<59ec29e038344c52eaa10845efc5240b>> + * @generated SignedSource<<681bff71eb87886a108f67b3162b030c>> */ /** @@ -875,6 +875,24 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { + auto flagValue = preventShadowTreeCommitExhaustion_.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(47, "preventShadowTreeCommitExhaustion"); + + flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); + preventShadowTreeCommitExhaustion_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid() { auto flagValue = traceTurboModulePromiseRejectionsOnAndroid_.load(); @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(48, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(49, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -920,7 +938,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(49, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(50, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -938,7 +956,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(50, "useFabricInterop"); + markFlagAsAccessed(51, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -956,7 +974,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(51, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(52, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(53, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "useRawPropsJsiValue"); + markFlagAsAccessed(54, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "useShadowNodeStateOnClone"); + markFlagAsAccessed(55, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1028,7 +1046,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(55, "useTurboModuleInterop"); + markFlagAsAccessed(56, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1046,7 +1064,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(56, "useTurboModules"); + markFlagAsAccessed(57, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1064,7 +1082,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(57, "virtualViewPrerenderRatio"); + markFlagAsAccessed(58, "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 8ee25afabd3..c71e8133664 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<<043e1a56e7a302fbca38151b5d079616>> + * @generated SignedSource<> */ /** @@ -79,6 +79,7 @@ class ReactNativeFeatureFlagsAccessor { bool fuseboxNetworkInspectionEnabled(); bool hideOffscreenVirtualViewsOnIOS(); double preparedTextCacheSize(); + bool preventShadowTreeCommitExhaustion(); bool traceTurboModulePromiseRejectionsOnAndroid(); bool updateRuntimeShadowNodeReferencesOnCommit(); bool useAlwaysAvailableJSErrorHandling(); @@ -101,7 +102,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 58> accessedFeatureFlags_; + std::array, 59> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> animatedShouldSignalBatch_; @@ -150,6 +151,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> fuseboxNetworkInspectionEnabled_; std::atomic> hideOffscreenVirtualViewsOnIOS_; std::atomic> preparedTextCacheSize_; + std::atomic> preventShadowTreeCommitExhaustion_; std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; std::atomic> updateRuntimeShadowNodeReferencesOnCommit_; std::atomic> useAlwaysAvailableJSErrorHandling_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index f80b0b99113..0dc1de80ced 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<<7b5caffd8f748384aa32ed6e153ee9c1>> + * @generated SignedSource<<9832c18e4c7ccf232b7222e2356f99d9>> */ /** @@ -215,6 +215,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return 200.0; } + bool preventShadowTreeCommitExhaustion() override { + return false; + } + bool traceTurboModulePromiseRejectionsOnAndroid() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 2ee1c5dd383..46ec128d23b 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<> + * @generated SignedSource<<19f0a48bcfa8f8ffaf634e85301adc7e>> */ /** @@ -468,6 +468,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::preparedTextCacheSize(); } + bool preventShadowTreeCommitExhaustion() override { + auto value = values_["preventShadowTreeCommitExhaustion"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::preventShadowTreeCommitExhaustion(); + } + bool traceTurboModulePromiseRejectionsOnAndroid() override { auto value = values_["traceTurboModulePromiseRejectionsOnAndroid"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h index 765468e4ee8..c45e55ce07a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsOverridesOSSExperimental.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<<1de02178e1be302bb4b19501950b260a>> + * @generated SignedSource<> */ /** @@ -27,7 +27,9 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur public: ReactNativeFeatureFlagsOverridesOSSExperimental() = default; - + bool preventShadowTreeCommitExhaustion() override { + return true; + } }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 2f0a127f62e..3df0f3be4a1 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<> + * @generated SignedSource<<815769cc8d08e19b2598dd1862ed5060>> */ /** @@ -72,6 +72,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool fuseboxNetworkInspectionEnabled() = 0; virtual bool hideOffscreenVirtualViewsOnIOS() = 0; virtual double preparedTextCacheSize() = 0; + virtual bool preventShadowTreeCommitExhaustion() = 0; virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; virtual bool updateRuntimeShadowNodeReferencesOnCommit() = 0; virtual bool useAlwaysAvailableJSErrorHandling() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 3819fbf4579..cda934866a5 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<> + * @generated SignedSource<<474a64af739969acebb4bb9bb1005168>> */ /** @@ -279,6 +279,11 @@ double NativeReactNativeFeatureFlags::preparedTextCacheSize( return ReactNativeFeatureFlags::preparedTextCacheSize(); } +bool NativeReactNativeFeatureFlags::preventShadowTreeCommitExhaustion( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::preventShadowTreeCommitExhaustion(); +} + bool NativeReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::traceTurboModulePromiseRejectionsOnAndroid(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index f34e0c27071..5696d5a7c7f 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<> + * @generated SignedSource<> */ /** @@ -130,6 +130,8 @@ class NativeReactNativeFeatureFlags double preparedTextCacheSize(jsi::Runtime& runtime); + bool preventShadowTreeCommitExhaustion(jsi::Runtime& runtime); + bool traceTurboModulePromiseRejectionsOnAndroid(jsi::Runtime& runtime); bool updateRuntimeShadowNodeReferencesOnCommit(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 253ca39522b..7bb81fa3bf0 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -543,6 +543,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + preventShadowTreeCommitExhaustion: { + defaultValue: false, + metadata: { + dateAdded: '2025-07-23', + description: + 'Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'experimental', + }, traceTurboModulePromiseRejectionsOnAndroid: { defaultValue: false, metadata: { @@ -821,17 +832,6 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, - preventShadowTreeCommitExhaustion: { - defaultValue: false, - metadata: { - dateAdded: '2025-07-23', - description: - 'Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again.', - expectedReleaseValue: true, - purpose: 'experimentation', - }, - ossReleaseStage: 'experimental', - }, }, }; diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 2859d86c466..ee5043e87bc 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<> + * @generated SignedSource<<999a8d329cdab258ac64c03b24f1a516>> * @flow strict * @noformat */ @@ -44,7 +44,6 @@ export type ReactNativeFeatureFlagsJsOnly = $ReadOnly<{ shouldUseRemoveClippedSubviewsAsDefaultOnIOS: Getter, shouldUseSetNativePropsInFabric: Getter, utilizeTokensInIntersectionObserver: Getter, - preventShadowTreeCommitExhaustion: Getter, }>; export type ReactNativeFeatureFlagsJsOnlyOverrides = OverridesFor; @@ -99,6 +98,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ fuseboxNetworkInspectionEnabled: Getter, hideOffscreenVirtualViewsOnIOS: Getter, preparedTextCacheSize: Getter, + preventShadowTreeCommitExhaustion: Getter, traceTurboModulePromiseRejectionsOnAndroid: Getter, updateRuntimeShadowNodeReferencesOnCommit: Getter, useAlwaysAvailableJSErrorHandling: Getter, @@ -192,11 +192,6 @@ export const shouldUseSetNativePropsInFabric: Getter = createJavaScript */ export const utilizeTokensInIntersectionObserver: Getter = createJavaScriptFlagGetter('utilizeTokensInIntersectionObserver', true); -/** - * Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again. - */ -export const preventShadowTreeCommitExhaustion: Getter = createJavaScriptFlagGetter('preventShadowTreeCommitExhaustion', false); - /** * Common flag for testing. Do NOT modify. */ @@ -389,6 +384,10 @@ export const hideOffscreenVirtualViewsOnIOS: Getter = createNativeFlagG * Number cached PreparedLayouts in TextLayoutManager cache */ export const preparedTextCacheSize: Getter = createNativeFlagGetter('preparedTextCacheSize', 200); +/** + * Enables a new mechanism in ShadowTree to prevent problems caused by multiple threads trying to commit concurrently. If a thread tries to commit a few times unsuccessfully, it will acquire a lock and try again. + */ +export const preventShadowTreeCommitExhaustion: Getter = createNativeFlagGetter('preventShadowTreeCommitExhaustion', false); /** * Enables storing js caller stack when creating promise in native module. This is useful in case of Promise rejection and tracing the cause. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index d91d5dbad0c..e64f0920b3e 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<<55c1f0223345b5680bbdd888a358f210>> + * @generated SignedSource<<1b84b6e04c214f6c2798010372937990>> * @flow strict * @noformat */ @@ -72,6 +72,7 @@ export interface Spec extends TurboModule { +fuseboxNetworkInspectionEnabled?: () => boolean; +hideOffscreenVirtualViewsOnIOS?: () => boolean; +preparedTextCacheSize?: () => number; + +preventShadowTreeCommitExhaustion?: () => boolean; +traceTurboModulePromiseRejectionsOnAndroid?: () => boolean; +updateRuntimeShadowNodeReferencesOnCommit?: () => boolean; +useAlwaysAvailableJSErrorHandling?: () => boolean;