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