Use of long in Nashorn

Hannes Wallnoefer hannes.wallnoefer at
Fri Dec 4 15:27:22 UTC 2015

After receiving another long/precision related bug last week I decided 
to go ahead with the removal of longs in Nashorn. It's been quite an 
effort, but I think it looks good now. Below are the links to the webrev 
and Jira issue.

This is a rather big patch, but it mostly removes code. There are over 
2000 deletions vs. 400 insertions. I removed all uses of long in our 
code where it represented JS numbers, including ScriptObject property 
accessors with longs as key or value, and the LongArrayData class. With 
this, all JS numbers are represented as int or double in Nashorn. Longs 
will not "naturally" occur anymore and only be present as java.lang.Long 

As expected, the areas that demanded special care were those where ES 
prescribes use of uint32. These are mostly unsigned right shift, 
Uint32Array elements, and the length property of arrays. For right shift 
and Uint32Array elements, I added optimistic implementations that return 
int if possible and deoptimize to double. Pdfjs and mandreel are 
benchmarks that make use of these features, and I didn't notice any 
observable impact on performance. Even when I simulated fallback to 
double performance was still ok (previously reported performance 
regressions for this case were in fact caused by an error of mine).

For the Array length property, I changed the getter in NativeArray to 
return int or double depending on actual value. Previously, the length 
getter always returned long. Since the property is actually evaluated by 
OptimisticTypesCalculator, for-loops with an array length as limit now 
use ints instead of longs to iterate through array indices, which is 
probably a good thing.

As for longs returned by Java code, their value is always preserved. 
Only when they are used for JS math they will be converted to double as 
prescribed by ECMA. When running with optimistic types we check if a 
long fits into an int or double to avoid deoptimization to object. 
Previously we did this only when converting long to optimistic int, but 
optimistic double did not use any return filter for longs, so a long 
returned for an optimistic double could easily lose precision.

You can find the related changes in I also 
added tests to make sure long values are preserved in various optimistic 
and non-optimstic contexts, some of which would have previously fail.

In a previous version of this patch it included functionality to only 
treat ints and doubles or their wrapper objects as native JS numbers 
(e.g. you could invoke Number.prototype methods only on ints and 
doubles). However, this is a quite a hairy issue and I reckoned the 
patch is large enough without it, so I pulled it out and will fix this 
separately as JDK-8143896.

I've testing and refining this patch for the last few days and think it 
looks pretty good. I thought it was a good idea to discuss this to this 
existing thread before posting a review request. Please let me know what 
you think.


Am 2015-11-13 um 15:06 schrieb Attila Szegedi:
> Well, we could just box them in that case. If we only used int and double as primitive number types internally, then a natural representation for a long becomes Long. Java methods returning long could have an optimistic filter that first checks if the value fits in an int (32-bit signed), then in a double (53-bit signed) without loss of precision, and finally deoptimizes to Object and uses Long. int->long->double->Object becomes int->double->Object, with longs of too large magnitude becoming boxed.
> Attila.
>> On Nov 13, 2015, at 2:46 PM, Jim Laskey (Oracle)<james.laskey at>  wrote:
>> The main thing to watch for here is that longs/Longs need to survive unobstructed between Java calls.  Remember we ran into trouble in this area (loss of precision when using longs for encoding.)
>>> On Nov 13, 2015, at 8:26 AM, Attila Szegedi<attila.szegedi at>  wrote:
>>>> On Nov 13, 2015, at 10:31 AM, Hannes Wallnoefer<hannes.wallnoefer at>  wrote:
>>>> Hi all,
>>>> I'm currently questioning our use of longs to represent numbers in combination with optimistic typing.
>>> I often feel that the presence of longs is more hassle than they’re worth. I’d be all for eliminating them.
>>>> After all, there's a pretty large range where long arithmetic will be more precise than the doubles required by ECMA.
>>> There’s currently several different places in Nashorn where we try to confine the precision of longs to 53 bits (so they aren’t more precise than doubles). It’s a bit of a whack-a-mole where you can’t always be sure whether you found all instances.
>>>> For context see this bug, especially the last two comments (the original bug was about number to string conversion which has been solved in the meantime):
>>>> So the question is: can we use longs at all and be confident that results won't be too precise (and thus, strictly speaking, incorrect)?
>>> Internally, the longs are also used for representing UInt32 even in non-optimistic setting, which is only really significant for the >>> operator and array indices and lengths; maybe we should limit longs to that usage only, or even just use doubles internally for UInt32 values that can’t be represented as Int32. FWIW, even for the >>> operator we only need it when shifting by zero, as in every other case the result will have the topmost bit set to 0 and thus fit in Int32 too.
>>> I guess once Valhalla rolls around, we could easily have an unsigned 32 bit int type.
>>>> Hannes
>>> Attila.

More information about the nashorn-dev mailing list