-
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
Stop using V8::External #13503
Comments
Mh, looking through the source …
I wouldn’t expect that anything here has a significant negative performance impact. |
Would it be possible to instead use a custom FunctionTemplate instead?
That would let Node typecheck it, which would avoid problems where bad JS
code can cause Node to crash.
…On Tue, Jun 6, 2017, 3:34 PM Anna Henningsen ***@***.***> wrote:
Mh, looking through the source …
- env.h & env-inl.h: This should be fine, it’s just creating the
object once and there’s not much we can do about these, I think. At least
it’s not trivially replaced by using internal fields.
- inspector_agent.cc: Maybe? This isn’t hot code, and I don’t know off
the top of my head what kind of object the inspector object is.
- node_api.cc: Yes, quite a few of those could probably be pointers.
We’d just need to make sure that we keep in mind that pointers provided
from userland can’t be assumed to be aligned.
- node_contextify.cc: The object on which we operate can be passed
from userland and doesn’t have any internal fields that would be available
for use by us.
- node_crypto.cc: These can’t be replaced by internal fields either,
but I think the methods using them might be dead code (i.e. not used
outside of our own tests).
- node_http_parser.cc, tls_wrap.cc & stream_base-inl.h: Externals are
used for passing around C++ objects in JS code; we might be able to get
around this by some refactoring.
I wouldn’t expect that anything here has a significant negative
performance impact.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#13503 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AGGWB1Xs1TeGSIa2oOOMVxhEIiR2b7fdks5sBam1gaJpZM4NxsKL>
.
|
I think you mean ObjectTemplate? Instantiating one with |
These getters are unused in our source code, untested (apart from a test checking that the getters themselves do not throw) and are useless for JS code due to the opaqueness of `v8::External`s. I can’t really imagine addons depending on this, especially as it’s undocumented and very niche anyway, but I guess there’s no reason to not consider this semver-major. Ref: nodejs#13503
I meant FunctionTemplate – V8 doesn’t (to my knowledge) allow one to
typecheck ObjectTemplate.
…On Jun 7, 2017 4:45 PM, "Ben Noordhuis" ***@***.***> wrote:
I think you mean ObjectTemplate? Instantiating one with NewInstance()
isn't much cheaper than External::New(). If anything, it's probably a
little slower because it does more.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#13503 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AGGWBw00qhLtTERQBYnbV3_sj1davOMvks5sBwvxgaJpZM4NxsKL>
.
|
FunctionTemplate doesn't have methods for defining extra slots but I infer you are referring to The point stands though that it's probably going to be at least as expensive as an External. Yes, you can do HasInstance checks on instances but that seems like a fairly marginal improvement over |
The main advantage is to avoid segfault “bugs” by ensuring that bad JS cannot cause a crash in C++. |
Just as a point of reference, I should note that I'm currently using V8::External in a couple of ways in the http2 implementation. Specifically:
|
Would it be possible to change those to use proper FunctionTemplates or to
use symbol-keyed properties?
…On Fri, Jun 16, 2017, 9:33 AM James M Snell ***@***.***> wrote:
Just as a point of reference, I should note that I'm currently using
V8::External in a couple of ways in the http2 implementation. Specifically:
-
The StreamBase reference on a socket is currently stored in an
External via the _external property. This reference is passed in to
the http2 impl's native side so that the native node::Http2Session can
read data from, and write data to, the StreamBase directly, without
bouncing back out to the JS layer each time. That could be refactored, of
course, but currently the _external is the only mechanism I have for
getting the appropriate pointer.
-
When headers are received, I am wrapping inbound header field names in
an external string to avoid unnecessary memcpy'ing. The header data is
passed from the nghttp2 library in a persistent buffer that is released
when the thing is garbage collected. If I was forced to treat header field
*values* as UTF-8 for backwards compatibility reasons, I would be
doing the same with those as it yields a significant performance
improvement.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#13503 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AGGWByuy-iX0vNLVHh-2uc3jGFHHESUDks5sEoQ-gaJpZM4NxsKL>
.
|
For the header names, not without adding a memcpy for every header field, which gets expensive very quickly. |
I'm working on getting rid of Externals in inspector, should be able to put up a PR by tomorrow. |
Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. Refs: nodejs#13503
- Group all relevant methods/states into a C++ class. - Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. - Use AsyncWrap to allow instrumenting callback states. Refs: nodejs#13503
- Group all relevant methods/states into a C++ class. - Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. - Use AsyncWrap to allow instrumenting callback states. PR-URL: nodejs#15643 Refs: nodejs#13503 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
- Group all relevant methods/states into a C++ class. - Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. - Use AsyncWrap to allow instrumenting callback states. PR-URL: nodejs/node#15643 Refs: nodejs/node#13503 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
- Group all relevant methods/states into a C++ class. - Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. - Use AsyncWrap to allow instrumenting callback states. Backport-PR-URL: nodejs#16071 PR-URL: nodejs#15643 Refs: nodejs#13503 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
- Group all relevant methods/states into a C++ class. - Uses internal fields instead of the less efficient v8::External for storing the pointer to the C++ object. - Use AsyncWrap to allow instrumenting callback states. Backport-PR-URL: #16071 PR-URL: #15643 Refs: #13503 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Eugene Ostroukhov <eostroukhov@google.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This issue has languished and it doesn't look like there is consensus on the suggested changes so I'll go ahead and close it out. |
Version: v6.10.3
Platform:
Subsystem: Scattered around in C++ code
Node.js uses
v8::External
in many places. However, these are not efficiently implemented in v8: each of them consists of a full object that contains a pointer. Instead, Node should ensure that each of the pointers is aligned, and useGetAlignedPointerInInternalField
/SetAlignedPointerInInternalField
instead.The text was updated successfully, but these errors were encountered: