[aarch64] assert(is_power_of_2(x)) failed: x must be a power of 2: 0xffffffff80000000
Andrew Haley
aph at redhat.com
Wed Feb 26 14:30:03 UTC 2020
On 2/25/20 7:01 PM, Doerr, Martin wrote:
>
>> These overflow when x is the largest negative integer. This is
>> Undefined Behaviour, so we have to fix it somehow.
>
> That's right.
>
>> We'd do much better converting to an unsigned type and then
>> performing the calculation on that. Maybe we should provide just
>> one definition of this function, casting its argument to uint64_t.
>
> I agree. We should never use is_power_of_2 or exact_log2 with signed types.
The trouble with this reasoning is that jint has both the behaviour of
signed and unsigned types in C++. On the one hand, jints can be
interpreted as signed, but on the other hand the +/-/* and bitwise
operations on Java's ints behave like C++ unsigned types.
We could make it so that is_power_of_2 failed to compile if passed a
signed type. However, existing practice in HotSpot is that all of the
log2 functions cast signed types to unsigned types, for example:
inline int log2_int(int x) {
STATIC_ASSERT(sizeof(int) <= sizeof(uintptr_t));
return log2_intptr((uintptr_t)x);
}
inline int log2_jint(jint x) {
STATIC_ASSERT(sizeof(jint) <= sizeof(uintptr_t));
return log2_intptr((uintptr_t)x);
}
Therefore, I believe that it would be appropriate to follow existing
practice in is_power_of_2, like so:
template <typename T>
bool is_power_of_2(T val) {
STATIC_ASSERT(sizeof(T) <= sizeof(julong));
julong x = val;
return (x != 0) && ((x & (x - 1)) == 0);
}
// Log2 of a power of 2
template <typename T>
inline int exact_log2(T val) {
STATIC_ASSERT(sizeof(T) <= sizeof(julong));
julong x = val;
assert(is_power_of_2(x), "x must be a power of 2: " JULONG_FORMAT, x);
return log2_long(x);
}
--
Andrew Haley (he/him)
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
https://keybase.io/andrewhaley
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671
More information about the hotspot-compiler-dev
mailing list