Use of long in Nashorn

Attila Szegedi szegedia at gmail.com
Fri Dec 4 15:40:11 UTC 2015


No worries, I’m subscribed to nashorn-dev :-) I’m reviewing the code right now.

> On Dec 4, 2015, at 4:39 PM, Jim Laskey (Oracle) <james.laskey at oracle.com> wrote:
> 
> Cool.  Note Attila’s mailing address is no more.
> 
> 
>> On Dec 4, 2015, at 11:27 AM, Hannes Wallnoefer <hannes.wallnoefer at oracle.com> wrote:
>> 
>> 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.
>> 
>> http://cr.openjdk.java.net/~hannesw/8144020/
>> https://bugs.openjdk.java.net/browse/JDK-8144020
>> 
>> 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 instances.
>> 
>> 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 OptimisticReturnFilters.java. 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.
>> 
>> Thanks,
>> Hannes
>> 
>> 
>> 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 oracle.com>  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 oracle.com>  wrote:
>>>>> 
>>>>>> On Nov 13, 2015, at 10:31 AM, Hannes Wallnoefer<hannes.wallnoefer at oracle.com>  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):
>>>>>> 
>>>>>> https://bugs.openjdk.java.net/browse/JDK-8065910
>>>>>> 
>>>>>> 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