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.
/* src/threads/lock.cpp - lock implementation
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
static void lock_hashtable_init(void);
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);
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);
u4 slot;
lock_record_t *lr;
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();
// Lock the hashtable.
lock_hashtable.mutex->lock();
#if defined(ENABLE_GC_BOEHM)
void lock_schedule_lockrecord_removal(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;
/* there is no lock record */
return;
- Lockword* lockword = lock_lockword_get(o);
+ uintptr_t lw_cache = *lock_lockword_get(o);
+ Lockword lockword(lw_cache);
- 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 */
/* remove the lock-record from the hashtable */
*******************************************************************************/
*******************************************************************************/
-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.
{
#if defined(ENABLE_GC_CACAO)
// Sanity check.
static void lock_inflate(java_handle_t *o, 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);
*******************************************************************************/
*******************************************************************************/
-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;
{
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
t_other = ThreadList::get_thread_by_index(index);
// The lockword could have changed during our way here. If the
// Set FLC bit first, then read the lockword again.
Atomic::memory_barrier();
// 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 */
/* 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 */
{
threadobject *f;
/* Add tuple (t, o) to the other thread's FLC list */
block on it. */
// Only if not already inflated.
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);
lock_record_t *lr = lock_hashtable_get(current->flc_object);
lock_record_enter(t, lr);
retry:
// Most common case: try to thin-lock an unlocked object.
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
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
// so we only need to inform the compiler.
Atomic::instruction_barrier();
#else
// 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).
// 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.
// 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.
// The recursion count is low enough.
- lockword->increase_thin_lock_count();
+ Lockword(*lw_ptr).increase_thin_lock_count();
// Success, we locked it.
return true;
// Success, we locked it.
return true;
}
// The lock is either contented or fat.
}
// 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) {
// Check for recursive entering.
if (lr->owner == t) {
jvmti_MonitorContendedEntering(false, o);
#endif
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 */
#if defined(ENABLE_JVMTI)
/* Monitor Contended Entered */
// We don't have to worry about stale values here, as any stale
// value will indicate that we don't own the lock.
// 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.
// 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();
// Memory barrier for Java Memory Model.
Atomic::write_memory_barrier();
+ Lockword(*lw_ptr).unlock();
// Memory barrier for FLC bit testing.
Atomic::memory_barrier();
// Memory barrier for FLC bit testing.
Atomic::memory_barrier();
}
// Next common case: we release a recursive lock, count > 0.
}
// 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.
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
// Check if we own this monitor.
// NOTE: We don't have to worry about stale values here, as
- 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.
// 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();
if (lr->owner != t) {
exceptions_throw_illegalmonitorstateexception();
}
else {
// It's a thin lock.
}
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;
}
exceptions_throw_illegalmonitorstateexception();
return;
}
lock_record_enter(t, lr);
// Inflate this lock.
lock_record_enter(t, lr);
// Inflate this lock.
+ Lockword(*lw_ptr).inflate(lr);
notify_flc_waiters(t, o);
}
notify_flc_waiters(t, o);
}
// This scope is inside a critical section.
GCCriticalSection cs;
// 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.
// 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();
if (lr->owner != t) {
exceptions_throw_illegalmonitorstateexception();
}
else {
// It's a thin lock.
}
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;
}
exceptions_throw_illegalmonitorstateexception();
return;
}
// NOTE: We don't have to worry about stale values here, as any
// stale value will fail this check.
threadobject* t = thread_get_current();
// 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()) {
- 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 (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);
/* src/threads/lockword.hpp - lockword implementation
/* src/threads/lockword.hpp - lockword implementation
+ Copyright (C) 2008-2010
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
private:
// The actual lockword.
private:
// The actual lockword.
- uintptr_t _lockword;
-
-private:
- Lockword(uintptr_t lockword) : _lockword(lockword) {}
- Lockword() : _lockword(THIN_UNLOCKED) {}
+ Lockword(uintptr_t& lockword) : _lockword(lockword) {}
void init() { _lockword = THIN_UNLOCKED; } // REMOVEME
void init() { _lockword = THIN_UNLOCKED; } // REMOVEME
/* src/vm/array.hpp - Java array functions
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
Copyright (C) 2008 Theobroma Systems Ltd.
LLNI_vftbl_direct(a) = arrayclass->vftbl;
#if defined(ENABLE_THREADS)
LLNI_vftbl_direct(a) = arrayclass->vftbl;
#if defined(ENABLE_THREADS)
- a->objheader.lockword.init();
+ Lockword(a->objheader.lockword).init();
/* src/vm/class.cpp - class related functions
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
if (classname != utf_not_named_yet)
class_set_packagename(c);
if (classname != utf_not_named_yet)
class_set_packagename(c);
- c->object.header.lockword.init();
+ Lockword(c->object.header.lockword).init();
/* src/vm/global.h - global definitions
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
struct java_object_t { /* header for all objects */
struct _vftbl *vftbl; /* pointer to virtual function table */
#if defined(ENABLE_THREADS)
struct java_object_t { /* header for all objects */
struct _vftbl *vftbl; /* pointer to virtual function table */
#if defined(ENABLE_THREADS)
#endif
#if defined(ENABLE_GC_CACAO)
uintptr_t hdrflags; /* word containing the GC bits */
#endif
#if defined(ENABLE_GC_CACAO)
uintptr_t hdrflags; /* word containing the GC bits */
/* src/vm/jit/builtin.cpp - functions for unsupported operations
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
LLNI_vftbl_direct(o) = c->vftbl;
#if defined(ENABLE_THREADS)
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);
#endif
CYCLES_STATS_GET(cycles_end);
LLNI_vftbl_direct(o) = c->vftbl;
# if defined(ENABLE_THREADS)
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);
# endif
CYCLES_STATS_GET(cycles_end);
o->vftbl = c->vftbl;
#if defined(ENABLE_THREADS)
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);
#endif
CYCLES_STATS_GET(cycles_end);
#endif
#if defined(ENABLE_THREADS)
#endif
#if defined(ENABLE_THREADS)
- LLNI_DIRECT(co)->lockword.init();
+ Lockword(LLNI_DIRECT(co)->lockword).init();
#endif
LLNI_CRITICAL_END;
#endif
LLNI_CRITICAL_END;
#endif
#if defined(ENABLE_THREADS)
#endif
#if defined(ENABLE_THREADS)
- LLNI_DIRECT(co)->lockword.init();
+ Lockword(LLNI_DIRECT(co)->lockword).init();
#endif
LLNI_CRITICAL_END;
#endif
LLNI_CRITICAL_END;
/* src/vm/string.cpp - java.lang.String related functions
/* 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.
CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#endif
#if defined(ENABLE_THREADS)
#endif
#if defined(ENABLE_THREADS)
+ Lockword(o->lockword).init();
#endif
o->vftbl = class_java_lang_String->vftbl;
#endif
o->vftbl = class_java_lang_String->vftbl;