Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for JSI's NativeState API to the JSC Runtime #505

Closed
tomduncalf opened this issue Sep 6, 2022 · 2 comments
Closed

Add support for JSI's NativeState API to the JSC Runtime #505

tomduncalf opened this issue Sep 6, 2022 · 2 comments

Comments

@tomduncalf
Copy link

tomduncalf commented Sep 6, 2022

Introduction

The master branch of Hermes adds a NativeState API, allowing a C++ object to be attached to JS object, but this is not implemented for the JSC runtime. It would be great to enable this for users who do not have Hermes enabled.

Details

In Realm JS, every JS object that a user interacts with has an attached native C++ object. Accessing this attached object is therefore a very hot path when working with Realm, as nearly every operation needs to do it.

Prior to using JSI, we used JSC's JSObjectSetPrivate API to store this native C++ object reference. After migrating to JSI to support Hermes, there was no equivalent at the time, so we wrap the native object in a HostObject and store it as a property on the JSI Object, but accessing this is much slower than using the JSC "private data" API, resulting in a 2-4x decrease in performance in our benchmarks.

The master branch of Hermes adds a NativeState API, allowing a C++ object to be attached to JS object, and accessed in a performant manner, and seems to solve this for us.

However, this API is not implemented for the JSC runtime, so we need to fall back to the "store native object as a property" approach for users who do not have Hermes enabled, which results in a large (2x slower in benchmarks) performance regression.

It would be great if we were able to use the NativeState API for the JSC runtime also, to address this regression for users who cannot enable Hermes yet.

Discussion points

  • Is React Native interested in supporting new APIs for the JSC runtime in this way, or is the intention for all users to migrate to Hermes?
  • What is the best way to implement storing the NativeState object for the JSC Runtime?
    • I would suggest using the JSObjectSetPrivate API, as this is an order of magnitude faster than other approaches – under the hood, the private data is a member variable

    • Currently, the object created by makeObjectValue in the JSC runtime has a nullptr jsClassRef, which means it cannot store any private data (as per the docs).

      I would suggest it might be reasonable to change this to something like the following, which creates an object indistinguishable from one created with a nullptr jsClassRef but which can store private data. I have been told shouldn't have any negative performance impacts but this would require verification:

      JSClassDefinition definition = kJSClassDefinitionEmpty;
      JSClassRef classRef = JSClassCreate(&definition);
      objectRef = JSObjectMake(ctx_, classRef, nullptr);
      
@tomduncalf tomduncalf changed the title Add support for JSI's NativeState to the JSC Runtime Add support for JSI's NativeState API to the JSC Runtime Sep 6, 2022
@javache
Copy link

javache commented Jan 25, 2024

This has landed in facebook/react-native@7b7f128

@javache javache closed this as completed Jan 25, 2024
@liamjones
Copy link

This has landed in facebook/react-native@7b7f128

Pinging @kneth for awareness since I think Tom has now left Mongo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants