8230184: rename, whitespace, indent and comments changes in preparation for lock free Monitor lists
Reviewed-by: kbarrett, dholmes
This commit is contained in:
parent
a2c067f6e8
commit
9b992ead1e
@ -946,7 +946,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
|
|||||||
while (is_being_initialized() && !is_reentrant_initialization(jt)) {
|
while (is_being_initialized() && !is_reentrant_initialization(jt)) {
|
||||||
wait = true;
|
wait = true;
|
||||||
jt->set_class_to_be_initialized(this);
|
jt->set_class_to_be_initialized(this);
|
||||||
ol.waitUninterruptibly(jt);
|
ol.wait_uninterruptibly(jt);
|
||||||
jt->set_class_to_be_initialized(NULL);
|
jt->set_class_to_be_initialized(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ class ObjectWaiter : public StackObj {
|
|||||||
public:
|
public:
|
||||||
enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
|
enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
|
||||||
enum Sorted { PREPEND, APPEND, SORTED };
|
enum Sorted { PREPEND, APPEND, SORTED };
|
||||||
ObjectWaiter * volatile _next;
|
ObjectWaiter* volatile _next;
|
||||||
ObjectWaiter * volatile _prev;
|
ObjectWaiter* volatile _prev;
|
||||||
Thread* _thread;
|
Thread* _thread;
|
||||||
jlong _notifier_tid;
|
jlong _notifier_tid;
|
||||||
ParkEvent * _event;
|
ParkEvent * _event;
|
||||||
@ -142,25 +142,35 @@ class ObjectMonitor {
|
|||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
JVMCI_ONLY(friend class JVMCIVMStructs;)
|
JVMCI_ONLY(friend class JVMCIVMStructs;)
|
||||||
|
|
||||||
volatile markWord _header; // displaced object header word - mark
|
// The sync code expects the header field to be at offset zero (0).
|
||||||
void* volatile _object; // backward object pointer - strong root
|
// Enforced by the assert() in header_addr().
|
||||||
|
volatile markWord _header; // displaced object header word - mark
|
||||||
|
void* volatile _object; // backward object pointer - strong root
|
||||||
public:
|
public:
|
||||||
ObjectMonitor* FreeNext; // Free list linkage
|
ObjectMonitor* _next_om; // Next ObjectMonitor* linkage
|
||||||
private:
|
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,
|
DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
|
||||||
sizeof(volatile markWord) + sizeof(void * volatile) +
|
sizeof(volatile markWord) + sizeof(void* volatile) +
|
||||||
sizeof(ObjectMonitor *));
|
sizeof(ObjectMonitor *));
|
||||||
protected: // protected for JvmtiRawMonitor
|
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 jlong _previous_owner_tid; // thread id of the previous owner of the monitor
|
||||||
volatile intptr_t _recursions; // recursion count, 0 for first entry
|
protected: // protected for JvmtiRawMonitor
|
||||||
ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
|
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,
|
// The list is actually composed of WaitNodes,
|
||||||
// acting as proxies for Threads.
|
// acting as proxies for Threads.
|
||||||
private:
|
private:
|
||||||
ObjectWaiter * volatile _cxq; // LL of recently-arrived threads blocked on entry.
|
ObjectWaiter* volatile _cxq; // LL of recently-arrived threads blocked on entry.
|
||||||
Thread * volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
|
Thread* volatile _succ; // Heir presumptive thread - used for futile wakeup throttling
|
||||||
Thread * volatile _Responsible;
|
Thread* volatile _Responsible;
|
||||||
|
|
||||||
volatile int _Spinner; // for exit->spinner handoff optimization
|
volatile int _Spinner; // for exit->spinner handoff optimization
|
||||||
volatile int _SpinDuration;
|
volatile int _SpinDuration;
|
||||||
@ -169,7 +179,7 @@ class ObjectMonitor {
|
|||||||
// along with other fields to determine if an ObjectMonitor can be
|
// along with other fields to determine if an ObjectMonitor can be
|
||||||
// deflated. See ObjectSynchronizer::deflate_monitor().
|
// deflated. See ObjectSynchronizer::deflate_monitor().
|
||||||
protected:
|
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
|
volatile jint _waiters; // number of waiting threads
|
||||||
private:
|
private:
|
||||||
volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
|
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 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);
|
void operator delete[] (void* p);
|
||||||
|
|
||||||
// TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
|
// TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
|
||||||
// ByteSize would also be an appropriate type.
|
// ByteSize would also be an appropriate type.
|
||||||
@ -256,7 +266,7 @@ class ObjectMonitor {
|
|||||||
protected:
|
protected:
|
||||||
// We don't typically expect or want the ctors or dtors to run.
|
// We don't typically expect or want the ctors or dtors to run.
|
||||||
// normal ObjectMonitors are type-stable and immortal.
|
// normal ObjectMonitors are type-stable and immortal.
|
||||||
ObjectMonitor() { ::memset((void *)this, 0, sizeof(*this)); }
|
ObjectMonitor() { ::memset((void*)this, 0, sizeof(*this)); }
|
||||||
|
|
||||||
~ObjectMonitor() {
|
~ObjectMonitor() {
|
||||||
// TODO: Add asserts ...
|
// TODO: Add asserts ...
|
||||||
@ -305,18 +315,18 @@ class ObjectMonitor {
|
|||||||
void reenter(intptr_t recursions, TRAPS);
|
void reenter(intptr_t recursions, TRAPS);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddWaiter(ObjectWaiter * waiter);
|
void AddWaiter(ObjectWaiter* waiter);
|
||||||
void INotify(Thread * Self);
|
void INotify(Thread* self);
|
||||||
ObjectWaiter * DequeueWaiter();
|
ObjectWaiter* DequeueWaiter();
|
||||||
void DequeueSpecificWaiter(ObjectWaiter * waiter);
|
void DequeueSpecificWaiter(ObjectWaiter* waiter);
|
||||||
void EnterI(TRAPS);
|
void EnterI(TRAPS);
|
||||||
void ReenterI(Thread * Self, ObjectWaiter * SelfNode);
|
void ReenterI(Thread* self, ObjectWaiter* self_node);
|
||||||
void UnlinkAfterAcquire(Thread * Self, ObjectWaiter * SelfNode);
|
void UnlinkAfterAcquire(Thread* self, ObjectWaiter* self_node);
|
||||||
int TryLock(Thread * Self);
|
int TryLock(Thread* self);
|
||||||
int NotRunnable(Thread * Self, Thread * Owner);
|
int NotRunnable(Thread* self, Thread * Owner);
|
||||||
int TrySpin(Thread * Self);
|
int TrySpin(Thread* self);
|
||||||
void ExitEpilog(Thread * Self, ObjectWaiter * Wakee);
|
void ExitEpilog(Thread* self, ObjectWaiter* Wakee);
|
||||||
bool ExitSuspendEquivalent(JavaThread * Self);
|
bool ExitSuspendEquivalent(JavaThread* self);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
||||||
|
@ -128,8 +128,8 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
|
|||||||
(symboltable_work = SymbolTable::has_work()) |
|
(symboltable_work = SymbolTable::has_work()) |
|
||||||
(resolved_method_table_work = ResolvedMethodTable::has_work()) |
|
(resolved_method_table_work = ResolvedMethodTable::has_work()) |
|
||||||
(protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
|
(protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
|
||||||
(oopstorage_work = OopStorage::has_cleanup_work_and_reset()))
|
(oopstorage_work = OopStorage::has_cleanup_work_and_reset())
|
||||||
== 0) {
|
) == 0) {
|
||||||
// Wait until notified that there is some work to do.
|
// Wait until notified that there is some work to do.
|
||||||
ml.wait();
|
ml.wait();
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -34,12 +34,14 @@
|
|||||||
class ObjectMonitor;
|
class ObjectMonitor;
|
||||||
class ThreadsList;
|
class ThreadsList;
|
||||||
|
|
||||||
|
typedef PaddedEnd<ObjectMonitor, DEFAULT_CACHE_LINE_SIZE> PaddedObjectMonitor;
|
||||||
|
|
||||||
struct DeflateMonitorCounters {
|
struct DeflateMonitorCounters {
|
||||||
int nInuse; // currently associated with objects
|
int n_in_use; // currently associated with objects
|
||||||
int nInCirculation; // extant
|
int n_in_circulation; // extant
|
||||||
int nScavenged; // reclaimed (global and per-thread)
|
int n_scavenged; // reclaimed (global and per-thread)
|
||||||
int perThreadScavenged; // per-thread scavenge total
|
int per_thread_scavenged; // per-thread scavenge total
|
||||||
double perThreadTimes; // per-thread scavenge times
|
double per_thread_times; // per-thread scavenge times
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectSynchronizer : AllStatic {
|
class ObjectSynchronizer : AllStatic {
|
||||||
@ -79,13 +81,13 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
static void notify(Handle obj, TRAPS);
|
static void notify(Handle obj, TRAPS);
|
||||||
static void notifyall(Handle obj, TRAPS);
|
static void notifyall(Handle obj, TRAPS);
|
||||||
|
|
||||||
static bool quick_notify(oopDesc* obj, Thread* Self, bool All);
|
static bool quick_notify(oopDesc* obj, Thread* self, bool All);
|
||||||
static bool quick_enter(oop obj, Thread* Self, BasicLock* Lock);
|
static bool quick_enter(oop obj, Thread* self, BasicLock* Lock);
|
||||||
|
|
||||||
// Special internal-use-only method for use by JVM infrastructure
|
// Special internal-use-only method for use by JVM infrastructure
|
||||||
// that needs to wait() on a java-level object but that can't risk
|
// that needs to wait() on a java-level object but that can't risk
|
||||||
// throwing unexpected InterruptedExecutionExceptions.
|
// 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,
|
// used by classloading to free classloader object lock,
|
||||||
// wait on an internal lock, and reclaim original 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 intptr_t complete_exit(Handle obj, TRAPS);
|
||||||
static void reenter (Handle obj, intptr_t recursion, TRAPS);
|
static void reenter (Handle obj, intptr_t recursion, TRAPS);
|
||||||
|
|
||||||
// thread-specific and global objectMonitor free list accessors
|
// thread-specific and global ObjectMonitor free list accessors
|
||||||
static ObjectMonitor * omAlloc(Thread * Self);
|
static ObjectMonitor* om_alloc(Thread* self);
|
||||||
static void omRelease(Thread * Self, ObjectMonitor * m,
|
static void om_release(Thread* self, ObjectMonitor* m,
|
||||||
bool FromPerThreadAlloc);
|
bool FromPerThreadAlloc);
|
||||||
static void omFlush(Thread * Self);
|
static void om_flush(Thread* self);
|
||||||
|
|
||||||
// Inflate light weight monitor to heavy weight monitor
|
// 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
|
// This version is only for internal use
|
||||||
static void inflate_helper(oop obj);
|
static void inflate_helper(oop obj);
|
||||||
static const char* inflate_cause_name(const InflateCause cause);
|
static const char* inflate_cause_name(const InflateCause cause);
|
||||||
@ -108,11 +110,11 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
// Returns the identity hash value for an oop
|
// Returns the identity hash value for an oop
|
||||||
// NOTE: It may cause monitor inflation
|
// NOTE: It may cause monitor inflation
|
||||||
static intptr_t identity_hash_value_for(Handle obj);
|
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
|
// java.lang.Thread support
|
||||||
static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
|
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);
|
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);
|
static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
|
||||||
|
|
||||||
// For a given monitor list: global or per-thread, deflate idle monitors
|
// For a given monitor list: global or per-thread, deflate idle monitors
|
||||||
static int deflate_monitor_list(ObjectMonitor** listheadp,
|
static int deflate_monitor_list(ObjectMonitor** list_p,
|
||||||
ObjectMonitor** freeHeadp,
|
ObjectMonitor** free_head_p,
|
||||||
ObjectMonitor** freeTailp);
|
ObjectMonitor** free_tail_p);
|
||||||
static bool deflate_monitor(ObjectMonitor* mid, oop obj,
|
static bool deflate_monitor(ObjectMonitor* mid, oop obj,
|
||||||
ObjectMonitor** freeHeadp,
|
ObjectMonitor** free_head_p,
|
||||||
ObjectMonitor** freeTailp);
|
ObjectMonitor** free_tail_p);
|
||||||
static bool is_cleanup_needed();
|
static bool is_cleanup_needed();
|
||||||
static void oops_do(OopClosure* f);
|
static void oops_do(OopClosure* f);
|
||||||
// Process oops in thread local used monitors
|
// Process oops in thread local used monitors
|
||||||
@ -142,13 +144,13 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
static void audit_and_print_stats(bool on_exit);
|
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);
|
outputStream * out, int *error_cnt_p);
|
||||||
static void chk_global_free_list_and_count(outputStream * out,
|
static void chk_global_free_list_and_count(outputStream * out,
|
||||||
int *error_cnt_p);
|
int *error_cnt_p);
|
||||||
static void chk_global_in_use_list_and_count(outputStream * out,
|
static void chk_global_in_use_list_and_count(outputStream * out,
|
||||||
int *error_cnt_p);
|
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);
|
outputStream * out, int *error_cnt_p);
|
||||||
static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
|
static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
|
||||||
outputStream * out,
|
outputStream * out,
|
||||||
@ -165,14 +167,14 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
|
|
||||||
enum { _BLOCKSIZE = 128 };
|
enum { _BLOCKSIZE = 128 };
|
||||||
// global list of blocks of monitors
|
// global list of blocks of monitors
|
||||||
static PaddedEnd<ObjectMonitor> * volatile gBlockList;
|
static PaddedObjectMonitor* volatile g_block_list;
|
||||||
// global monitor free list
|
// global monitor free list
|
||||||
static ObjectMonitor * volatile gFreeList;
|
static ObjectMonitor* volatile g_free_list;
|
||||||
// global monitor in-use list, for moribund threads,
|
// global monitor in-use list, for moribund threads,
|
||||||
// monitors they inflated need to be scanned for deflation
|
// monitors they inflated need to be scanned for deflation
|
||||||
static ObjectMonitor * volatile gOmInUseList;
|
static ObjectMonitor* volatile g_om_in_use_list;
|
||||||
// count of entries in gOmInUseList
|
// count of entries in g_om_in_use_list
|
||||||
static int gOmInUseCount;
|
static int g_om_in_use_count;
|
||||||
|
|
||||||
// Process oops in all global used monitors (i.e. moribund thread's monitors)
|
// Process oops in all global used monitors (i.e. moribund thread's monitors)
|
||||||
static void global_used_oops_do(OopClosure* f);
|
static void global_used_oops_do(OopClosure* f);
|
||||||
@ -181,9 +183,9 @@ class ObjectSynchronizer : AllStatic {
|
|||||||
|
|
||||||
// Support for SynchronizerTest access to GVars fields:
|
// Support for SynchronizerTest access to GVars fields:
|
||||||
static u_char* get_gvars_addr();
|
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 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
|
// ObjectLocker enforces balanced locking and can never throw an
|
||||||
@ -198,13 +200,13 @@ class ObjectLocker : public StackObj {
|
|||||||
BasicLock _lock;
|
BasicLock _lock;
|
||||||
bool _dolock; // default true
|
bool _dolock; // default true
|
||||||
public:
|
public:
|
||||||
ObjectLocker(Handle obj, Thread* thread, bool doLock = true);
|
ObjectLocker(Handle obj, Thread* thread, bool do_lock = true);
|
||||||
~ObjectLocker();
|
~ObjectLocker();
|
||||||
|
|
||||||
// Monitor behavior
|
// Monitor behavior
|
||||||
void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
|
void wait(TRAPS) { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
|
||||||
void notify_all(TRAPS) { ObjectSynchronizer::notifyall(_obj, CHECK); }
|
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
|
// complete_exit gives up lock completely, returning recursion count
|
||||||
// reenter reclaims lock with original recursion count
|
// reenter reclaims lock with original recursion count
|
||||||
intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
|
intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
|
||||||
|
@ -259,11 +259,11 @@ Thread::Thread() {
|
|||||||
_current_pending_monitor_is_from_java = true;
|
_current_pending_monitor_is_from_java = true;
|
||||||
_current_waiting_monitor = NULL;
|
_current_waiting_monitor = NULL;
|
||||||
_num_nested_signal = 0;
|
_num_nested_signal = 0;
|
||||||
omFreeList = NULL;
|
om_free_list = NULL;
|
||||||
omFreeCount = 0;
|
om_free_count = 0;
|
||||||
omFreeProvision = 32;
|
om_free_provision = 32;
|
||||||
omInUseList = NULL;
|
om_in_use_list = NULL;
|
||||||
omInUseCount = 0;
|
om_in_use_count = 0;
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
_visited_for_critical_count = false;
|
_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) {
|
void Threads::remove(JavaThread* p, bool is_daemon) {
|
||||||
|
|
||||||
// Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
|
// Reclaim the ObjectMonitors from the om_in_use_list and om_free_list of the moribund thread.
|
||||||
ObjectSynchronizer::omFlush(p);
|
ObjectSynchronizer::om_flush(p);
|
||||||
|
|
||||||
// Extra scope needed for Thread_lock, so we can check
|
// Extra scope needed for Thread_lock, so we can check
|
||||||
// that we do not remove thread without safepoint code notice
|
// that we do not remove thread without safepoint code notice
|
||||||
|
@ -408,13 +408,13 @@ class Thread: public ThreadShadow {
|
|||||||
// ObjectMonitor on which this thread called Object.wait()
|
// ObjectMonitor on which this thread called Object.wait()
|
||||||
ObjectMonitor* _current_waiting_monitor;
|
ObjectMonitor* _current_waiting_monitor;
|
||||||
|
|
||||||
// Private thread-local objectmonitor list - a simple cache organized as a SLL.
|
// Per-thread ObjectMonitor lists:
|
||||||
public:
|
public:
|
||||||
ObjectMonitor* omFreeList;
|
ObjectMonitor* om_free_list; // SLL of free ObjectMonitors
|
||||||
int omFreeCount; // length of omFreeList
|
int om_free_count; // # on om_free_list
|
||||||
int omFreeProvision; // reload chunk size
|
int om_free_provision; // # to try to allocate next
|
||||||
ObjectMonitor* omInUseList; // SLL to track monitors in circulation
|
ObjectMonitor* om_in_use_list; // SLL of in-use ObjectMonitors
|
||||||
int omInUseCount; // length of omInUseList
|
int om_in_use_count; // # on om_in_use_list
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
private:
|
private:
|
||||||
@ -522,7 +522,7 @@ class Thread: public ThreadShadow {
|
|||||||
os::set_native_thread_name(name);
|
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; }
|
Monitor* SR_lock() const { return _SR_lock; }
|
||||||
|
|
||||||
bool has_async_exception() const { return (_suspend_flags & _has_async_exception) != 0; }
|
bool has_async_exception() const { return (_suspend_flags & _has_async_exception) != 0; }
|
||||||
|
@ -167,8 +167,6 @@ typedef Hashtable<intptr_t, mtInternal> IntptrHashtable;
|
|||||||
typedef Hashtable<InstanceKlass*, mtClass> KlassHashtable;
|
typedef Hashtable<InstanceKlass*, mtClass> KlassHashtable;
|
||||||
typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||||
|
|
||||||
typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
// VM_STRUCTS
|
// VM_STRUCTS
|
||||||
//
|
//
|
||||||
@ -914,11 +912,11 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|||||||
volatile_nonstatic_field(ObjectMonitor, _contentions, jint) \
|
volatile_nonstatic_field(ObjectMonitor, _contentions, jint) \
|
||||||
volatile_nonstatic_field(ObjectMonitor, _waiters, jint) \
|
volatile_nonstatic_field(ObjectMonitor, _waiters, jint) \
|
||||||
volatile_nonstatic_field(ObjectMonitor, _recursions, intptr_t) \
|
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) \
|
volatile_nonstatic_field(BasicLock, _displaced_header, markWord) \
|
||||||
nonstatic_field(BasicObjectLock, _lock, BasicLock) \
|
nonstatic_field(BasicObjectLock, _lock, BasicLock) \
|
||||||
nonstatic_field(BasicObjectLock, _obj, oop) \
|
nonstatic_field(BasicObjectLock, _obj, oop) \
|
||||||
static_ptr_volatile_field(ObjectSynchronizer, gBlockList, PaddedObjectMonitor*) \
|
static_ptr_volatile_field(ObjectSynchronizer, g_block_list, PaddedObjectMonitor*) \
|
||||||
\
|
\
|
||||||
/*********************/ \
|
/*********************/ \
|
||||||
/* Matcher (C2 only) */ \
|
/* Matcher (C2 only) */ \
|
||||||
|
@ -168,7 +168,7 @@ private:
|
|||||||
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
|
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
|
||||||
|
|
||||||
// This macro generates a VMStructEntry line for a static pointer volatile field,
|
// 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) \
|
#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
|
||||||
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
|
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ private:
|
|||||||
{type* dummy = &typeName::fieldName; }
|
{type* dummy = &typeName::fieldName; }
|
||||||
|
|
||||||
// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
|
// 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) \
|
#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
|
||||||
{type volatile * dummy = &typeName::fieldName; }
|
{type volatile * dummy = &typeName::fieldName; }
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ public class ObjectMonitor extends VMObject {
|
|||||||
objectFieldOffset = f.getOffset();
|
objectFieldOffset = f.getOffset();
|
||||||
f = type.getField("_owner");
|
f = type.getField("_owner");
|
||||||
ownerFieldOffset = f.getOffset();
|
ownerFieldOffset = f.getOffset();
|
||||||
f = type.getField("FreeNext");
|
f = type.getField("_next_om");
|
||||||
FreeNextFieldOffset = f.getOffset();
|
nextOMFieldOffset = f.getOffset();
|
||||||
contentionsField = type.getJIntField("_contentions");
|
contentionsField = type.getJIntField("_contentions");
|
||||||
waitersField = type.getJIntField("_waiters");
|
waitersField = type.getJIntField("_waiters");
|
||||||
recursionsField = type.getCIntegerField("_recursions");
|
recursionsField = type.getCIntegerField("_recursions");
|
||||||
@ -83,7 +83,7 @@ public class ObjectMonitor extends VMObject {
|
|||||||
|
|
||||||
public int waiters() { return waitersField.getValue(addr); }
|
public int waiters() { return waitersField.getValue(addr); }
|
||||||
|
|
||||||
public Address freeNext() { return addr.getAddressAt(FreeNextFieldOffset); }
|
public Address nextOM() { return addr.getAddressAt(nextOMFieldOffset); }
|
||||||
// FIXME
|
// FIXME
|
||||||
// void set_queue(void* owner);
|
// void set_queue(void* owner);
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ public class ObjectMonitor extends VMObject {
|
|||||||
private static long headerFieldOffset;
|
private static long headerFieldOffset;
|
||||||
private static long objectFieldOffset;
|
private static long objectFieldOffset;
|
||||||
private static long ownerFieldOffset;
|
private static long ownerFieldOffset;
|
||||||
private static long FreeNextFieldOffset;
|
private static long nextOMFieldOffset;
|
||||||
private static JIntField contentionsField;
|
private static JIntField contentionsField;
|
||||||
private static JIntField waitersField;
|
private static JIntField waitersField;
|
||||||
private static CIntegerField recursionsField;
|
private static CIntegerField recursionsField;
|
||||||
|
@ -44,7 +44,7 @@ public class ObjectSynchronizer {
|
|||||||
Type type;
|
Type type;
|
||||||
try {
|
try {
|
||||||
type = db.lookupType("ObjectSynchronizer");
|
type = db.lookupType("ObjectSynchronizer");
|
||||||
gBlockList = type.getAddressField("gBlockList").getValue();
|
gBlockList = type.getAddressField("g_block_list").getValue();
|
||||||
blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
|
blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
|
||||||
defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
|
defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
|
||||||
} catch (RuntimeException e) { }
|
} catch (RuntimeException e) { }
|
||||||
@ -101,14 +101,14 @@ public class ObjectSynchronizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return (index > 0 || block.freeNext() != null);
|
return (index > 0 || block.nextOM() != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next() {
|
public Object next() {
|
||||||
Address addr;
|
Address addr;
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
// advance to next block
|
// advance to next block
|
||||||
blockAddr = block.freeNext();
|
blockAddr = block.nextOM();
|
||||||
if (blockAddr == null) {
|
if (blockAddr == null) {
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,9 +30,9 @@
|
|||||||
class SynchronizerTest : public ::testing::Test {
|
class SynchronizerTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
static u_char* get_gvars_addr() { return ObjectSynchronizer::get_gvars_addr(); }
|
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 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) {
|
TEST_VM(SynchronizerTest, sanity) {
|
||||||
@ -42,27 +42,27 @@ TEST_VM(SynchronizerTest, sanity) {
|
|||||||
// do some cache line specific sanity checks
|
// do some cache line specific sanity checks
|
||||||
|
|
||||||
u_char *addr_begin = SynchronizerTest::get_gvars_addr();
|
u_char *addr_begin = SynchronizerTest::get_gvars_addr();
|
||||||
u_char *addr_stwRandom = SynchronizerTest::get_gvars_stwRandom_addr();
|
u_char *addr_stw_random = SynchronizerTest::get_gvars_stw_random_addr();
|
||||||
u_char *addr_hcSequence = SynchronizerTest::get_gvars_hcSequence_addr();
|
u_char *addr_hc_sequence = SynchronizerTest::get_gvars_hc_sequence_addr();
|
||||||
size_t gvars_size = SynchronizerTest::get_gvars_size();
|
size_t gvars_size = SynchronizerTest::get_gvars_size();
|
||||||
|
|
||||||
uint offset_stwRandom = (uint) (addr_stwRandom - addr_begin);
|
uint offset_stw_random = (uint) (addr_stw_random - addr_begin);
|
||||||
uint offset_hcSequence = (uint) (addr_hcSequence - addr_begin);
|
uint offset_hc_sequence = (uint) (addr_hc_sequence - addr_begin);
|
||||||
uint offset_hcSequence_stwRandom = offset_hcSequence - offset_stwRandom;
|
uint offset_hc_sequence_stw_random = offset_hc_sequence - offset_stw_random;
|
||||||
uint offset_hcSequence_struct_end = (uint) gvars_size - offset_hcSequence;
|
uint offset_hc_sequence_struct_end = (uint) gvars_size - offset_hc_sequence;
|
||||||
|
|
||||||
EXPECT_GE(offset_stwRandom, cache_line_size)
|
EXPECT_GE(offset_stw_random, cache_line_size)
|
||||||
<< "the SharedGlobals.stwRandom field is closer "
|
<< "the SharedGlobals.stw_random field is closer "
|
||||||
<< "to the struct beginning than a cache line which permits "
|
<< "to the struct beginning than a cache line which permits "
|
||||||
<< "false sharing.";
|
<< "false sharing.";
|
||||||
|
|
||||||
EXPECT_GE(offset_hcSequence_stwRandom, cache_line_size)
|
EXPECT_GE(offset_hc_sequence_stw_random, cache_line_size)
|
||||||
<< "the SharedGlobals.stwRandom and "
|
<< "the SharedGlobals.stw_random and "
|
||||||
<< "SharedGlobals.hcSequence fields are closer than a cache "
|
<< "SharedGlobals.hc_sequence fields are closer than a cache "
|
||||||
<< "line which permits false sharing.";
|
<< "line which permits false sharing.";
|
||||||
|
|
||||||
EXPECT_GE(offset_hcSequence_struct_end, cache_line_size)
|
EXPECT_GE(offset_hc_sequence_struct_end, cache_line_size)
|
||||||
<< "the SharedGlobals.hcSequence field is closer "
|
<< "the SharedGlobals.hc_sequence field is closer "
|
||||||
<< "to the struct end than a cache line which permits false "
|
<< "to the struct end than a cache line which permits false "
|
||||||
<< "sharing.";
|
<< "sharing.";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user