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

Kim Barrett kim.barrett at oracle.com
Thu Aug 25 06:52:43 UTC 2016


> 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?



More information about the hotspot-runtime-dev mailing list