mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8161280: assert failed: reference count underflow for symbol
Reviewed-by: dholmes, coleenp, kbarrett
This commit is contained in:
parent
4aea7b3333
commit
e710f3bd8b
2 changed files with 20 additions and 18 deletions
|
@ -229,24 +229,25 @@ unsigned int Symbol::new_hash(juint seed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Symbol::increment_refcount() {
|
void Symbol::increment_refcount() {
|
||||||
// Only increment the refcount if positive. If negative either
|
// Only increment the refcount if non-negative. If negative either
|
||||||
// overflow has occurred or it is a permanent symbol in a read only
|
// overflow has occurred or it is a permanent symbol in a read only
|
||||||
// shared archive.
|
// shared archive.
|
||||||
if (_refcount >= 0) {
|
if (_refcount >= 0) { // not a permanent symbol
|
||||||
Atomic::inc(&_refcount);
|
Atomic::inc(&_refcount);
|
||||||
NOT_PRODUCT(Atomic::inc(&_total_count);)
|
NOT_PRODUCT(Atomic::inc(&_total_count);)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Symbol::decrement_refcount() {
|
void Symbol::decrement_refcount() {
|
||||||
if (_refcount >= 0) {
|
if (_refcount >= 0) { // not a permanent symbol
|
||||||
Atomic::dec(&_refcount);
|
jshort new_value = Atomic::add(-1, &_refcount);
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (_refcount < 0) {
|
if (new_value == -1) { // we have transitioned from 0 -> -1
|
||||||
print();
|
print();
|
||||||
assert(false, "reference count underflow for symbol");
|
assert(false, "reference count underflow for symbol");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
(void)new_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ class Atomic : AllStatic {
|
||||||
|
|
||||||
// Atomically add to a location. Returns updated value. add*() provide:
|
// Atomically add to a location. Returns updated value. add*() provide:
|
||||||
// <fence> add-value-to-dest <membar StoreLoad|StoreStore>
|
// <fence> add-value-to-dest <membar StoreLoad|StoreStore>
|
||||||
|
inline static jshort add (jshort add_value, volatile jshort* dest);
|
||||||
inline static jint add (jint add_value, volatile jint* dest);
|
inline static jint add (jint add_value, volatile jint* dest);
|
||||||
inline static size_t add (size_t add_value, volatile size_t* dest);
|
inline static size_t add (size_t add_value, volatile size_t* dest);
|
||||||
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
|
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
|
||||||
|
@ -208,10 +209,11 @@ inline jlong Atomic::add(jlong add_value, volatile jlong* dest) {
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Atomic::inc(volatile short* dest) {
|
inline jshort Atomic::add(jshort add_value, volatile jshort* dest) {
|
||||||
// Most platforms do not support atomic increment on a 2-byte value. However,
|
// Most platforms do not support atomic add on a 2-byte value. However,
|
||||||
// if the value occupies the most significant 16 bits of an aligned 32-bit
|
// if the value occupies the most significant 16 bits of an aligned 32-bit
|
||||||
// word, then we can do this with an atomic add of 0x10000 to the 32-bit word.
|
// word, then we can do this with an atomic add of (add_value << 16)
|
||||||
|
// to the 32-bit word.
|
||||||
//
|
//
|
||||||
// The least significant parts of this 32-bit word will never be affected, even
|
// The least significant parts of this 32-bit word will never be affected, even
|
||||||
// in case of overflow/underflow.
|
// in case of overflow/underflow.
|
||||||
|
@ -219,21 +221,20 @@ inline void Atomic::inc(volatile short* dest) {
|
||||||
// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
|
// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
|
||||||
#ifdef VM_LITTLE_ENDIAN
|
#ifdef VM_LITTLE_ENDIAN
|
||||||
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
|
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
|
||||||
(void)Atomic::add(0x10000, (volatile int*)(dest-1));
|
jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
|
||||||
#else
|
#else
|
||||||
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
|
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
|
||||||
(void)Atomic::add(0x10000, (volatile int*)(dest));
|
jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
|
||||||
#endif
|
#endif
|
||||||
|
return (jshort)(new_value >> 16); // preserves sign
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Atomic::dec(volatile short* dest) {
|
inline void Atomic::inc(volatile jshort* dest) {
|
||||||
#ifdef VM_LITTLE_ENDIAN
|
(void)add(1, dest);
|
||||||
assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
|
}
|
||||||
(void)Atomic::add(-0x10000, (volatile int*)(dest-1));
|
|
||||||
#else
|
inline void Atomic::dec(volatile jshort* dest) {
|
||||||
assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
|
(void)add(-1, dest);
|
||||||
(void)Atomic::add(-0x10000, (volatile int*)(dest));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SHARE_VM_RUNTIME_ATOMIC_HPP
|
#endif // SHARE_VM_RUNTIME_ATOMIC_HPP
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue