Welcome to better optimised op calls! Currently opSync is called with parameters of every type and count. This most definitely makes the call megamorphic. Additionally, it seems that spread params leads to V8 not being able to optimise the calls quite as well (apparently Fast Calls cannot be used with spread params).
Monomorphising op calls should lead to some improved performance. Now that unwrapping of sync ops results is done on Rust side, this is pretty simple:
```
opSync("op_foo", param1, param2);
// -> turns to
ops.op_foo(param1, param2);
```
This means sync op calls are now just directly calling the native binding function. When V8 Fast API Calls are enabled, this will enable those to be called on the optimised path.
Monomorphising async ops likely requires using callbacks and is left as an exercise to the reader.
Pull request #14019 enabled initial support for realms, but it did not
include support for async ops anywhere other than the main realm. The
main issue was that the `js_recv_cb` callback, which resolves promises
corresponding to async ops, was only set for the main realm, so async
ops in other realms would never resolve. Furthermore, promise ID's are
specific to each realm, which meant that async ops from other realms
would result in a wrong promise from the main realm being resolved.
This change creates a `ContextState` struct, similar to
`JsRuntimeState` but stored in a slot of each `v8::Context`, which
contains a `js_recv_cb` callback for each realm. Combined with a new
list of known realms, which stores them as `v8::Weak<v8::Context>`,
and a change in the `#[op]` macro to pass the current context to
`queue_async_op`, this makes it possible to send the results of
promises for different realms to their realm, and prevent the ID's
from getting mixed up.
Additionally, since promise ID's are no longer unique to the isolate,
having a single set of unrefed ops doesn't work. This change therefore
also moves `unrefed_ops` from `JsRuntimeState` to `ContextState`, and
adds the lengths of the unrefed op sets for all known realms to get
the total number of unrefed ops to compare in the event loop.
Co-authored-by: Luis Malheiro <luismalheiro@gmail.com>
This commit adds new "import.meta.resolve()" API which
allows to resolve specifiers relative to the module the API
is called in. This API supports resolving using import maps.
Relanding #12994
This commit adds support for "unhandledrejection" event.
This event will trigger event listeners registered using:
"globalThis.addEventListener("unhandledrejection")
"globalThis.onunhandledrejection"
This is done by registering a default handler using
"Deno.core.setPromiseRejectCallback" that allows to
handle rejected promises in JavaScript instead of Rust.
This commit will make it possible to polyfill
"process.on("unhandledRejection")" in the Node compat
layer.
Co-authored-by: Colin Ihrig <cjihrig@gmail.com>
Update "deno_core" to not forward rejection of top level module
if it was already handled by appropriate handlers.
Co-authored-by: Colin Ihrig cjihrig@gmail.com
This commit uses `DetachedBuffer` instead of `ZeroCopyBuf` in the ops
that back `Worker.prototype.postMessage` and
`MessagePort.prototype.postMessage`. This is done because the
serialized buffer is then copied to the destination isolate, even
though it is internal to runtime code and not used for anything else,
so detaching it and transferring it instead saves an unnecessary copy.
The `op_event_loop_has_more_work` op, introduced in #14830, duplicates
code from `JsRuntime::poll_event_loop`. That PR also added the unused
method `JsRuntime::event_loop_has_work`, which is another duplication
of that same code, and which isn't used anywhere.
This change deduplicates this by renaming
`JsRuntime::event_loop_has_work` to `event_loop_pending_state`, and
making it the single place to determine what in the event loop is
pending. This result is then returned in a struct which is used both
in the event loop and in the `op_event_loop_has_more_work` op.
Currently almost every `JsRealm` method has a `&mut JsRuntime`
argument. This argument, however, is only used to get the runtime's
corresponding isolate. Given that a mutable reference to the
corresponding `v8::Isolate` can be reached from many more places than
a mutable reference to the `JsRuntime` (for example, by derefing a V8
scope), changing that will make `JsRealm` usable from many more places
than it currently is.
This commit adds support for "unhandledrejection" event.
This event will trigger event listeners registered using:
"globalThis.addEventListener("unhandledrejection")
"globalThis.onunhandledrejection"
This is done by registering a default handler using
"Deno.core.setPromiseRejectCallback" that allows to
handle rejected promises in JavaScript instead of Rust.
This commit will make it possible to polyfill
"process.on("unhandledRejection")" in the Node compat
layer.
Co-authored-by: Colin Ihrig <cjihrig@gmail.com>