8256675: Zero: purge biased locking support

Reviewed-by: coleenp, pchilanomate
This commit is contained in:
Aleksey Shipilev 2020-11-23 19:15:50 +00:00
parent d9ae0db699
commit 7551c6800c

@ -44,7 +44,6 @@
#include "prims/jvmtiExport.hpp" #include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp" #include "prims/jvmtiThreadState.hpp"
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/frame.inline.hpp" #include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp" #include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp" #include "runtime/interfaceSupport.inline.hpp"
@ -573,77 +572,15 @@ void BytecodeInterpreter::run(interpreterState istate) {
rcvr = LOCALS_OBJECT(0); rcvr = LOCALS_OBJECT(0);
VERIFY_OOP(rcvr); VERIFY_OOP(rcvr);
} }
// The initial monitor is ours for the taking. // The initial monitor is ours for the taking.
// Monitor not filled in frame manager any longer as this caused race condition with biased locking. // Monitor not filled in frame manager any longer as this caused race condition with biased locking.
BasicObjectLock* mon = &istate->monitor_base()[-1]; BasicObjectLock* mon = &istate->monitor_base()[-1];
mon->set_obj(rcvr); mon->set_obj(rcvr);
bool success = false;
uintptr_t epoch_mask_in_place = markWord::epoch_mask_in_place;
markWord mark = rcvr->mark();
intptr_t hash = (intptr_t) markWord::no_hash;
// Implies UseBiasedLocking.
if (mark.has_bias_pattern()) {
uintptr_t thread_ident;
uintptr_t anticipated_bias_locking_value;
thread_ident = (uintptr_t)istate->thread();
anticipated_bias_locking_value =
((rcvr->klass()->prototype_header().value() | thread_ident) ^ mark.value()) &
~(markWord::age_mask_in_place);
if (anticipated_bias_locking_value == 0) { assert(!UseBiasedLocking, "Not implemented");
// Already biased towards this thread, nothing to do.
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::biased_lock_entry_count_addr())++;
}
success = true;
} else if ((anticipated_bias_locking_value & markWord::biased_lock_mask_in_place) != 0) {
// Try to revoke bias.
markWord header = rcvr->klass()->prototype_header();
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
if (rcvr->cas_set_mark(header, mark) == mark) {
if (PrintBiasedLockingStatistics)
(*BiasedLocking::revoked_lock_entry_count_addr())++;
}
} else if ((anticipated_bias_locking_value & epoch_mask_in_place) != 0) {
// Try to rebias.
markWord new_header( (intptr_t) rcvr->klass()->prototype_header().value() | thread_ident);
if (hash != markWord::no_hash) {
new_header = new_header.copy_set_hash(hash);
}
if (rcvr->cas_set_mark(new_header, mark) == mark) {
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::rebiased_lock_entry_count_addr())++;
}
} else {
InterpreterRuntime::monitorenter(THREAD, mon);
}
success = true;
} else {
// Try to bias towards thread in case object is anonymously biased.
markWord header(mark.value() &
(markWord::biased_lock_mask_in_place |
markWord::age_mask_in_place | epoch_mask_in_place));
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
markWord new_header(header.value() | thread_ident);
// Debugging hint.
DEBUG_ONLY(mon->lock()->set_displaced_header(markWord((uintptr_t) 0xdeaddead));)
if (rcvr->cas_set_mark(new_header, header) == header) {
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
}
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception);
}
success = true;
}
}
// Traditional lightweight locking. // Traditional lightweight locking.
if (!success) {
markWord displaced = rcvr->mark().set_unlocked(); markWord displaced = rcvr->mark().set_unlocked();
mon->lock()->set_displaced_header(displaced); mon->lock()->set_displaced_header(displaced);
bool call_vm = UseHeavyMonitors; bool call_vm = UseHeavyMonitors;
@ -656,7 +593,6 @@ void BytecodeInterpreter::run(interpreterState istate) {
} }
} }
} }
}
THREAD->clr_do_not_unlock(); THREAD->clr_do_not_unlock();
// Notify jvmti. // Notify jvmti.
@ -737,74 +673,10 @@ void BytecodeInterpreter::run(interpreterState istate) {
BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base();
assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor"); assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor");
entry->set_obj(lockee); entry->set_obj(lockee);
bool success = false;
uintptr_t epoch_mask_in_place = markWord::epoch_mask_in_place;
markWord mark = lockee->mark(); assert(!UseBiasedLocking, "Not implemented");
intptr_t hash = (intptr_t) markWord::no_hash;
// implies UseBiasedLocking
if (mark.has_bias_pattern()) {
uintptr_t thread_ident;
uintptr_t anticipated_bias_locking_value;
thread_ident = (uintptr_t)istate->thread();
anticipated_bias_locking_value =
((lockee->klass()->prototype_header().value() | thread_ident) ^ mark.value()) &
~(markWord::age_mask_in_place);
if (anticipated_bias_locking_value == 0) {
// already biased towards this thread, nothing to do
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::biased_lock_entry_count_addr())++;
}
success = true;
} else if ((anticipated_bias_locking_value & markWord::biased_lock_mask_in_place) != 0) {
// try revoke bias
markWord header = lockee->klass()->prototype_header();
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
if (lockee->cas_set_mark(header, mark) == mark) {
if (PrintBiasedLockingStatistics) {
(*BiasedLocking::revoked_lock_entry_count_addr())++;
}
}
} else if ((anticipated_bias_locking_value & epoch_mask_in_place) !=0) {
// try rebias
markWord new_header( (intptr_t) lockee->klass()->prototype_header().value() | thread_ident);
if (hash != markWord::no_hash) {
new_header = new_header.copy_set_hash(hash);
}
if (lockee->cas_set_mark(new_header, mark) == mark) {
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::rebiased_lock_entry_count_addr())++;
}
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
} else {
// try to bias towards thread in case object is anonymously biased
markWord header(mark.value() & (markWord::biased_lock_mask_in_place |
markWord::age_mask_in_place | epoch_mask_in_place));
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
markWord new_header(header.value() | thread_ident);
// debugging hint
DEBUG_ONLY(entry->lock()->set_displaced_header(markWord((uintptr_t) 0xdeaddead));)
if (lockee->cas_set_mark(new_header, header) == header) {
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
}
} else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
}
}
// traditional lightweight locking // traditional lightweight locking
if (!success) {
markWord displaced = lockee->mark().set_unlocked(); markWord displaced = lockee->mark().set_unlocked();
entry->lock()->set_displaced_header(displaced); entry->lock()->set_displaced_header(displaced);
bool call_vm = UseHeavyMonitors; bool call_vm = UseHeavyMonitors;
@ -816,7 +688,6 @@ void BytecodeInterpreter::run(interpreterState istate) {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
} }
} }
}
UPDATE_PC_AND_TOS(1, -1); UPDATE_PC_AND_TOS(1, -1);
goto run; goto run;
} }
@ -1642,77 +1513,10 @@ run:
} }
if (entry != NULL) { if (entry != NULL) {
entry->set_obj(lockee); entry->set_obj(lockee);
int success = false;
uintptr_t epoch_mask_in_place = markWord::epoch_mask_in_place;
markWord mark = lockee->mark(); assert(!UseBiasedLocking, "Not implemented");
intptr_t hash = (intptr_t) markWord::no_hash;
// implies UseBiasedLocking
if (mark.has_bias_pattern()) {
uintptr_t thread_ident;
uintptr_t anticipated_bias_locking_value;
thread_ident = (uintptr_t)istate->thread();
anticipated_bias_locking_value =
((lockee->klass()->prototype_header().value() | thread_ident) ^ mark.value()) &
~(markWord::age_mask_in_place);
if (anticipated_bias_locking_value == 0) {
// already biased towards this thread, nothing to do
if (PrintBiasedLockingStatistics) {
(* BiasedLocking::biased_lock_entry_count_addr())++;
}
success = true;
}
else if ((anticipated_bias_locking_value & markWord::biased_lock_mask_in_place) != 0) {
// try revoke bias
markWord header = lockee->klass()->prototype_header();
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
if (lockee->cas_set_mark(header, mark) == mark) {
if (PrintBiasedLockingStatistics)
(*BiasedLocking::revoked_lock_entry_count_addr())++;
}
}
else if ((anticipated_bias_locking_value & epoch_mask_in_place) !=0) {
// try rebias
markWord new_header( (intptr_t) lockee->klass()->prototype_header().value() | thread_ident);
if (hash != markWord::no_hash) {
new_header = new_header.copy_set_hash(hash);
}
if (lockee->cas_set_mark(new_header, mark) == mark) {
if (PrintBiasedLockingStatistics)
(* BiasedLocking::rebiased_lock_entry_count_addr())++;
}
else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
}
else {
// try to bias towards thread in case object is anonymously biased
markWord header(mark.value() & (markWord::biased_lock_mask_in_place |
markWord::age_mask_in_place |
epoch_mask_in_place));
if (hash != markWord::no_hash) {
header = header.copy_set_hash(hash);
}
markWord new_header(header.value() | thread_ident);
// debugging hint
DEBUG_ONLY(entry->lock()->set_displaced_header(markWord((uintptr_t) 0xdeaddead));)
if (lockee->cas_set_mark(new_header, header) == header) {
if (PrintBiasedLockingStatistics)
(* BiasedLocking::anonymously_biased_lock_entry_count_addr())++;
}
else {
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
}
success = true;
}
}
// traditional lightweight locking // traditional lightweight locking
if (!success) {
markWord displaced = lockee->mark().set_unlocked(); markWord displaced = lockee->mark().set_unlocked();
entry->lock()->set_displaced_header(displaced); entry->lock()->set_displaced_header(displaced);
bool call_vm = UseHeavyMonitors; bool call_vm = UseHeavyMonitors;
@ -1724,7 +1528,6 @@ run:
CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
} }
} }
}
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
} else { } else {
istate->set_msg(more_monitors); istate->set_msg(more_monitors);
@ -1744,9 +1547,11 @@ run:
BasicLock* lock = most_recent->lock(); BasicLock* lock = most_recent->lock();
markWord header = lock->displaced_header(); markWord header = lock->displaced_header();
most_recent->set_obj(NULL); most_recent->set_obj(NULL);
if (!lockee->mark().has_bias_pattern()) {
bool call_vm = UseHeavyMonitors; assert(!UseBiasedLocking, "Not implemented");
// If it isn't recursive we either must swap old header or call the runtime // If it isn't recursive we either must swap old header or call the runtime
bool call_vm = UseHeavyMonitors;
if (header.to_pointer() != NULL || call_vm) { if (header.to_pointer() != NULL || call_vm) {
markWord old_header = markWord::encode(lock); markWord old_header = markWord::encode(lock);
if (call_vm || lockee->cas_set_mark(header, old_header) != old_header) { if (call_vm || lockee->cas_set_mark(header, old_header) != old_header) {
@ -1755,7 +1560,6 @@ run:
InterpreterRuntime::monitorexit(most_recent); InterpreterRuntime::monitorexit(most_recent);
} }
} }
}
UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);
} }
most_recent++; most_recent++;
@ -2008,11 +1812,8 @@ run:
memset(to_zero, 0, obj_size * HeapWordSize); memset(to_zero, 0, obj_size * HeapWordSize);
} }
} }
if (UseBiasedLocking) { assert(!UseBiasedLocking, "Not implemented");
result->set_mark(ik->prototype_header());
} else {
result->set_mark(markWord::prototype()); result->set_mark(markWord::prototype());
}
result->set_klass_gap(0); result->set_klass_gap(0);
result->set_klass(ik); result->set_klass(ik);
// Must prevent reordering of stores for object initialization // Must prevent reordering of stores for object initialization
@ -2816,7 +2617,8 @@ run:
markWord header = lock->displaced_header(); markWord header = lock->displaced_header();
end->set_obj(NULL); end->set_obj(NULL);
if (!lockee->mark().has_bias_pattern()) { assert(!UseBiasedLocking, "Not implemented");
// If it isn't recursive we either must swap old header or call the runtime // If it isn't recursive we either must swap old header or call the runtime
if (header.to_pointer() != NULL) { if (header.to_pointer() != NULL) {
markWord old_header = markWord::encode(lock); markWord old_header = markWord::encode(lock);
@ -2826,7 +2628,7 @@ run:
InterpreterRuntime::monitorexit(end); InterpreterRuntime::monitorexit(end);
} }
} }
}
// One error is plenty // One error is plenty
if (illegal_state_oop() == NULL && !suppress_error) { if (illegal_state_oop() == NULL && !suppress_error) {
{ {
@ -2883,8 +2685,8 @@ run:
markWord header = lock->displaced_header(); markWord header = lock->displaced_header();
base->set_obj(NULL); base->set_obj(NULL);
if (!rcvr->mark().has_bias_pattern()) { assert(!UseBiasedLocking, "Not implemented");
base->set_obj(NULL);
// If it isn't recursive we either must swap old header or call the runtime // If it isn't recursive we either must swap old header or call the runtime
if (header.to_pointer() != NULL) { if (header.to_pointer() != NULL) {
markWord old_header = markWord::encode(lock); markWord old_header = markWord::encode(lock);
@ -2902,7 +2704,6 @@ run:
} }
} }
} }
}
// Clear the do_not_unlock flag now. // Clear the do_not_unlock flag now.
THREAD->clr_do_not_unlock(); THREAD->clr_do_not_unlock();