Open ronag opened 1 year ago
We actually use it in some places (https://github.com/nodejs/node/blob/be525d7d04ec839fd2bb47affef00bb3c1302aca/src/node_process_methods.cc#L471-L475), just not a lot
I think the main reason that they aren't used a lot is this
* By design, fast calls are limited by the following requirements, which
* the embedder should enforce themselves:
* - they should not allocate on the JS heap;
* - they should not trigger JS execution.
And in many performance-critical bindings, we are either directly calling back from native to JS because that's just how the API works, or we need to invoke various kinds of hooks or make sure that process.nextTick() callbacks are processed. Or that we need to synthesize the return results as JS objects from native in a way that's cannot be easily worked around using AliasedStruct
or AliasedBuffer
. Though at least for APIs that are only calling native from JS without the need of a callback can certainly use more of the fast API calls.
Could napi support it?
So far this has been a pretty V8 thing. If we no longer prioritize engine-agnosticism then I suppose yes?
node_process_methods.cc
uses fast api, and I believe it is the only place its used.
SetFastMethod(ctx, object(), "hrtime", SlowNumber, &fast_number_);
SetFastMethod(ctx, object(), "hrtimeBigInt", SlowBigInt, &fast_bigint_);
Here's the list of fast_api calls Deno uses: https://github.com/search?q=repo%3Adenoland%2Fdeno+%23%5Bop%28fast%29%5D&type=code
This will be a good reference to where we can also do it. (Thanks to Deno team)
I think many of the Buffer
calls could make use of it, e.g. indexOf
.
V8 has support for fast call from js to cpp which NodeJS currently does not implement.
As @joyeecheung pointed out, we do use them in some places. Aside from the restrictions that Joyee mentioned, there is also a significant maintenance burden: there is no guarantee that V8 will actually use the fast API call, it depends on various compiler heuristics and runtime data types, so we have to maintain both the regular and the fast API call variant of the same API. It also only really helps much when the overhead of crossing the JS/C++ boundary really is significant compared to the complexity of the C++ function itself.
Newly committed to v8 repo https://github.com/v8/v8/commit/bc831f8ba33b79e2eb670faf1f84c4e39aeb0f9f
I’ll be happy to help someone to write a documentation about this and open a pull request to Node repository.
Hi @anonrig, I would like to work on this issue.
I'm removing the performance-agenda
label due to the open pull request.
One of the questions we (@ronag) had in the meeting was whether it is possible to add a function to NAPI to support v8 fast APIs. I need to find the right team for it, but let's investigate & ask if it's possible.
I think, while it's possible, Node-API has so far tried not to be too V8-specific. Also, one of the main motivations behind Node-API is stability and ABI compatibility, and V8 APIs don't typically guarantee that. (Native addons can already use V8 APIs, including fast API calls, if they don't need stability guarantees.)
cc @nodejs/node-api
Yes, new node-api must be validated that the api is agnostic towards the underlying JavaScript VM: https://github.com/nodejs/node/blob/main/doc/contributing/adding-new-napi-api.md -- i.e. it can be implemented on other JavaScript engines too, like other node-api implementations mentioned at https://github.com/nodejs/abi-stable-node/blob/doc/node-api-engine-bindings.md#node-api-bindings-for-other-runtimes.
V8 has support for fast call from js to cpp which NodeJS currently does not implement.