< prev index next > src/hotspot/share/runtime/synchronizer.cpp
Print this page
#include "runtime/vmThread.hpp"
#include "utilities/align.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/globalDefinitions.hpp"
+ #include "utilities/fastHash.hpp"
#include "utilities/linkedlist.hpp"
#include "utilities/preserveException.hpp"
class ObjectMonitorDeflationLogging;
// (objects allocated back-to-back, in particular). This could potentially
// result in hashtable collisions and reduced hashtable efficiency.
// There are simple ways to "diffuse" the middle address bits over the
// generated hashCode values:
! static intptr_t get_next_hash(Thread* current, oop obj) {
intptr_t value = 0;
if (hashCode == 0) {
// This form uses global Park-Miller RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
// (objects allocated back-to-back, in particular). This could potentially
// result in hashtable collisions and reduced hashtable efficiency.
// There are simple ways to "diffuse" the middle address bits over the
// generated hashCode values:
! intptr_t ObjectSynchronizer::get_next_hash(Thread* current, oop obj) {
intptr_t value = 0;
if (hashCode == 0) {
// This form uses global Park-Miller RNG.
// On MP system we'll have lots of RW access to a global, so the
// mechanism induces lots of coherency traffic.
value = 1; // for sensitivity testing
} else if (hashCode == 3) {
value = ++GVars.hc_sequence;
} else if (hashCode == 4) {
value = cast_from_oop<intptr_t>(obj);
! } else {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = current->_hashStateX;
t ^= (t << 11);
value = 1; // for sensitivity testing
} else if (hashCode == 3) {
value = ++GVars.hc_sequence;
} else if (hashCode == 4) {
value = cast_from_oop<intptr_t>(obj);
! } else if (hashCode == 5) {
// Marsaglia's xor-shift scheme with thread-specific state
// This is probably the best overall implementation -- we'll
// likely make this the default in future releases.
unsigned t = current->_hashStateX;
t ^= (t << 11);
current->_hashStateZ = current->_hashStateW;
unsigned v = current->_hashStateW;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
current->_hashStateW = v;
value = v;
}
value &= markWord::hash_mask;
! if (value == 0) value = 0xBAD;
! assert(value != markWord::no_hash, "invariant");
return value;
}
static intptr_t install_hash_code(Thread* current, oop obj) {
assert(UseObjectMonitorTable && LockingMode == LM_LIGHTWEIGHT, "must be");
markWord mark = obj->mark_acquire();
for (;;) {
! intptr_t hash = mark.hash();
! if (hash != 0) {
! return hash;
! }
! hash = get_next_hash(current, obj);
! const markWord old_mark = mark;
! const markWord new_mark = old_mark.copy_set_hash(hash);
! mark = obj->cas_set_mark(new_mark, old_mark);
! if (old_mark == mark) {
! return hash;
}
}
}
intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
current->_hashStateZ = current->_hashStateW;
unsigned v = current->_hashStateW;
v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
current->_hashStateW = v;
value = v;
+ } else {
+ assert(UseCompactObjectHeaders, "Only with compact i-hash");
+ #ifdef _LP64
+ uint64_t val = cast_from_oop<uint64_t>(obj);
+ uint32_t hash = FastHash::get_hash32((uint32_t)val, (uint32_t)(val >> 32));
+ #else
+ uint32_t val = cast_from_oop<uint32_t>(obj);
+ uint32_t hash = FastHash::get_hash32(val, UCONST64(0xAAAAAAAA));
+ #endif
+ value= static_cast<intptr_t>(hash);
}
value &= markWord::hash_mask;
! if (hashCode != 6 && value == 0) value = 0xBAD;
! assert(value != markWord::no_hash || hashCode == 6, "invariant");
return value;
}
static intptr_t install_hash_code(Thread* current, oop obj) {
assert(UseObjectMonitorTable && LockingMode == LM_LIGHTWEIGHT, "must be");
markWord mark = obj->mark_acquire();
for (;;) {
! if (UseCompactObjectHeaders) {
! if (mark.is_hashed()) {
! return LightweightSynchronizer::get_hash(mark, obj);
! }
+ intptr_t hash = ObjectSynchronizer::get_next_hash(current, obj); // get a new hash
+ markWord new_mark;
+ if (mark.is_not_hashed_expanded()) {
+ new_mark = mark.set_hashed_expanded();
+ int offset = mark.klass()->hash_offset_in_bytes(obj);
+ obj->int_field_put(offset, (jint) hash);
+ } else {
+ new_mark = mark.set_hashed_not_expanded();
+ }
+ markWord old_mark = obj->cas_set_mark(new_mark, mark);
+ if (old_mark == mark) {
+ return hash;
+ }
+ mark = old_mark;
+ } else {
+ intptr_t hash = mark.hash();
+ if (hash != 0) {
+ return hash;
+ }
! hash = ObjectSynchronizer::get_next_hash(current, obj);
! const markWord old_mark = mark;
! const markWord new_mark = old_mark.copy_set_hash(hash);
! mark = obj->cas_set_mark(new_mark, old_mark);
! if (old_mark == mark) {
! return hash;
+ }
}
}
}
intptr_t ObjectSynchronizer::FastHashCode(Thread* current, oop obj) {
< prev index next >