LibJS: Encode Cell Values as conventional bottom-tagged pointers #2633
+228
−239
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cell
values were previously encoded asNaN
-boxed pointers,with the
Cell
type encoded in the top bits of theNaN
-payload.However, since
Cell
values are so common, this meant that we had todo a lot of bit masking and bit shifting to retrieve the pointer
everytime we wanted to do a dereference.
Additionally, on all systems we support, (user-space) pointers must
always start with leading
0
bits.The new encoding therefore takes advantage of this by storing pointers
without any
NaN
-boxing, andNaN
-boxing the subnormal numbersinstead, which also all start with leading
0
bits.Since subnormals are rarely seen in practice, it makes sense to do
the masking and shifting on these values instead, and encode the
more common
Cell
pointers in their usual encodings, therebyincreasing performance on average.
We can then further take advantage of the fact that
Cell
pointers are8-byte aligned, and use the unused bottom bits to store the cell type.
This is called "bottom-tagging", which is better for modern CPUs as it
still allows them to prefetch the right cache line, since cache lines
are also >8-byte (usually 64-byte) aligned, and therefore have no reason
to inspect the bottom bits of a pointer in this case.
Bottom-tagging is also a more conventional approach, and as such
alternative garbage collector implementations are much more likely to
support it as compared to
NaN
-boxing.Furthermore, since
CellTag::Object == 0
,Value::as_object()
canbe optimized to a no-op in most cases, which makes the compiler and
the CPU very happy :^)
Note that since encoding non-userspace pointers is no longer supported,
LibJS
will no longer work correctly in kernel-space and on someembedded devices.
The capability to encode kernel-space pointers could be added back in
the future by adding a special case for them such that they will still
be
NaN
-boxed as before, at a performance cost of course.