Skip to content

Commit 9a3cd01

Browse files
javachefacebook-github-bot
authored andcommitted
Add feature flag to use JSI NativeState instead of HostObject (#36395)
Summary: Pull Request resolved: #36395 NativeState is a lighter-weight alternative to HostObject, which may simplify some of our use-cases of interacting with JS in the renderer. The down-side is that this approach doesn't allow exposing custom props or functions. This diffs adds new feature flags to enable experimenting with this functionality and measure any perf impact. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D41553421 fbshipit-source-id: 1a8f252b6910384d7a1a5699c2cca0b69e0c74ca
1 parent 419025d commit 9a3cd01

File tree

11 files changed

+87
-32
lines changed

11 files changed

+87
-32
lines changed

React/Fabric/RCTSurfacePresenter.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ - (RCTScheduler *)_createScheduler
277277
CoreFeatures::enablePropIteratorSetter = true;
278278
}
279279

280+
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:use_native_state")) {
281+
CoreFeatures::useNativeState = true;
282+
}
283+
280284
auto componentRegistryFactory =
281285
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
282286
EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) {

ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,10 @@ public class ReactFeatureFlags {
118118
* SurfaceMountingManager.
119119
*/
120120
public static boolean reduceDeleteCreateMutation = false;
121+
122+
/**
123+
* Use JSI NativeState API to store references to native objects rather than the more expensive
124+
* HostObject pattern
125+
*/
126+
public static boolean useNativeState = false;
121127
}

ReactAndroid/src/main/jni/react/fabric/Binding.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ void Binding::installFabricUIManager(
433433
CoreFeatures::enablePropIteratorSetter =
434434
getFeatureFlagValue("enableCppPropsIteratorSetter");
435435

436+
// NativeState experiment
437+
CoreFeatures::useNativeState = getFeatureFlagValue("useNativeState");
438+
436439
// RemoveDelete mega-op
437440
ShadowViewMutation::PlatformSupportsRemoveDeleteTreeInstruction =
438441
getFeatureFlagValue("enableRemoveDeleteTreeInstruction");

ReactCommon/react/renderer/core/CoreFeatures.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace react {
1313
bool CoreFeatures::enablePropIteratorSetter = false;
1414
bool CoreFeatures::enableMapBuffer = false;
1515
bool CoreFeatures::blockPaintForUseLayoutEffect = false;
16+
bool CoreFeatures::useNativeState = false;
1617

1718
} // namespace react
1819
} // namespace facebook

ReactCommon/react/renderer/core/CoreFeatures.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class CoreFeatures {
3030
// useLayoutEffect hooks to be processed. This changes affects scheduling of
3131
// when a transaction is mounted.
3232
static bool blockPaintForUseLayoutEffect;
33+
34+
// Whether to use Hermes' NativeState instead of HostObject
35+
// in simple data passing scenarios with JS
36+
static bool useNativeState;
3337
};
3438

3539
} // namespace react

ReactCommon/react/renderer/core/ShadowNode.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ static constexpr const int kShadowNodeChildrenSmallVectorSize = 8;
2929
class ComponentDescriptor;
3030
struct ShadowNodeFragment;
3131

32-
class ShadowNode : public Sealable, public DebugStringConvertible {
32+
class ShadowNode : public Sealable,
33+
public DebugStringConvertible,
34+
public jsi::NativeState {
3335
public:
3436
using Shared = std::shared_ptr<ShadowNode const>;
3537
using Weak = std::weak_ptr<ShadowNode const>;

ReactCommon/react/renderer/graphics/BUCK

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ load(
88
"get_apple_compiler_flags",
99
"get_apple_inspector_flags",
1010
"get_preprocessor_flags_for_build_mode",
11-
"react_native_target",
1211
"react_native_xplat_target",
1312
"rn_xplat_cxx_library",
1413
"subdir_glob",
@@ -53,7 +52,7 @@ rn_xplat_cxx_library(
5352
fbandroid_allow_jni_merging = True,
5453
fbandroid_deps = [
5554
FBJNI_TARGET,
56-
react_native_target("jni/react/jni:jni"),
55+
"//xplat/folly:dynamic",
5756
],
5857
fbandroid_exported_headers = subdir_glob(
5958
[

ReactCommon/react/renderer/runtimescheduler/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ rn_xplat_cxx_library(
4949
deps = [
5050
"//xplat/folly:dynamic",
5151
react_native_xplat_target("runtimeexecutor:runtimeexecutor"),
52+
react_native_xplat_target("react/renderer/core:core"),
5253
react_native_xplat_target("react/renderer/debug:debug"),
5354
react_native_xplat_target("butter:butter"),
5455
react_native_xplat_target("callinvoker:callinvoker"),

ReactCommon/react/renderer/runtimescheduler/Task.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class TaskPriorityComparer;
2121

2222
using RawCallback = std::function<void(jsi::Runtime &)>;
2323

24-
struct Task final {
24+
struct Task final : public jsi::NativeState {
2525
Task(
2626
SchedulerPriority priority,
2727
jsi::Function callback,

ReactCommon/react/renderer/runtimescheduler/primitives.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <folly/dynamic.h>
1111
#include <jsi/jsi.h>
12+
#include <react/renderer/core/CoreFeatures.h>
1213
#include <react/renderer/runtimescheduler/Task.h>
1314

1415
namespace facebook {
@@ -22,9 +23,15 @@ struct TaskWrapper : public jsi::HostObject {
2223

2324
inline static jsi::Value valueFromTask(
2425
jsi::Runtime &runtime,
25-
std::shared_ptr<Task> const &task) {
26-
return jsi::Object::createFromHostObject(
27-
runtime, std::make_shared<TaskWrapper>(task));
26+
std::shared_ptr<Task> task) {
27+
if (CoreFeatures::useNativeState) {
28+
jsi::Object obj(runtime);
29+
obj.setNativeState(runtime, std::move(task));
30+
return obj;
31+
} else {
32+
return jsi::Object::createFromHostObject(
33+
runtime, std::make_shared<TaskWrapper>(task));
34+
}
2835
}
2936

3037
inline static std::shared_ptr<Task> taskFromValue(
@@ -34,7 +41,11 @@ inline static std::shared_ptr<Task> taskFromValue(
3441
return nullptr;
3542
}
3643

37-
return value.getObject(runtime).getHostObject<TaskWrapper>(runtime)->task;
44+
if (CoreFeatures::useNativeState) {
45+
return value.getObject(runtime).getNativeState<Task>(runtime);
46+
} else {
47+
return value.getObject(runtime).getHostObject<TaskWrapper>(runtime)->task;
48+
}
3849
}
3950

4051
} // namespace react

0 commit comments

Comments
 (0)