-
Notifications
You must be signed in to change notification settings - Fork 29.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
consider implementing v8::Platform on top of libuv instead of using the default platform #12980
Comments
/cc @nodejs/v8 |
and @nodejs/chakracore too :) |
Just as an fyi, I played around with this a few months back and have some initial prototype work here: https://github.com/matthewloring/node/commit/c76caae8de9c689db1018506b2fa8d3ac4d38e3e. Happy to pick it up again or collaborate on this if others are interested. |
Interesting! It's not necessary to implement idle task support, the platform can just indicate that it doesn't support idle tasks. For the rest, why not post stuff directly to libuv's event loop? The Call* methods could be implemented on top of a uv_timer and uv_work_queue respectively. The tracing stuff, I'd just take over from v8's libplatform |
To further clarify, I believe you are suggesting that the Then, Node would substitute the uv background tasks for V8 background tasks in our (i.e. Node's) platform implementations. Chakra's implementation, as an example, would perhaps substitute Is that what you're suggesting? Thanks! |
On further review, I'm conflating Nevertheless... If we want a custom derivation of cc @mhdawson @nodejs/api |
Sorry, I'm indeed quite confused but what you mean @joshgav. I'd propose to first replace the bundling v8::Platform implementation with a custom node version, and then continue with your shared abstraction plan. Does that make sense? |
It's the proposed order that I'm not sure about. We (Node) have been trying to move away from tight coupling to V8 APIs, and writing our own implementation of v8::Platform seems to move us the other way. If we need our own implementation, wouldn't it be better to define a node::Platform (probably a copy of v8::Platform) first and derive from that? |
Hum, it sounds like we're still not talking about the same thing. Let me try to explain a bit more: v8::Platform is a pure virtual interface, and in order to start v8, you need to create a class that derives from that interface and pass an instance of that class to v8. if you copy v8::Platform and call it node::Platform (or anything else - copying is the point here), you can no longer use v8. To help embedders of v8 to get started, we bundle a library that provides an example class call "DefaultPlatform". For more advanced usages of v8, DefaultPlatform is not suitable. In this issue, I want to point out that the usage of v8 by node falls into this advanced category, and from v8 6.0 on, the shortcomings of DefaultPlatform will become user visible. What Matt started was to copy the DefaultPlatform into node, which is a reasonable first step. Maybe you're suggesting that this copy should inherit from some node::Platform interface? As explained above, it has to inherit from v8::Platform. I'm also not sure how much value there would be in such a node::Platform, as really all that v8::Platform does is giving access to the embedder's message loop which in node's case is handled by libuv. |
Yes, I'm suggesting a Please bear with me, all this is relevant to @jeisinger's original request cause I think Node shouldn't implement a custom platform till it defines and manages such a platform itself. The further we go with Also, a platform defined and managed by Node will make it easier to recognize proposed changes in one engine or embedder which others need to take account of - for example the Trace and Inspector initializers which were introduced over the past year into both A good example of this is in my demo code now: it doesn't compile primarily because of Line 248, which calls Building on this and using Chakra as an example, if it provided a similar platform initialization function, say by extending JsCreateRuntime, it wouldn't be able to accept a In summary, by defining and deriving from a Does that make sense? What do you think? Thanks! |
defining a node::Platform and then casting that to void* and having v8 cast that to v8::Platform is not allowed by the C++ standard. |
Also, I don't think it would work unless What do you think of the argument for a shared interface itself? |
I'd recommend introducing a wrapper library around the underlying VM that has an API you control. E.g. in chrome, we have the "gin" library that implements interfaces such as v8:: Platform, and the rest of chrome can instantiate v8 via a simple API provided by gin. |
Just so y’all know, there has been some previous discussion about this topic in #11855 (if I’m not mixing things up). |
Node.js currently uses the V8 implementation of the DefaultPlatform which schedules VM tasks on a V8 managed thread pool. Since the Node.js event loop is not aware of these tasks, the Node.js process may exit while there are outstanding VM tasks. This will become problematic once asynchronous wasm compilation lands in V8. This PR introduces a Node.js specific implementation of the v8::Platform on top of libuv so that the event loop is aware of outstanding VM tasks. PR-URL: #14001 Fixes: #3665 Fixes: #8496 Fixes: #12980 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Node.js currently uses the V8 implementation of the DefaultPlatform which schedules VM tasks on a V8 managed thread pool. Since the Node.js event loop is not aware of these tasks, the Node.js process may exit while there are outstanding VM tasks. This will become problematic once asynchronous wasm compilation lands in V8. This PR introduces a Node.js specific implementation of the v8::Platform on top of libuv so that the event loop is aware of outstanding VM tasks. PR-URL: #14001 Fixes: #3665 Fixes: #8496 Fixes: #12980 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Node.js currently uses the V8 implementation of the DefaultPlatform which schedules VM tasks on a V8 managed thread pool. Since the Node.js event loop is not aware of these tasks, the Node.js process may exit while there are outstanding VM tasks. This will become problematic once asynchronous wasm compilation lands in V8. This PR introduces a Node.js specific implementation of the v8::Platform on top of libuv so that the event loop is aware of outstanding VM tasks. PR-URL: #14001 Fixes: #3665 Fixes: #8496 Fixes: #12980 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
currently node.js just blocks if there are pending tasks on libuv's message loop before exiting, however, with e.g. WebAssembly's async compile API, it might be the case that there's ongoing work on one of v8::Platform's background threads, and eventually in the future, a task will be posted to the foreground thread to resolve the promise for the compilation.
If node.js would implement its own version of v8::Platform instead of relying on the default platform shipped with v8, it would have visibility into the number of on-going tasks, and could wait for the promise to resolve before exiting.
From a cursory look, posting tasks to the main loop of libuv would be easy. I didn't see a way to post delayed tasks? Also, node.js would have to implement its own worker pool.
There's no need to implement idle tasks, the platform can just indicate that it doesn't support idle tasks
The text was updated successfully, but these errors were encountered: