8230184: rename, whitespace, indent and comments changes in preparation for lock free Monitor lists

Reviewed-by: kbarrett, dholmes
This commit is contained in:
Daniel D. Daugherty 2019-08-28 10:56:50 -04:00
parent a2c067f6e8
commit 9b992ead1e
12 changed files with 490 additions and 474 deletions

View File

@ -946,7 +946,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
while (is_being_initialized() && !is_reentrant_initialization(jt)) {
wait = true;
jt->set_class_to_be_initialized(this);
ol.waitUninterruptibly(jt);
ol.wait_uninterruptibly(jt);
jt->set_class_to_be_initialized(NULL);
}

View File

@ -44,8 +44,8 @@ class ObjectWaiter : public StackObj {
public:
enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
enum Sorted { PREPEND, APPEND, SORTED };
ObjectWaiter * volatile _next;
ObjectWaiter * volatile _prev;
ObjectWaiter* volatile _next;
ObjectWaiter* volatile _prev;
Thread* _thread;
jlong _notifier_tid;
ParkEvent * _event;
@ -142,25 +142,35 @@ class ObjectMonitor {
friend class VMStructs;
JVMCI_ONLY(friend class JVMCIVMStructs;)
volatile markWord _header; // displaced object header word - mark
void* volatile _object; // backward object pointer - strong root
// The sync code expects the header field to be at offset zero (0).
// Enforced by the assert() in header_addr().
volatile markWord _header; // displaced object header word - mark
void* volatile _object; // backward object pointer - strong root
public:
ObjectMonitor* FreeNext; // Free list linkage
ObjectMonitor* _next_om; // Next ObjectMonitor* linkage
private:
// Separate _header and _owner on different cache lines since both can
// have busy multi-threaded access. _header and _object are set at
// initial inflation and _object doesn't change until deflation so
// _object is a good choice to share the cache line with _header.
// _next_om shares _header's cache line for pre-monitor list historical
// reasons. _next_om only changes if the next ObjectMonitor is deflated.
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
sizeof(volatile markWord) + sizeof(void * volatile) +
sizeof(volatile markWord) + sizeof(void* volatile) +
sizeof(ObjectMonitor *));
protected: // protected for JvmtiRawMonitor
void * volatile _owner; // pointer to owning thread OR BasicLock
void* volatile _owner; // pointer to owning thread OR BasicLock
private:
volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor
volatile intptr_t _recursions; // recursion count, 0 for first entry
ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
protected: // protected for JvmtiRawMonitor
volatile intptr_t _recursions; // recursion count, 0 for first entry
ObjectWaiter* volatile _EntryList; // Threads blocked on entry or reentry.
// The list is actually composed of WaitNodes,
// acting as proxies for Threads.
private:
ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry.
Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
Thread * volatile _Responsible;
ObjectWaiter* volatile _cxq; // LL of recently-arrived threads blocked on entry.
Thread* volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
Thread* volatile _Responsible;
volatile int _Spinner; // for exit->spinner handoff optimization
volatile int _SpinDuration;
@ -169,7 +179,7 @@ class ObjectMonitor {
// along with other fields to determine if an ObjectMonitor can be
// deflated. See ObjectSynchronizer::deflate_monitor().
protected:
ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
ObjectWaiter* volatile _WaitSet; // LL of threads wait()ing on the monitor
volatile jint _waiters; // number of waiting threads
private:
volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
@ -202,7 +212,7 @@ class ObjectMonitor {
void* operator new (size_t size) throw();
void* operator new[] (size_t size) throw();
void operator delete(void* p);
void operator delete[] (void *p);
void operator delete[] (void* p);
// TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
// ByteSize would also be an appropriate type.
@ -256,7 +266,7 @@ class ObjectMonitor {
protected:
// We don't typically expect or want the ctors or dtors to run.
// normal ObjectMonitors are type-stable and immortal.
ObjectMonitor() { ::memset((void *)this, 0, sizeof(*this)); }
ObjectMonitor() { ::memset((void*)this, 0, sizeof(*this)); }
~ObjectMonitor() {
// TODO: Add asserts ...
@ -305,18 +315,18 @@ class ObjectMonitor {
void reenter(intptr_t recursions, TRAPS);
private:
void AddWaiter(ObjectWaiter * waiter);
void INotify(Thread * Self);
ObjectWaiter * DequeueWaiter();
void DequeueSpecificWaiter(ObjectWaiter * waiter);
void AddWaiter(ObjectWaiter* waiter);
void INotify(Thread* self);
ObjectWaiter* DequeueWaiter();
void DequeueSpecificWaiter(ObjectWaiter* waiter);
void EnterI(TRAPS);
void ReenterI(Thread * Self, ObjectWaiter * SelfNode);
void UnlinkAfterAcquire(Thread * Self, ObjectWaiter * SelfNode);
int TryLock(Thread * Self);
int NotRunnable(Thread * Self, Thread * Owner);
int TrySpin(Thread * Self);
void ExitEpilog(Thread * Self, ObjectWaiter * Wakee);
bool ExitSuspendEquivalent(JavaThread * Self);
void ReenterI(Thread* self, ObjectWaiter* self_node);
void UnlinkAfterAcquire(Thread* self, ObjectWaiter* self_node);
int TryLock(Thread* self);
int NotRunnable(Thread* self, Thread * Owner);
int TrySpin(Thread* self);
void ExitEpilog(Thread* self, ObjectWaiter* Wakee);
bool ExitSuspendEquivalent(JavaThread* self);
};
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP

View File

@ -128,8 +128,8 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
(symboltable_work = SymbolTable::has_work()) |
(resolved_method_table_work = ResolvedMethodTable::has_work()) |
(protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
(oopstorage_work = OopStorage::has_cleanup_work_and_reset()))
== 0) {
(oopstorage_work = OopStorage::has_cleanup_work_and_reset())
) == 0) {
// Wait until notified that there is some work to do.
ml.wait();
}

File diff suppressed because it is too large Load Diff

View File

@ -34,12 +34,14 @@
class ObjectMonitor;
class ThreadsList;
typedef PaddedEnd<ObjectMonitor, DEFAULT_CACHE_LINE_SIZE> PaddedObjectMonitor;
struct DeflateMonitorCounters {
int nInuse; // currently associated with objects
int nInCirculation; // extant
int nScavenged; // reclaimed (global and per-thread)
int perThreadScavenged; // per-thread scavenge total
double perThreadTimes; // per-thread scavenge times
int n_in_use; // currently associated with objects
int n_in_circulation; // extant
int n_scavenged; // reclaimed (global and per-thread)
int per_thread_scavenged; // per-thread scavenge total
double per_thread_times; // per-thread scavenge times
};
class ObjectSynchronizer : AllStatic {
@ -79,13 +81,13 @@ class ObjectSynchronizer : AllStatic {
static void notify(Handle obj, TRAPS);
static void notifyall(Handle obj, TRAPS);
static bool quick_notify(oopDesc* obj, Thread* Self, bool All);
static bool quick_enter(oop obj, Thread* Self, BasicLock* Lock);
static bool quick_notify(oopDesc* obj, Thread* self, bool All);
static bool quick_enter(oop obj, Thread* self, BasicLock* Lock);
// Special internal-use-only method for use by JVM infrastructure
// that needs to wait() on a java-level object but that can't risk
// throwing unexpected InterruptedExecutionExceptions.
static void waitUninterruptibly(Handle obj, jlong Millis, Thread * THREAD);
static void wait_uninterruptibly(Handle obj, jlong Millis, Thread* THREAD);
// used by classloading to free classloader object lock,
// wait on an internal lock, and reclaim original lock
@ -93,14 +95,14 @@ class ObjectSynchronizer : AllStatic {
static intptr_t complete_exit(Handle obj, TRAPS);
static void reenter (Handle obj, intptr_t recursion, TRAPS);
// thread-specific and global objectMonitor free list accessors
static ObjectMonitor * omAlloc(Thread * Self);
static void omRelease(Thread * Self, ObjectMonitor * m,
bool FromPerThreadAlloc);
static void omFlush(Thread * Self);
// thread-specific and global ObjectMonitor free list accessors
static ObjectMonitor* om_alloc(Thread* self);
static void om_release(Thread* self, ObjectMonitor* m,
bool FromPerThreadAlloc);
static void om_flush(Thread* self);
// Inflate light weight monitor to heavy weight monitor
static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause);
static ObjectMonitor* inflate(Thread* self, oop obj, const InflateCause cause);
// This version is only for internal use
static void inflate_helper(oop obj);
static const char* inflate_cause_name(const InflateCause cause);
@ -108,11 +110,11 @@ class ObjectSynchronizer : AllStatic {
// Returns the identity hash value for an oop
// NOTE: It may cause monitor inflation
static intptr_t identity_hash_value_for(Handle obj);
static intptr_t FastHashCode(Thread * Self, oop obj);
static intptr_t FastHashCode(Thread* self, oop obj);
// java.lang.Thread support
static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
static LockOwnership query_lock_ownership(JavaThread * self, Handle h_obj);
static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj);
static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
@ -129,12 +131,12 @@ class ObjectSynchronizer : AllStatic {
static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
// For a given monitor list: global or per-thread, deflate idle monitors
static int deflate_monitor_list(ObjectMonitor** listheadp,
ObjectMonitor** freeHeadp,
ObjectMonitor** freeTailp);
static int deflate_monitor_list(ObjectMonitor** list_p,
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
static bool deflate_monitor(ObjectMonitor* mid, oop obj,
ObjectMonitor** freeHeadp,
ObjectMonitor** freeTailp);
ObjectMonitor** free_head_p,
ObjectMonitor** free_tail_p);
static bool is_cleanup_needed();
static void oops_do(OopClosure* f);
// Process oops in thread local used monitors
@ -142,13 +144,13 @@ class ObjectSynchronizer : AllStatic {
// debugging
static void audit_and_print_stats(bool on_exit);
static void chk_free_entry(JavaThread * jt, ObjectMonitor * n,
static void chk_free_entry(JavaThread* jt, ObjectMonitor* n,
outputStream * out, int *error_cnt_p);
static void chk_global_free_list_and_count(outputStream * out,
int *error_cnt_p);
static void chk_global_in_use_list_and_count(outputStream * out,
int *error_cnt_p);
static void chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
static void chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
outputStream * out, int *error_cnt_p);
static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
outputStream * out,
@ -165,14 +167,14 @@ class ObjectSynchronizer : AllStatic {
enum { _BLOCKSIZE = 128 };
// global list of blocks of monitors
static PaddedEnd<ObjectMonitor> * volatile gBlockList;
static PaddedObjectMonitor* volatile g_block_list;
// global monitor free list
static ObjectMonitor * volatile gFreeList;
static ObjectMonitor* volatile g_free_list;
// global monitor in-use list, for moribund threads,
// monitors they inflated need to be scanned for deflation
static ObjectMonitor * volatile gOmInUseList;
// count of entries in gOmInUseList
static int gOmInUseCount;
static ObjectMonitor* volatile g_om_in_use_list;
// count of entries in g_om_in_use_list
static int g_om_in_use_count;
// Process oops in all global used monitors (i.e. moribund thread's monitors)
static void global_used_oops_do(OopClosure* f);
@ -181,9 +183,9 @@ class ObjectSynchronizer : AllStatic {
// Support for SynchronizerTest access to GVars fields:
static u_char* get_gvars_addr();
static u_char* get_gvars_hcSequence_addr();
static u_char* get_gvars_hc_sequence_addr();
static size_t get_gvars_size();
static u_char* get_gvars_stwRandom_addr();
static u_char* get_gvars_stw_random_addr();
};
// ObjectLocker enforces balanced locking and can never throw an
@ -198,13 +200,13 @@ class ObjectLocker : public StackObj {
BasicLock _lock;
bool _dolock; // default true
public:
ObjectLocker(Handle obj, Thread* thread, bool doLock = true);
ObjectLocker(Handle obj, Thread* thread, bool do_lock = true);
~ObjectLocker();
// Monitor behavior
void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); }
void waitUninterruptibly(TRAPS) { ObjectSynchronizer::waitUninterruptibly(_obj, 0, CHECK); }
void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); }
// complete_exit gives up lock completely, returning recursion count
// reenter reclaims lock with original recursion count
intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); }

View File

@ -259,11 +259,11 @@ Thread::Thread() {
_current_pending_monitor_is_from_java = true;
_current_waiting_monitor = NULL;
_num_nested_signal = 0;
omFreeList = NULL;
omFreeCount = 0;
omFreeProvision = 32;
omInUseList = NULL;
omInUseCount = 0;
om_free_list = NULL;
om_free_count = 0;
om_free_provision = 32;
om_in_use_list = NULL;
om_in_use_count = 0;
#ifdef ASSERT
_visited_for_critical_count = false;
@ -4414,8 +4414,8 @@ void Threads::add(JavaThread* p, bool force_daemon) {
void Threads::remove(JavaThread* p, bool is_daemon) {
// Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
ObjectSynchronizer::omFlush(p);
// Reclaim the ObjectMonitors from the om_in_use_list and om_free_list of the moribund thread.
ObjectSynchronizer::om_flush(p);
// Extra scope needed for Thread_lock, so we can check
// that we do not remove thread without safepoint code notice

View File

@ -408,13 +408,13 @@ class Thread: public ThreadShadow {
// ObjectMonitor on which this thread called Object.wait()
ObjectMonitor* _current_waiting_monitor;
// Private thread-local objectmonitor list - a simple cache organized as a SLL.
// Per-thread ObjectMonitor lists:
public:
ObjectMonitor* omFreeList;
int omFreeCount; // length of omFreeList
int omFreeProvision; // reload chunk size
ObjectMonitor* omInUseList; // SLL to track monitors in circulation
int omInUseCount; // length of omInUseList
ObjectMonitor* om_free_list; // SLL of free ObjectMonitors
int om_free_count; // # on om_free_list
int om_free_provision; // # to try to allocate next
ObjectMonitor* om_in_use_list; // SLL of in-use ObjectMonitors
int om_in_use_count; // # on om_in_use_list
#ifdef ASSERT
private:
@ -522,7 +522,7 @@ class Thread: public ThreadShadow {
os::set_native_thread_name(name);
}
ObjectMonitor** omInUseList_addr() { return (ObjectMonitor **)&omInUseList; }
ObjectMonitor** om_in_use_list_addr() { return (ObjectMonitor **)&om_in_use_list; }
Monitor* SR_lock() const { return _SR_lock; }
bool has_async_exception() const { return (_suspend_flags & _has_async_exception) != 0; }

View File

@ -167,8 +167,6 @@ typedef Hashtable<intptr_t, mtInternal> IntptrHashtable;
typedef Hashtable<InstanceKlass*, mtClass> KlassHashtable;
typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
//--------------------------------------------------------------------------------
// VM_STRUCTS
//
@ -914,11 +912,11 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
volatile_nonstatic_field(ObjectMonitor, _contentions, jint) \
volatile_nonstatic_field(ObjectMonitor, _waiters, jint) \
volatile_nonstatic_field(ObjectMonitor, _recursions, intptr_t) \
nonstatic_field(ObjectMonitor, FreeNext, ObjectMonitor*) \
nonstatic_field(ObjectMonitor, _next_om, ObjectMonitor*) \
volatile_nonstatic_field(BasicLock, _displaced_header, markWord) \
nonstatic_field(BasicObjectLock, _lock, BasicLock) \
nonstatic_field(BasicObjectLock, _obj, oop) \
static_ptr_volatile_field(ObjectSynchronizer, gBlockList, PaddedObjectMonitor*) \
static_ptr_volatile_field(ObjectSynchronizer, g_block_list, PaddedObjectMonitor*) \
\
/*********************/ \
/* Matcher (C2 only) */ \

View File

@ -168,7 +168,7 @@ private:
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
// This macro generates a VMStructEntry line for a static pointer volatile field,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
// e.g.: "static ObjectMonitor * volatile g_block_list;"
#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
@ -202,7 +202,7 @@ private:
{type* dummy = &typeName::fieldName; }
// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
// e.g.: "static ObjectMonitor * volatile g_block_list;"
#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type volatile * dummy = &typeName::fieldName; }

View File

@ -48,8 +48,8 @@ public class ObjectMonitor extends VMObject {
objectFieldOffset = f.getOffset();
f = type.getField("_owner");
ownerFieldOffset = f.getOffset();
f = type.getField("FreeNext");
FreeNextFieldOffset = f.getOffset();
f = type.getField("_next_om");
nextOMFieldOffset = f.getOffset();
contentionsField = type.getJIntField("_contentions");
waitersField = type.getJIntField("_waiters");
recursionsField = type.getCIntegerField("_recursions");
@ -83,7 +83,7 @@ public class ObjectMonitor extends VMObject {
public int waiters() { return waitersField.getValue(addr); }
public Address freeNext() { return addr.getAddressAt(FreeNextFieldOffset); }
public Address nextOM() { return addr.getAddressAt(nextOMFieldOffset); }
// FIXME
// void set_queue(void* owner);
@ -108,7 +108,7 @@ public class ObjectMonitor extends VMObject {
private static long headerFieldOffset;
private static long objectFieldOffset;
private static long ownerFieldOffset;
private static long FreeNextFieldOffset;
private static long nextOMFieldOffset;
private static JIntField contentionsField;
private static JIntField waitersField;
private static CIntegerField recursionsField;

View File

@ -44,7 +44,7 @@ public class ObjectSynchronizer {
Type type;
try {
type = db.lookupType("ObjectSynchronizer");
gBlockList = type.getAddressField("gBlockList").getValue();
gBlockList = type.getAddressField("g_block_list").getValue();
blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
} catch (RuntimeException e) { }
@ -101,14 +101,14 @@ public class ObjectSynchronizer {
}
public boolean hasNext() {
return (index > 0 || block.freeNext() != null);
return (index > 0 || block.nextOM() != null);
}
public Object next() {
Address addr;
if (index == 0) {
// advance to next block
blockAddr = block.freeNext();
blockAddr = block.nextOM();
if (blockAddr == null) {
throw new NoSuchElementException();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,9 +30,9 @@
class SynchronizerTest : public ::testing::Test {
public:
static u_char* get_gvars_addr() { return ObjectSynchronizer::get_gvars_addr(); }
static u_char* get_gvars_hcSequence_addr() { return ObjectSynchronizer::get_gvars_hcSequence_addr(); }
static u_char* get_gvars_hc_sequence_addr() { return ObjectSynchronizer::get_gvars_hc_sequence_addr(); }
static size_t get_gvars_size() { return ObjectSynchronizer::get_gvars_size(); }
static u_char* get_gvars_stwRandom_addr() { return ObjectSynchronizer::get_gvars_stwRandom_addr(); }
static u_char* get_gvars_stw_random_addr() { return ObjectSynchronizer::get_gvars_stw_random_addr(); }
};
TEST_VM(SynchronizerTest, sanity) {
@ -42,27 +42,27 @@ TEST_VM(SynchronizerTest, sanity) {
// do some cache line specific sanity checks
u_char *addr_begin = SynchronizerTest::get_gvars_addr();
u_char *addr_stwRandom = SynchronizerTest::get_gvars_stwRandom_addr();
u_char *addr_hcSequence = SynchronizerTest::get_gvars_hcSequence_addr();
u_char *addr_stw_random = SynchronizerTest::get_gvars_stw_random_addr();
u_char *addr_hc_sequence = SynchronizerTest::get_gvars_hc_sequence_addr();
size_t gvars_size = SynchronizerTest::get_gvars_size();
uint offset_stwRandom = (uint) (addr_stwRandom - addr_begin);
uint offset_hcSequence = (uint) (addr_hcSequence - addr_begin);
uint offset_hcSequence_stwRandom = offset_hcSequence - offset_stwRandom;
uint offset_hcSequence_struct_end = (uint) gvars_size - offset_hcSequence;
uint offset_stw_random = (uint) (addr_stw_random - addr_begin);
uint offset_hc_sequence = (uint) (addr_hc_sequence - addr_begin);
uint offset_hc_sequence_stw_random = offset_hc_sequence - offset_stw_random;
uint offset_hc_sequence_struct_end = (uint) gvars_size - offset_hc_sequence;
EXPECT_GE(offset_stwRandom, cache_line_size)
<< "the SharedGlobals.stwRandom field is closer "
EXPECT_GE(offset_stw_random, cache_line_size)
<< "the SharedGlobals.stw_random field is closer "
<< "to the struct beginning than a cache line which permits "
<< "false sharing.";
EXPECT_GE(offset_hcSequence_stwRandom, cache_line_size)
<< "the SharedGlobals.stwRandom and "
<< "SharedGlobals.hcSequence fields are closer than a cache "
EXPECT_GE(offset_hc_sequence_stw_random, cache_line_size)
<< "the SharedGlobals.stw_random and "
<< "SharedGlobals.hc_sequence fields are closer than a cache "
<< "line which permits false sharing.";
EXPECT_GE(offset_hcSequence_struct_end, cache_line_size)
<< "the SharedGlobals.hcSequence field is closer "
EXPECT_GE(offset_hc_sequence_struct_end, cache_line_size)
<< "the SharedGlobals.hc_sequence field is closer "
<< "to the struct end than a cache line which permits false "
<< "sharing.";
}