51 #if defined(ENABLE_JVMTI)
55 #if defined(ENABLE_GC_BOEHM)
56 # include "mm/boehm-gc/include/gc.h"
62 # define DEBUGLOCKS(format) \
64 if (opt_DebugLocks) { \
69 # define DEBUGLOCKS(format)
81 #define LOCK_INITIAL_LOCK_RECORDS 8
83 #define LOCK_INITIAL_HASHTABLE_SIZE 1613
185 #if defined(ENABLE_GC_CACAO)
194 DEBUGLOCKS((
"[lock_record_new : lr=%p]", (
void *) lr));
211 DEBUGLOCKS((
"[lock_record_free : lr=%p]", (
void *) lr));
216 #if defined(ENABLE_GC_CACAO)
279 oldsize = lock_hashtable.
size;
280 newsize = oldsize*2 + 1;
282 DEBUGLOCKS((
"growing lock hashtable to size %d", newsize));
284 oldtable = lock_hashtable.
ptr;
293 for (i = 0; i < oldsize; i++) {
299 newslot = h % newsize;
302 newtable[newslot] =
lr;
310 lock_hashtable.
ptr = newtable;
311 lock_hashtable.
size = newsize;
326 #if defined(ENABLE_GC_CACAO)
327 void lock_hashtable_cleanup(
void)
339 Mutex_lock(lock_hashtable.
mutex);
343 for (i = 0; i < lock_hashtable.
size; i++) {
344 lr = lock_hashtable.
ptr[
i];
375 Mutex_unlock(lock_hashtable.
mutex);
393 #if defined(ENABLE_GC_BOEHM)
424 for (; lr != NULL; lr = lr->
hashlink) {
436 #if defined(ENABLE_GC_BOEHM)
450 if (lock_hashtable.
entries * 3 > lock_hashtable.
size * 4) {
496 tmplr = lock_hashtable.
ptr[
slot];
504 for (; tmplr != NULL; tmplr = tmplr->
hashlink) {
511 assert(tmplr != NULL);
533 #define DEBUG_NAME "finalizer"
537 #if defined(ENABLE_LOGGING)
542 LOG(
"[finalizer lockrecord:"
572 #if defined(ENABLE_GC_CACAO)
749 DEBUGLOCKS((
"thread %d inflating lock of %p to lr %p",
803 uintptr_t lw_cache = *lw_ptr;
807 if (result ==
true) {
810 #if defined(CAS_PROVIDES_FULL_BARRIER) && CAS_PROVIDES_FULL_BARRIER
852 if (lr->
owner == t) {
861 assert(lr->
count == 0);
867 #if defined(ENABLE_JVMTI)
874 #if defined(ENABLE_JVMTI)
917 uintptr_t lw_cache = *lw_ptr;
953 if (lr->
owner != t) {
960 if (lr->
count != 0) {
1044 bool wasinterrupted =
false;
1046 DEBUGLOCKS((
"[lock_record_wait : lr=%p, t=%p, millis=%lld, nanos=%d]",
1047 lr, thread, millis, nanos));
1057 lockcount = lr->
count;
1078 lr->
count = lockcount;
1093 return wasinterrupted;
1117 uintptr_t lw_cache = *lw_ptr;
1126 if (lr->
owner != t) {
1172 #if defined(ENABLE_GC_CACAO)
1190 DEBUGLOCKS((
"[lock_record_notify: lr=%p, t=%p, waitingthread=%p, one=%d]", lr, t, waiter, one));
1240 if (lr->
owner != t) {
1295 return (lr->
owner == t);
void write_memory_barrier(void)
jlong jlong jlong jlong jint jmethodID jint slot
#define STATISTICS(x)
Wrapper for statistics only code.
static void lock_hashtable_grow(void)
void exceptions_throw_illegalmonitorstateexception(void)
void gc_weakreference_unregister(java_object_t **ref)
void signal()
Restarts one of the threads that are waiting on this condition variable.
static void notify_flc_waiters(threadobject *t, java_handle_t *o)
threadobject * get_thread_by_index(int32_t index)
Return the thread object with the given index.
static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 nanos)
void unlock()
Set the lockword to THIN_UNLOCKED.
void exceptions_throw_interruptedexception(void)
struct threadobject * flc_list
bool lock_monitor_exit(java_handle_t *o)
static void lock_hashtable_init(void)
void gc_weakreference_register(java_object_t **ref, int32_t reftype)
static void lock_record_finalizer(java_handle_t *object, void *p)
struct threadobject * owner
void decrease_thin_lock_count()
Dummy implementation of a mutex.
int32_t get_thin_lock_thread_index() const
static int32_t heap_hashcode(java_object_t *obj)
List< threadobject * > * waiters
static void lock_inflate(java_handle_t *o, lock_record_t *lr)
static void lock_record_remove_waiter(lock_record_t *lr, threadobject *t)
static void * attach_custom_finalizer(java_handle_t *h, FinalizerFunc f, void *data)
static lock_hashtable_t lock_hashtable
struct threadobject * flc_next
static void lock_record_add_waiter(lock_record_t *lr, threadobject *t)
#define MZERO(ptr, type, num)
static lock_record_t * lock_record_new(void)
static bool inside()
Checks if the calling thread is inside a GC critical section.
MachineBasicBlock * current
void jvmti_MonitorContendedEntering(bool entered, jobject obj)
static void lock_record_free(lock_record_t *lr)
#define LLNI_class_get(obj, variable)
void lock_notify_all_object(java_handle_t *o)
static void lock_record_enter(threadobject *t, lock_record_t *lr)
static void lock_record_notify(threadobject *t, lock_record_t *lr, bool one)
static ThreadList * get()
Provides access to singleton.
Critical section for the GC.
uintptr_t get_thin_lock_without_count() const
bool lock(uintptr_t thinlock)
Try to lock the lockword with the given thin-lock value.
bool is_thin_lock() const
void lock_notify_object(java_handle_t *o)
void exceptions_throw_nullpointerexception(void)
void increase_thin_lock_count()
void threads_wait_with_timeout_relative(threadobject *thread, s8 millis, s4 nanos)
bool is_max_thin_lock_count() const
static uintptr_t * lock_lockword_get(java_handle_t *o)
void broadcast()
Restarts all the threads that are waiting on the condition variable.
struct threadobject * flc_tail
void lock_wait_for_object(java_handle_t *o, s8 millis, s4 nanos)
java_handle_t * flc_object
#define LOG(STMT)
Analogous to DEBUG.
static void lock_record_exit(threadobject *t, lock_record_t *lr)
static threadobject * thread_get_current()
Return the threadobject for the current thread.
void memory_barrier(void)
#define LOCK_INITIAL_HASHTABLE_SIZE
static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one)
bool lock_is_held_by_current_thread(java_handle_t *o)
#define DEBUGLOCKS(format)
void unlock()
Unlocks the given mutex object and checks for errors.
static void sable_flc_waiting(uintptr_t lw_cache, threadobject *t, java_handle_t *o)
static lock_record_t * lock_hashtable_get(java_handle_t *o)
static java_object_t * next
bool lock_monitor_enter(java_handle_t *o)
static bool lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 nanos)
void inflate(struct lock_record_t *lr)
Inflate the lock of the given object.
#define STAT_DECLARE_VAR(type, var, init)
Declare an external statistics variable.
static void lock_hashtable_remove(threadobject *t, java_handle_t *o)
void instruction_barrier(void)
struct lock_record_t * get_fat_lock() const
#define MFREE(ptr, type, num)
void wait(Mutex *mutex)
Waits for the condition variable.
void lock()
Locks the given mutex object and checks for errors.
uintptr_t get_thin_lock() const