-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[dart2wasm] High overhead getting JS wrapper for WasmGC objects in new interop API #55183
Comments
…ting to JS wrappers The `js_util.jsify()` related code shows up in CPU profile of wonderous. => Any `SkwasmObjectWrapper` object invokes this logic in the constructor and dispose method. This PR * makes `DomFinalizationRegistryExtension` accept JSAny types instead of Dart types and internally converting => Callsites can call more precise `<>.toJS*` extension methods => Avoids extra type checks on the objects * avoids making `toJSAnyShallow` delegate to `toJSAnyDeep` in wasm => `toJSAnyDeep` uses `js_util.jsify()` which is slow => We cannot use `Object.toJSBox` due to it being slower to create JS boxes as it semantically does something different atm (see issue below) => Instead use conditional import of `dart:_wasm` which provides the necessary primitives => Similar for going from JS to Dart. * Avoid calling converting from Dart object to JSAny more than needed (we did the operation twice for each registration and once for unregistration) Issue dart-lang/sdk#55183
Our plan is to do the third option: #55187. We've had some internal discussion a while back and agreed to add this, but we haven't had any external need for this until recently, so this should be a higher priority. |
As mentioned on the other issue, passing objects to JS and back again should use the fast mechanism by-default, we shouldn't encourage users to use a slow mechanism and hide the fast one /cc @sigmundch |
…ting to JS wrappers The `js_util.jsify()` related code shows up in CPU profile of wonderous. => Any `SkwasmObjectWrapper` object invokes this logic in the constructor and dispose method. This PR * makes `DomFinalizationRegistryExtension` accept JSAny types instead of Dart types and internally converting => Callsites can call more precise `<>.toJS*` extension methods => Avoids extra type checks on the objects * avoids making `toJSAnyShallow` delegate to `toJSAnyDeep` in wasm => `toJSAnyDeep` uses `js_util.jsify()` which is slow => We cannot use `Object.toJSBox` due to it being slower to create JS boxes as it semantically does something different atm (see issue below) => Instead use conditional import of `dart:_wasm` which provides the necessary primitives => Similar for going from JS to Dart. * Avoid calling converting from Dart object to JSAny more than needed (we did the operation twice for each registration and once for unregistration) Issue dart-lang/sdk#55183
…ting to JS wrappers The `js_util.jsify()` related code shows up in CPU profile of wonderous. => Any `SkwasmObjectWrapper` object invokes this logic in the constructor and dispose method. This PR * makes `DomFinalizationRegistryExtension` accept JSAny types instead of Dart types and internally converting => Callsites can call more precise `<>.toJS*` extension methods => Avoids extra type checks on the objects * avoids making `toJSAnyShallow` delegate to `toJSAnyDeep` in wasm => `toJSAnyDeep` uses `js_util.jsify()` which is slow => We cannot use `Object.toJSBox` due to it being slower to create JS boxes as it semantically does something different atm (see issue below) => Instead use conditional import of `dart:_wasm` which provides the necessary primitives => Similar for going from JS to Dart. * Avoid calling converting from Dart object to JSAny more than needed (we did the operation twice for each registration and once for unregistration) Issue dart-lang/sdk#55183 change condition move
…ting to JS wrappers The `js_util.jsify()` related code shows up in CPU profile of wonderous. => Any `SkwasmObjectWrapper` object invokes this logic in the constructor and dispose method. This PR * makes `DomFinalizationRegistryExtension` accept JSAny types instead of Dart types and internally converting => Callsites can call more precise `<>.toJS*` extension methods => Avoids extra type checks on the objects * avoids making `toJSAnyShallow` delegate to `toJSAnyDeep` in wasm => `toJSAnyDeep` uses `js_util.jsify()` which is slow => We cannot use `Object.toJSBox` due to it being slower to create JS boxes as it semantically does something different atm (see issue below) => Instead use conditional import of `dart:_wasm` which provides the necessary primitives => Similar for going from JS to Dart. * Avoid calling converting from Dart object to JSAny more than needed (we did the operation twice for each registration and once for unregistration) Issue dart-lang/sdk#55183 change condition move
…ting to JS wrappers (#51375) The `js_util.jsify()` related code shows up in CPU profile of wonderous. => Any `SkwasmObjectWrapper` object invokes this logic in the constructor and dispose method. This PR * makes `DomFinalizationRegistryExtension` accept `JSAny` types instead of Dart types and internally converting => Callsites can call more precise `<>.toJS*` extension methods => Will avoids extra type checks on the objects when we can call `Object.toJSBox` directly * makes us use a `toJSWrapper` / `fromJSWrapper` which will not delegate to a recursive `jsify()` but simply externalize the wasm gc object => We cannot use `Object.toJSBox` due to it being slower to create JS boxes as it semantically does something different atm (see issue below) => Instead use conditional import of `dart:_wasm` which provides the necessary primitives => Similar for going from JS to Dart. * Avoid converting from Dart object to `JSAny` more than needed (we did the operation twice for each registration and once for unregistration) Issue dart-lang/sdk#55183
We now have Thanks @srujzs for adding those! |
@srujzs This seems to be still the case. It may be a discrepancy between dart2js/ddc and dart2wasm. Should this get aligned? |
I believe it's aligned as it is:
ExternalDartReference when given an unrelated Dart object. In DDC and dart2js, both this operation and toExternalReference are a no-op. In dart2wasm, they both externalize the Dart object.
There's still the intention of disallowing unrelated Dart objects from being passed to |
If we disallow sending unrelated dart objects, then that's fine |
The issue in [0] was fixed. So we no longer have to use conditional imports and dart2wasm vs dart2js specific implementations. Instead we use the new extension methods introduced due to [0], namely `Object.toExternalReference` and `ExternalDartReference.toDartObject`. [0] dart-lang/sdk#55183
The issue in [0] was fixed. So we no longer have to use conditional imports and dart2wasm vs dart2js specific implementations. Instead we use the new extension methods introduced due to [0], namely `Object.toExternalReference` and `ExternalDartReference.toDartObject`. [0] dart-lang/sdk#55183
…er#53304) The issue in [0] was fixed. So we no longer have to use conditional imports and dart2wasm vs dart2js specific implementations. Instead we use the new extension methods introduced due to [0], namely `Object.toExternalReference` and `ExternalDartReference.toDartObject`. [0] dart-lang/sdk#55183
The current way to pass Dart objects to JavaScript with the new interop API is this via
Object.toJSBox
:The reasoning behind it seems to be safety when mixing dart objects from different dart applications running in the same browser context:
=> Our main user of Dart2Wasm is Flutter4Web where almost certainly only one Dart app runs
=> This makes us pay a high price for something that's very uncommon.
We need to change this. Either
Interestingly enough
js_util.jsify()
is high overhead due to many type tests and recursive behavior, but it does not perform the complex mechanism of obtaining JS wrappers. Instead it makes the simple & fast way to get JS wrapper, namelyWasmAnyRef.fromObject(object).externalize().toJS
./cc @srujzs
The text was updated successfully, but these errors were encountered: