GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||
GeezerVison is showing github.com — src: use STL containers instead of v8 values for static module data by joyeecheung · Pull Request #24384 · nodejs/node Conversation
|
|
@joyeecheung build started: https://ci.nodejs.org/blue/organizations/jenkins/node-test-pull-request-lite-pipeline/detail/node-test-pull-request-lite-pipeline/1626/pipeline |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
CI: https://ci.nodejs.org/job/node-test-pull-request/18661/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Also @hashseed as I understand there is no way to use the cache if node is started with v8 flags which leads to a mismatch of the flag hash in the serialized code cache data, is that correct? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Hm, maybe this one could better be implemented as an ToV8Value() overload from util.h? It fits in with the others pretty well, I think (the downside being that we always use UTF8 there unconditionally…)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
@addaleax The current implementation is only capable of converting std::set<const std::string> to an array...not exactly what we want here, but I can leave a TODO
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
btw, did you consider using std::unordered_map and std::unordered_set over std::map/std::set? I don’t know if we need to worry a lot about the performance tradeoffs here, but I personally tend to use the unordered versions when I can
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a reason not to use the unordered version...good idea, I'll change that
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Wow! 😮 Looks great.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
@joyeecheung could you gist the new |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
@refack If I remove the static char data, they look like this: https://gist.github.com/joyeecheung/9b41e0b9309d9492270ba23a92e2733d |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Thanks for the reviews, updated. CI: https://ci.nodejs.org/job/node-test-pull-request/18673/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
IMO they look much better than before 😄 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Rebased: https://ci.nodejs.org/job/node-test-pull-request/18675/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
So...interesting enough, this uncovers a circular dependency in I opened #24396 to fix this. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Is the return value cached / should it be cached? Right now it seems like every time internalBinding('native_module').source is accessed a new object is created.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
It's not cached, but that does not really matter since this is only used by tools/generate_code_cache.js, the native module loader in the binary only gets to call into a C++ function that can access the std::unordered_map directly.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
So...interesting: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/275 https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/276 I tried to google around and turns out that's not quite surprising, given that we only have < 200 items, and we only insert items and don't touch them once the map is initialized, hashing on the strings could be slower than searching in the tree. e.g. See https://stackoverflow.com/questions/4846798/why-would-map-be-much-faster-than-unordered-map (this almost tempted me to try implementing a trie..nah) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Removing |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
CI (rebased on master): https://ci.nodejs.org/job/node-test-pull-request/18724/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
LGTM other than some fairly superficial comments.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Use isUint8Array from util.types?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This change should be unneeded right?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
@TimothyGu Yeah, just so that it's clearer since this length is only used to calculate a string displayed in KB/MB etc. human readable format.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'll switch this to const size = cachedData.byteLength - I think that makes this a bit more self-explanatory and less ambiguous
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
nit: bootstrap
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I’d make this a method, as it signals that getting the value is a relatively expensive operation (and that the returned object is different every time this is called).
Ditto for GetCacheUsage().
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:
- It's slightly lighter in weight compared to storing things on the
v8 heap. Also it may be slightly faster since the preivous v8::Object is
already in dictionary mode - though the difference is very small
given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
since they just initialize static arrays and manipulate STL
constructs. They are also easier to debug from the C++'s side,
especially early in the bootstrap process when no inspector
can be attached.
- The static native module data can be accessed independent of any
Environment or Isolate, and it's easy to look them up from the
C++'s side.
- It's now impossible to mutate the source code used to compile
native modules from the JS land since it's completely separate
from the v8 heap. We can still get the constant strings from
process.binding('natives') but that's all.
A few drive-by fixes:
- Remove DecorateErrorStack in LookupAndCompile - We don't need to
capture the exception to decorate when we encounter
errors during native module compilation, as those errors should be
syntax errors and v8 is able to decorate them well. We use
CompileFunctionInContext so there is no need to worry about
wrappers either.
- The code cache could be rejected when node is started with v8 flags.
Instead of aborting in that case, simply keep a record in the
native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
to make the one-byte/two-byte special treatment easier to read.
|
Fixed a few more nits & rebased & squashed the fixup into one. CI: https://ci.nodejs.org/job/node-test-pull-request/18758/ |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Landed in 7778c03, thanks! |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:
- It's slightly lighter in weight compared to storing things on the
v8 heap. Also it may be slightly faster since the preivous v8::Object
is already in dictionary mode - though the difference is very small
given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
since they just initialize static arrays and manipulate STL
constructs.
- The static native module data can be accessed independently of any
Environment or Isolate, and it's easy to look them up from the
C++'s side.
- It's now impossible to mutate the source code used to compile
native modules from the JS land since it's completely separate
from the v8 heap. We can still get the constant strings from
process.binding('natives') but that's all.
A few drive-by fixes:
- Remove DecorateErrorStack in LookupAndCompile - We don't need to
capture the exception to decorate when we encounter
errors during native module compilation, as those errors should be
syntax errors and v8 is able to decorate them well. We use
CompileFunctionInContext so there is no need to worry about
wrappers either.
- The code cache could be rejected when node is started with v8 flags.
Instead of aborting in that case, simply keep a record in the
native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
to make the one-byte/two-byte special treatment easier to read.
PR-URL: #24384
Fixes: https://github.com/Remove
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Franziska Hinkelmann <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: James M Snell <[email protected]>
There was an error while loading. Please reload this page.
|
This should be backported together with #24382 and #24382 (for 10.x at least, I am not sure if we need to backport this to 8.x? Mostly because I don't know if at this point 8.x patches are backported on an as-needed basis or we are still trying to backport everything possible onto 8.x) |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:
- It's slightly lighter in weight compared to storing things on the
v8 heap. Also it may be slightly faster since the preivous v8::Object
is already in dictionary mode - though the difference is very small
given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
since they just initialize static arrays and manipulate STL
constructs.
- The static native module data can be accessed independently of any
Environment or Isolate, and it's easy to look them up from the
C++'s side.
- It's now impossible to mutate the source code used to compile
native modules from the JS land since it's completely separate
from the v8 heap. We can still get the constant strings from
process.binding('natives') but that's all.
A few drive-by fixes:
- Remove DecorateErrorStack in LookupAndCompile - We don't need to
capture the exception to decorate when we encounter
errors during native module compilation, as those errors should be
syntax errors and v8 is able to decorate them well. We use
CompileFunctionInContext so there is no need to worry about
wrappers either.
- The code cache could be rejected when node is started with v8 flags.
Instead of aborting in that case, simply keep a record in the
native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
to make the one-byte/two-byte special treatment easier to read.
PR-URL: #24384
Fixes: https://github.com/Remove
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Franziska Hinkelmann <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:
- It's slightly lighter in weight compared to storing things on the
v8 heap. Also it may be slightly faster since the preivous v8::Object
is already in dictionary mode - though the difference is very small
given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
since they just initialize static arrays and manipulate STL
constructs.
- The static native module data can be accessed independently of any
Environment or Isolate, and it's easy to look them up from the
C++'s side.
- It's now impossible to mutate the source code used to compile
native modules from the JS land since it's completely separate
from the v8 heap. We can still get the constant strings from
process.binding('natives') but that's all.
A few drive-by fixes:
- Remove DecorateErrorStack in LookupAndCompile - We don't need to
capture the exception to decorate when we encounter
errors during native module compilation, as those errors should be
syntax errors and v8 is able to decorate them well. We use
CompileFunctionInContext so there is no need to worry about
wrappers either.
- The code cache could be rejected when node is started with v8 flags.
Instead of aborting in that case, simply keep a record in the
native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
to make the one-byte/two-byte special treatment easier to read.
PR-URL: #24384
Fixes: https://github.com/Remove
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Franziska Hinkelmann <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:
- It's slightly lighter in weight compared to storing things on the
v8 heap. Also it may be slightly faster since the preivous v8::Object
is already in dictionary mode - though the difference is very small
given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
since they just initialize static arrays and manipulate STL
constructs.
- The static native module data can be accessed independently of any
Environment or Isolate, and it's easy to look them up from the
C++'s side.
- It's now impossible to mutate the source code used to compile
native modules from the JS land since it's completely separate
from the v8 heap. We can still get the constant strings from
process.binding('natives') but that's all.
A few drive-by fixes:
- Remove DecorateErrorStack in LookupAndCompile - We don't need to
capture the exception to decorate when we encounter
errors during native module compilation, as those errors should be
syntax errors and v8 is able to decorate them well. We use
CompileFunctionInContext so there is no need to worry about
wrappers either.
- The code cache could be rejected when node is started with v8 flags.
Instead of aborting in that case, simply keep a record in the
native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
to make the one-byte/two-byte special treatment easier to read.
PR-URL: nodejs#24384
Fixes: https://github.com/Remove
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Franziska Hinkelmann <[email protected]>
Reviewed-By: Tiancheng "Timothy" Gu <[email protected]>
Reviewed-By: James M Snell <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.