Open
Bug 1275561
Opened 9 years ago
Updated 2 years ago
Change NaN boxing to fit 48 bits payloads.
Categories
(Core :: JavaScript Engine, enhancement, P5)
Core
JavaScript Engine
Tracking
()
NEW
Tracking | Status | |
---|---|---|
firefox49 | --- | affected |
People
(Reporter: nbp, Unassigned)
References
(Blocks 1 open bug)
Details
Having ValueTag on 16 bits is necessary to store 48 bits payload in JS::Value.
48 bits payload are necessary for some linux system, which allow to have a 48th bit for pointers.
Another nice aspect of 16+48 bits is that this would fit nicely with SIMD lane sizes, which would allow us to load multiple values with fewer instructions (such as Bug 832718 which relies on Bug 832779).
Among the proposal for moving from 17 bits to 16 bits, we have the following possibilities:
(1) Use a single tag for all special values: magic, null, undefined, true, and false.
(2) Use the sign bit as part of the tag.
(3) quiet-NaN and signaling-NaN should only matter if the values are flowing into Double arithmetic operation, so we could technically also reset (s) / set (q) the first bit of the mantissa of the NaN that we are manipulating.
The first 16 bits of a NaN are composed of
- 1 bit of sign
- 11 bits of exponents.
- 4 bits of mantissa. (with the top bit being the signaling(0) / quite(1) bit)
On x64, we currently use the 5 first bits of the mantissa, with 1 bit set for the making our ValueTag a qNaN, and 4 bits used to represent 10 different values tags.
Among the pit-falls about sNaN, is the fact that for the mantissa part of the tag is 0, we need non-zero mantissa (payload), otherwise we it might be interpreted as a valid ±Infinity.
Currently, to check if we have a Double, we check if the value is smaller that qNaN, which might be an issue for sNaN proposal (3), as we do not want to compare with sNaN
values.
Reporter | ||
Comment 1•9 years ago
|
||
Additional information to help design a better ValueTag.
Currently we have more than one valid double-NaN.
The valid NaN that we have today, are theoretically in the following range:
0x7ff0000000000000 - 0x7fffffffffffffff
0xfff8000000000000 - 0xfff80000ffffffff
On top of these ranges we have non-GC private pointers. Currently these pointers are stored by shifting the pointer by 1 to the right. The reason of the shift is (likely) to reset the sign bit, to prevent any private non-GC pointer to be interpreted as a valid JS::Value, which is not that safe after-all.
In practice (*), today, we have 2 double-NaNs ( ±qNaN(0) ) and all private pointers, on x64, fit in 47 bits.
So,
a. We can move private pointers, to have a proper ValueTag.
b. Restrict the NaN ranges to a few NaNs.
In the current implementation of the JS::Value, valid doubles are all the doubles which are (uint64_t-)below 0xfff80000ffffffff. The reason of this upper limit is that on 32bits we can only check for the upper part.
Also, This include all positive {s,q}NaNs, and all negative sNaN and qNaN{0x0 - 0xffffffff}.
Using the signaling/quiet bit (3), or the sign bit (2), we would have to change the way we check for valid doubles.
(*) https://treeherder.mozilla.org/#/jobs?repo=try&revision=682d0be587ca5d908918f3e6c25d4e6725246119
Reporter | ||
Updated•9 years ago
|
Priority: -- → P3
Updated•3 years ago
|
Severity: normal → S3
Updated•2 years ago
|
You need to log in
before you can comment on or make changes to this bug.
Description
•