RFR (XS) 8161280 - assert failed: reference count underflow for symbol

Kim Barrett kim.barrett at oracle.com
Thu Aug 25 17:37:06 UTC 2016


> On Aug 25, 2016, at 4:26 AM, Ioi Lam <ioi.lam at oracle.com> wrote:
> 
> On 8/24/16 11:52 PM, Kim Barrett wrote:
>>> On Aug 24, 2016, at 8:46 PM, Ioi Lam <ioi.lam at oracle.com> wrote:
>>> 
>>> Hi Kim,
>>> 
>>> Thanks for pointing out the problems with the shift operators. I never knew that!
>>> 
>>> Since I am shifting only by 16, can change the expressions to these?
>>> 
>>>    jint(add_value) * 0x10000
>> Yes.  I remembered that technique shortly after hitting send.
>> Multiplying a signed value doesn't work (is UB) in the general case
>> because of overflow, but we know the value ranges here are safe from
>> that.
>> 
>>>    jshort(new_value / 0x10000)
>> No, because under 2s complement arithmetic, arithmetic right shift of
>> a negative number is not necessarily equivalent to division by the
>> corresponding power of 2.  [See, for example, "Arithmetic shifting
>> considered harmful", Guy Steele, ACM SIGPLAN Notices, 11/1977.]
>> 
>> Consider the 32bit value with all 1s in the upper 16 bits, and a
>> non-zero value in the lower 16 bits.  If division is truncate, which
>> it is defined to be for C99/C++11 (*), that value / 0x10000 == 0,
>> rather than the desired -1.  Clear the low 16bits first and then
>> divide, and I think it works for the case at hand, though I haven't
>> proved it.  But pragmatically we’re probably better off assuming
>> right shift works as expected, though perhaps in a wrapper to
>> help indicate we’ve actually thought about the issue.
>> 
>> (*) For C89/C++98 the rounding of division involving negative operands
>> is implementation defined, perhaps in part to allow the "optimization"
>> of division by a power of 2 to arithmetic right shift.
>> 
>>> Does C/C++ preserve signs when multiplying/dividing with a positive constant?
> 
> Hi Kim,
> 
> I looked for the use of >> in our source code:
> 
> globalDefinitions.hpp:
> inline jint high(jlong value)                    { return jint(value >> 32); }
> 
> sharedRuntimeTrans.cpp:
> static double __ieee754_log(double x) {
>  double hfsq,f,s,z,R,w,t1,t2,dk;
>  int k,hx,i,j;
>  ...
>  k += (hx>>20)-1023;
> 
> So maybe we already assume that >> "does the right thing" for us?

Yes, that's what I expected to see.

> -------------------------------
> 
> Since I am doing something very specific (setting/extracting the top 16 bits of a jint), I am a bit hesitant to add routines for general shifting. globalDefinitions.hpp has these:

The suggestion of using a wrapper was a "perhaps", and not really
intended for you to deal with while addressing the problem at hand.
Sorry I was confusing about that.

If we do something along that line (as a separate project), I suggest
we keep with the names we've already got for similar operations,
e.g. use java_shift_{left,right} to be consistent with java_add and
friends.

> 
> inline int extract_low_short_from_int(jint x) {
>  return x & 0xffff;
> }
> inline int extract_high_short_from_int(jint x) {
>  return (x >> 16) & 0xffff;
> }
> inline int build_int_from_shorts( jushort low, jushort high ) {
>  return ((int)((unsigned int)high << 16) | (unsigned int)low);
> }
> 
> I am thinking of adding:
> 
> inline int extract_signed_high_short_from_int(jint x) {
>  if (x >= 0) {
>    return (x >> 16) & 0xffff;
>  } else {
>    return int((unsigned int)x >> 16) | 0xffff0000);
>  }
> }
> 
> inline int build_int_from_shorts(jshort low, jshort high) {
>  return build_int_from_shorts(jushort(low) & 0xffff, jushort(high) & 0xffff);
> }
> 
> What do you think?
> - Ioi




More information about the hotspot-runtime-dev mailing list