From: Stefan Ring Date: Mon, 13 Sep 2010 09:43:40 +0000 (+0200) Subject: * src/vm/global.h: Made 'lockword' member of java_object_t a plain X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=fa8651a5a680d2f25e03d6df5fd275e70d5cc696 * src/vm/global.h: Made 'lockword' member of java_object_t a plain integer type because offsetof works only on POD structs (and gcc complains about that). * src/threads/lockword.hpp: Lockword references its data member now instead of containing it. * src/threads/lock.cpp: Adapted to new Lockword signature. * src/vm/array.hpp: Likewise. * src/vm/class.cpp: Likewise. * src/vm/jit/builtin.cpp: Likewise. * src/vm/string.cpp: Likewise. --- diff --git a/src/threads/lock.cpp b/src/threads/lock.cpp index 140905e2b..87851a731 100644 --- a/src/threads/lock.cpp +++ b/src/threads/lock.cpp @@ -1,6 +1,6 @@ /* src/threads/lock.cpp - lock implementation - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -143,7 +143,7 @@ static lock_hashtable_t lock_hashtable; static void lock_hashtable_init(void); -static inline Lockword* lock_lockword_get(java_handle_t* o); +static inline uintptr_t* lock_lockword_get(java_handle_t* o); static void lock_record_enter(threadobject *t, lock_record_t *lr); static void lock_record_exit(threadobject *t, lock_record_t *lr); static bool lock_record_wait(threadobject *t, lock_record_t *lr, s8 millis, s4 nanos); @@ -431,10 +431,16 @@ static lock_record_t *lock_hashtable_get(java_handle_t* o) u4 slot; lock_record_t *lr; - Lockword* lockword = lock_lockword_get(o); + // lw_cache is used throughout this file because the lockword can change at + // any time, unless it is absolutely certain that we are holding the lock. + // We don't do deflation, so we would also not expect a fat lockword to + // change, but for the sake of uniformity, lw_cache is used even in this + // case. + uintptr_t lw_cache = *lock_lockword_get(o); + Lockword lockword(lw_cache); - if (lockword->is_fat_lock()) - return lockword->get_fat_lock(); + if (lockword.is_fat_lock()) + return lockword.get_fat_lock(); // Lock the hashtable. lock_hashtable.mutex->lock(); @@ -503,8 +509,8 @@ static lock_record_t *lock_hashtable_get(java_handle_t* o) #if defined(ENABLE_GC_BOEHM) void lock_schedule_lockrecord_removal(java_handle_t *o) { - Lockword* lockword = lock_lockword_get(o); - if (!lockword->is_fat_lock()) + Lockword lockword(*lock_lockword_get(o)); + if (!lockword.is_fat_lock()) /* there is no lock record */ return; @@ -536,12 +542,13 @@ static void lock_hashtable_remove(threadobject *t, java_handle_t *o) /* get lock record */ - Lockword* lockword = lock_lockword_get(o); + uintptr_t lw_cache = *lock_lockword_get(o); + Lockword lockword(lw_cache); // Sanity check. - assert(lockword->is_fat_lock()); + assert(lockword.is_fat_lock()); - lr = lockword->get_fat_lock(); + lr = lockword.get_fat_lock(); /* remove the lock-record from the hashtable */ @@ -628,7 +635,7 @@ static void lock_record_finalizer(void *object, void *p) *******************************************************************************/ -static inline Lockword* lock_lockword_get(java_handle_t* o) +static inline uintptr_t* lock_lockword_get(java_handle_t* o) { #if defined(ENABLE_GC_CACAO) // Sanity check. @@ -695,8 +702,8 @@ static inline void lock_record_exit(threadobject *t, lock_record_t *lr) static void lock_inflate(java_handle_t *o, lock_record_t *lr) { - Lockword* lockword = lock_lockword_get(o); - lockword->inflate(lr); + Lockword lockword(*lock_lockword_get(o)); + lockword.inflate(lr); } @@ -716,13 +723,14 @@ static void lock_inflate(java_handle_t *o, lock_record_t *lr) *******************************************************************************/ -static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t *o) +static void sable_flc_waiting(uintptr_t lw_cache, threadobject *t, java_handle_t *o) { int32_t index; threadobject *t_other; int old_flc; - index = lockword->get_thin_lock_thread_index(); + Lockword lockword(lw_cache); + index = lockword.get_thin_lock_thread_index(); t_other = ThreadList::get_thread_by_index(index); // The lockword could have changed during our way here. If the @@ -741,10 +749,10 @@ static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t // Set FLC bit first, then read the lockword again. Atomic::memory_barrier(); - lockword = lock_lockword_get(o); + lw_cache = *lock_lockword_get(o); /* Lockword is still the way it was seen before */ - if (lockword->is_thin_lock() && (lockword->get_thin_lock_thread_index() == index)) + if (lockword.is_thin_lock() && (lockword.get_thin_lock_thread_index() == index)) { threadobject *f; /* Add tuple (t, o) to the other thread's FLC list */ @@ -801,8 +809,8 @@ static void notify_flc_waiters(threadobject *t, java_handle_t *o) block on it. */ // Only if not already inflated. - Lockword* lockword = lock_lockword_get(current->flc_object); - if (lockword->is_thin_lock()) { + Lockword lockword(*lock_lockword_get(current->flc_object)); + if (lockword.is_thin_lock()) { lock_record_t *lr = lock_hashtable_get(current->flc_object); lock_record_enter(t, lr); @@ -859,15 +867,17 @@ bool lock_monitor_enter(java_handle_t *o) retry: // Most common case: try to thin-lock an unlocked object. - Lockword* lockword = lock_lockword_get(o); - bool result = lockword->lock(thinlock); + uintptr_t *lw_ptr = lock_lockword_get(o); + uintptr_t lw_cache = *lw_ptr; + Lockword lockword(lw_cache); + bool result = Lockword(*lw_ptr).lock(thinlock); if (result == true) { // Success, we locked it. // NOTE: The Java Memory Model requires a memory barrier here. #if defined(CAS_PROVIDES_FULL_BARRIER) && CAS_PROVIDES_FULL_BARRIER // On some architectures, the CAS (hidden in the - // lockword->lock call above), already provides this barrier, + // lockword.lock call above), already provides this barrier, // so we only need to inform the compiler. Atomic::instruction_barrier(); #else @@ -880,11 +890,11 @@ retry: // NOTE: We don't have to worry about stale values here, as any // stale value will indicate another thread holding the lock (or // an inflated lock). - if (lockword->get_thin_lock_without_count() == thinlock) { + if (lockword.get_thin_lock_without_count() == thinlock) { // We own this monitor. Check the current recursion count. - if (lockword->is_max_thin_lock_count() == false) { + if (lockword.is_max_thin_lock_count() == false) { // The recursion count is low enough. - lockword->increase_thin_lock_count(); + Lockword(*lw_ptr).increase_thin_lock_count(); // Success, we locked it. return true; @@ -903,8 +913,8 @@ retry: } // The lock is either contented or fat. - if (lockword->is_fat_lock()) { - lock_record_t* lr = lockword->get_fat_lock(); + if (lockword.is_fat_lock()) { + lock_record_t* lr = lockword.get_fat_lock(); // Check for recursive entering. if (lr->owner == t) { @@ -927,7 +937,7 @@ retry: jvmti_MonitorContendedEntering(false, o); #endif - sable_flc_waiting(lockword, t, o); + sable_flc_waiting(lw_cache, t, o); #if defined(ENABLE_JVMTI) /* Monitor Contended Entered */ @@ -971,13 +981,15 @@ bool lock_monitor_exit(java_handle_t* o) // We don't have to worry about stale values here, as any stale // value will indicate that we don't own the lock. - Lockword* lockword = lock_lockword_get(o); + uintptr_t *lw_ptr = lock_lockword_get(o); + uintptr_t lw_cache = *lw_ptr; + Lockword lockword(lw_cache); // Most common case: we release a thin lock that we hold once. - if (lockword->get_thin_lock() == thinlock) { + if (lockword.get_thin_lock() == thinlock) { // Memory barrier for Java Memory Model. Atomic::write_memory_barrier(); - lockword->unlock(); + Lockword(*lw_ptr).unlock(); // Memory barrier for FLC bit testing. Atomic::memory_barrier(); @@ -994,14 +1006,14 @@ bool lock_monitor_exit(java_handle_t* o) } // Next common case: we release a recursive lock, count > 0. - if (lockword->get_thin_lock_without_count() == thinlock) { - lockword->decrease_thin_lock_count(); + if (lockword.get_thin_lock_without_count() == thinlock) { + Lockword(*lw_ptr).decrease_thin_lock_count(); return true; } // Either the lock is fat, or we don't hold it at all. - if (lockword->is_fat_lock()) { - lock_record_t* lr = lockword->get_fat_lock(); + if (lockword.is_fat_lock()) { + lock_record_t* lr = lockword.get_fat_lock(); // Check if we own this monitor. // NOTE: We don't have to worry about stale values here, as @@ -1175,13 +1187,15 @@ static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 n { lock_record_t *lr; - Lockword* lockword = lock_lockword_get(o); + uintptr_t *lw_ptr = lock_lockword_get(o); + uintptr_t lw_cache = *lw_ptr; + Lockword lockword(lw_cache); // Check if we own this monitor. // NOTE: We don't have to worry about stale values here, as any // stale value will fail this check. - if (lockword->is_fat_lock()) { - lr = lockword->get_fat_lock(); + if (lockword.is_fat_lock()) { + lr = lockword.get_fat_lock(); if (lr->owner != t) { exceptions_throw_illegalmonitorstateexception(); @@ -1190,7 +1204,7 @@ static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 n } else { // It's a thin lock. - if (lockword->get_thin_lock_without_count() != t->thinlock) { + if (lockword.get_thin_lock_without_count() != t->thinlock) { exceptions_throw_illegalmonitorstateexception(); return; } @@ -1200,7 +1214,7 @@ static void lock_monitor_wait(threadobject *t, java_handle_t *o, s8 millis, s4 n lock_record_enter(t, lr); // Inflate this lock. - lockword->inflate(lr); + Lockword(*lw_ptr).inflate(lr); notify_flc_waiters(t, o); } @@ -1287,14 +1301,15 @@ static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one) // This scope is inside a critical section. GCCriticalSection cs; - Lockword* lockword = lock_lockword_get(o); + uintptr_t lw_cache = *lock_lockword_get(o); + Lockword lockword(lw_cache); // Check if we own this monitor. // NOTE: We don't have to worry about stale values here, as any // stale value will fail this check. - if (lockword->is_fat_lock()) { - lr = lockword->get_fat_lock(); + if (lockword.is_fat_lock()) { + lr = lockword.get_fat_lock(); if (lr->owner != t) { exceptions_throw_illegalmonitorstateexception(); @@ -1303,7 +1318,7 @@ static void lock_monitor_notify(threadobject *t, java_handle_t *o, bool one) } else { // It's a thin lock. - if (lockword->get_thin_lock_without_count() != t->thinlock) { + if (lockword.get_thin_lock_without_count() != t->thinlock) { exceptions_throw_illegalmonitorstateexception(); return; } @@ -1345,16 +1360,17 @@ bool lock_is_held_by_current_thread(java_handle_t *o) // NOTE: We don't have to worry about stale values here, as any // stale value will fail this check. threadobject* t = thread_get_current(); - Lockword* lockword = lock_lockword_get(o); + uintptr_t lw_cache = *lock_lockword_get(o); + Lockword lockword(lw_cache); - if (lockword->is_fat_lock()) { + if (lockword.is_fat_lock()) { // It's a fat lock. - lock_record_t* lr = lockword->get_fat_lock(); + lock_record_t* lr = lockword.get_fat_lock(); return (lr->owner == t); } else { // It's a thin lock. - return (lockword->get_thin_lock_without_count() == t->thinlock); + return (lockword.get_thin_lock_without_count() == t->thinlock); } } diff --git a/src/threads/lockword.hpp b/src/threads/lockword.hpp index 74ccb94fd..99b2d8296 100644 --- a/src/threads/lockword.hpp +++ b/src/threads/lockword.hpp @@ -1,6 +1,6 @@ /* src/threads/lockword.hpp - lockword implementation - Copyright (C) 2008 + Copyright (C) 2008-2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -53,13 +53,10 @@ private: private: // The actual lockword. - uintptr_t _lockword; - -private: - Lockword(uintptr_t lockword) : _lockword(lockword) {} + uintptr_t& _lockword; public: - Lockword() : _lockword(THIN_UNLOCKED) {} + Lockword(uintptr_t& lockword) : _lockword(lockword) {} void init() { _lockword = THIN_UNLOCKED; } // REMOVEME diff --git a/src/vm/array.hpp b/src/vm/array.hpp index 1097734dc..d6406eae4 100644 --- a/src/vm/array.hpp +++ b/src/vm/array.hpp @@ -1,6 +1,6 @@ /* src/vm/array.hpp - Java array functions - Copyright (C) 2007, 2009 + Copyright (C) 2007, 2009, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2008 Theobroma Systems Ltd. @@ -160,7 +160,7 @@ inline Array::Array(int32_t size, classinfo* arrayclass) LLNI_vftbl_direct(a) = arrayclass->vftbl; #if defined(ENABLE_THREADS) - a->objheader.lockword.init(); + Lockword(a->objheader.lockword).init(); #endif a->size = size; diff --git a/src/vm/class.cpp b/src/vm/class.cpp index ee17a20ca..601ac6cfd 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -1,6 +1,6 @@ /* src/vm/class.cpp - class related functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -177,7 +177,7 @@ classinfo *class_create_classinfo(utf *classname) if (classname != utf_not_named_yet) class_set_packagename(c); - c->object.header.lockword.init(); + Lockword(c->object.header.lockword).init(); return c; } diff --git a/src/vm/global.h b/src/vm/global.h index 45287193b..e761d76eb 100644 --- a/src/vm/global.h +++ b/src/vm/global.h @@ -1,6 +1,6 @@ /* src/vm/global.h - global definitions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -247,7 +247,7 @@ typedef struct java_objectarray_t java_objectarray_t; struct java_object_t { /* header for all objects */ struct _vftbl *vftbl; /* pointer to virtual function table */ #if defined(ENABLE_THREADS) - Lockword lockword; + uintptr_t lockword; #endif #if defined(ENABLE_GC_CACAO) uintptr_t hdrflags; /* word containing the GC bits */ diff --git a/src/vm/jit/builtin.cpp b/src/vm/jit/builtin.cpp index 46945ada4..146e64dff 100644 --- a/src/vm/jit/builtin.cpp +++ b/src/vm/jit/builtin.cpp @@ -1,6 +1,6 @@ /* src/vm/jit/builtin.cpp - functions for unsupported operations - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -863,7 +863,7 @@ java_handle_t *builtin_new(classinfo *c) LLNI_vftbl_direct(o) = c->vftbl; #if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); #endif CYCLES_STATS_GET(cycles_end); @@ -945,7 +945,7 @@ java_handle_t *builtin_tlh_new(classinfo *c) LLNI_vftbl_direct(o) = c->vftbl; # if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); # endif CYCLES_STATS_GET(cycles_end); @@ -1024,7 +1024,7 @@ java_object_t *builtin_fast_new(classinfo *c) o->vftbl = c->vftbl; #if defined(ENABLE_THREADS) - LLNI_DIRECT(o)->lockword.init(); + Lockword(LLNI_DIRECT(o)->lockword).init(); #endif CYCLES_STATS_GET(cycles_end); @@ -2163,7 +2163,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) #endif #if defined(ENABLE_THREADS) - LLNI_DIRECT(co)->lockword.init(); + Lockword(LLNI_DIRECT(co)->lockword).init(); #endif LLNI_CRITICAL_END; @@ -2198,7 +2198,7 @@ java_handle_t *builtin_clone(void *env, java_handle_t *o) #endif #if defined(ENABLE_THREADS) - LLNI_DIRECT(co)->lockword.init(); + Lockword(LLNI_DIRECT(co)->lockword).init(); #endif LLNI_CRITICAL_END; diff --git a/src/vm/string.cpp b/src/vm/string.cpp index 45b4ad46e..ab38e6698 100644 --- a/src/vm/string.cpp +++ b/src/vm/string.cpp @@ -1,6 +1,6 @@ /* src/vm/string.cpp - java.lang.String related functions - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2010 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -547,7 +547,7 @@ static java_handle_t *literalstring_u2(java_handle_chararray_t *a, int32_t lengt #endif #if defined(ENABLE_THREADS) - o->lockword.init(); + Lockword(o->lockword).init(); #endif o->vftbl = class_java_lang_String->vftbl;