mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8234544: ObjectSynchronizer::FastHashCode() cleanups from Async Monitor Deflation project
Reviewed-by: dholmes
This commit is contained in:
parent
8333ea85fa
commit
008bdefad4
1 changed files with 31 additions and 26 deletions
|
@ -694,35 +694,39 @@ intptr_t ObjectSynchronizer::FastHashCode(Thread* self, oop obj) {
|
||||||
// object should remain ineligible for biased locking
|
// object should remain ineligible for biased locking
|
||||||
assert(!mark.has_bias_pattern(), "invariant");
|
assert(!mark.has_bias_pattern(), "invariant");
|
||||||
|
|
||||||
if (mark.is_neutral()) {
|
if (mark.is_neutral()) { // if this is a normal header
|
||||||
hash = mark.hash(); // this is a normal header
|
hash = mark.hash();
|
||||||
if (hash != 0) { // if it has hash, just return it
|
if (hash != 0) { // if it has a hash, just return it
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
hash = get_next_hash(self, obj); // allocate a new hash code
|
hash = get_next_hash(self, obj); // get a new hash
|
||||||
temp = mark.copy_set_hash(hash); // merge the hash code into header
|
temp = mark.copy_set_hash(hash); // merge the hash into header
|
||||||
// use (machine word version) atomic operation to install the hash
|
// try to install the hash
|
||||||
test = obj->cas_set_mark(temp, mark);
|
test = obj->cas_set_mark(temp, mark);
|
||||||
if (test == mark) {
|
if (test == mark) { // if the hash was installed, return it
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
// If atomic operation failed, we must inflate the header
|
// Failed to install the hash. It could be that another thread
|
||||||
// into heavy weight monitor. We could add more code here
|
// installed the hash just before our attempt or inflation has
|
||||||
// for fast path, but it does not worth the complexity.
|
// occurred or... so we fall thru to inflate the monitor for
|
||||||
|
// stability and then install the hash.
|
||||||
} else if (mark.has_monitor()) {
|
} else if (mark.has_monitor()) {
|
||||||
monitor = mark.monitor();
|
monitor = mark.monitor();
|
||||||
temp = monitor->header();
|
temp = monitor->header();
|
||||||
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
||||||
hash = temp.hash();
|
hash = temp.hash();
|
||||||
if (hash != 0) {
|
if (hash != 0) { // if it has a hash, just return it
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
// Skip to the following code to reduce code size
|
// Fall thru so we only have one place that installs the hash in
|
||||||
|
// the ObjectMonitor.
|
||||||
} else if (self->is_lock_owned((address)mark.locker())) {
|
} else if (self->is_lock_owned((address)mark.locker())) {
|
||||||
temp = mark.displaced_mark_helper(); // this is a lightweight monitor owned
|
// This is a stack lock owned by the calling thread so fetch the
|
||||||
|
// displaced markWord from the BasicLock on the stack.
|
||||||
|
temp = mark.displaced_mark_helper();
|
||||||
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
||||||
hash = temp.hash(); // by current thread, check if the displaced
|
hash = temp.hash();
|
||||||
if (hash != 0) { // header contains hash code
|
if (hash != 0) { // if it has a hash, just return it
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
// WARNING:
|
// WARNING:
|
||||||
|
@ -735,29 +739,30 @@ intptr_t ObjectSynchronizer::FastHashCode(Thread* self, oop obj) {
|
||||||
// may not propagate to other threads correctly.
|
// may not propagate to other threads correctly.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inflate the monitor to set hash code
|
// Inflate the monitor to set the hash.
|
||||||
monitor = inflate(self, obj, inflate_cause_hash_code);
|
monitor = inflate(self, obj, inflate_cause_hash_code);
|
||||||
// Load displaced header and check it has hash code
|
// Load ObjectMonitor's header/dmw field and see if it has a hash.
|
||||||
mark = monitor->header();
|
mark = monitor->header();
|
||||||
assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
|
assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
|
||||||
hash = mark.hash();
|
hash = mark.hash();
|
||||||
if (hash == 0) {
|
if (hash == 0) { // if it does not have a hash
|
||||||
hash = get_next_hash(self, obj);
|
hash = get_next_hash(self, obj); // get a new hash
|
||||||
temp = mark.copy_set_hash(hash); // merge hash code into header
|
temp = mark.copy_set_hash(hash); // merge the hash into header
|
||||||
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
|
||||||
uintptr_t v = Atomic::cmpxchg(temp.value(), (volatile uintptr_t*)monitor->header_addr(), mark.value());
|
uintptr_t v = Atomic::cmpxchg(temp.value(), (volatile uintptr_t*)monitor->header_addr(), mark.value());
|
||||||
test = markWord(v);
|
test = markWord(v);
|
||||||
if (test != mark) {
|
if (test != mark) {
|
||||||
// The only non-deflation update to the ObjectMonitor's
|
// The attempt to update the ObjectMonitor's header/dmw field
|
||||||
// header/dmw field is to merge in the hash code. If someone
|
// did not work. This can happen if another thread managed to
|
||||||
// adds a new usage of the header/dmw field, please update
|
// merge in the hash just before our cmpxchg().
|
||||||
// this code.
|
// If we add any new usages of the header/dmw field, this code
|
||||||
|
// will need to be updated.
|
||||||
hash = test.hash();
|
hash = test.hash();
|
||||||
assert(test.is_neutral(), "invariant: header=" INTPTR_FORMAT, test.value());
|
assert(test.is_neutral(), "invariant: header=" INTPTR_FORMAT, test.value());
|
||||||
assert(hash != 0, "Trivial unexpected object/monitor header usage.");
|
assert(hash != 0, "should only have lost the race to a thread that set a non-zero hash");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We finally get the hash
|
// We finally get the hash.
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue