add appropriate memory barriers to double-checked locking code

This commit is contained in:
Joel Dice 2011-04-10 14:46:53 -06:00
parent 88c95615c7
commit 7c30e44601
5 changed files with 47 additions and 13 deletions

View File

@ -2120,13 +2120,20 @@ setProperty(Thread* t, object method, object properties,
object
interruptLock(Thread* t, object thread)
{
if (threadInterruptLock(t, thread) == 0) {
object lock = threadInterruptLock(t, thread);
loadMemoryBarrier();
if (lock == 0) {
PROTECT(t, thread);
ACQUIRE(t, t->m->referenceLock);
if (threadInterruptLock(t, thread) == 0) {
object head = makeMonitorNode(t, 0, 0);
object lock = makeMonitor(t, 0, 0, 0, head, head, 0);
storeStoreMemoryBarrier();
set(t, thread, ThreadInterruptLock, lock);
}
}

View File

@ -9586,6 +9586,8 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size)
uintptr_t
virtualThunk(MyThread* t, unsigned index)
{
ACQUIRE(t, t->m->classLock);
if (root(t, VirtualThunks) == 0
or wordArrayLength(t, root(t, VirtualThunks)) <= index * 2)
{
@ -9599,14 +9601,10 @@ virtualThunk(MyThread* t, unsigned index)
}
if (wordArrayBody(t, root(t, VirtualThunks), index * 2) == 0) {
ACQUIRE(t, t->m->classLock);
if (wordArrayBody(t, root(t, VirtualThunks), index * 2) == 0) {
unsigned size;
uintptr_t thunk = compileVirtualThunk(t, index, &size);
wordArrayBody(t, root(t, VirtualThunks), index * 2) = thunk;
wordArrayBody(t, root(t, VirtualThunks), (index * 2) + 1) = size;
}
unsigned size;
uintptr_t thunk = compileVirtualThunk(t, index, &size);
wordArrayBody(t, root(t, VirtualThunks), index * 2) = thunk;
wordArrayBody(t, root(t, VirtualThunks), (index * 2) + 1) = size;
}
return wordArrayBody(t, root(t, VirtualThunks), index * 2);

View File

@ -509,7 +509,11 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec)
jint
methodID(Thread* t, object method)
{
if (methodNativeID(t, method) == 0) {
int id = methodNativeID(t, method);
loadMemoryBarrier();
if (id == 0) {
PROTECT(t, method);
ACQUIRE(t, t->m->referenceLock);
@ -517,6 +521,9 @@ methodID(Thread* t, object method)
if (methodNativeID(t, method) == 0) {
setRoot(t, Machine::JNIMethodTable, vectorAppend
(t, root(t, Machine::JNIMethodTable), method));
storeStoreMemoryBarrier();
methodNativeID(t, method) = vectorSize
(t, root(t, Machine::JNIMethodTable));
}
@ -1164,7 +1171,11 @@ CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...)
jint
fieldID(Thread* t, object field)
{
if (fieldNativeID(t, field) == 0) {
int id = fieldNativeID(t, field);
loadMemoryBarrier();
if (id == 0) {
PROTECT(t, field);
ACQUIRE(t, t->m->referenceLock);
@ -1172,6 +1183,9 @@ fieldID(Thread* t, object field)
if (fieldNativeID(t, field) == 0) {
setRoot(t, Machine::JNIFieldTable, vectorAppend
(t, root(t, Machine::JNIFieldTable), field));
storeStoreMemoryBarrier();
fieldNativeID(t, field) = vectorSize(t, root(t, Machine::JNIFieldTable));
}
}

View File

@ -3677,7 +3677,11 @@ classNeedsInit(Thread* t, object c)
bool
preInitClass(Thread* t, object c)
{
if (classVmFlags(t, c) & NeedInitFlag) {
int flags = classVmFlags(t, c);
loadMemoryBarrier();
if (flags & NeedInitFlag) {
PROTECT(t, c);
ACQUIRE(t, t->m->classLock);

View File

@ -3619,7 +3619,11 @@ getClassRuntimeData(Thread* t, object c)
inline object
getMethodRuntimeData(Thread* t, object method)
{
if (methodRuntimeDataIndex(t, method) == 0) {
int index = methodRuntimeDataIndex(t, method);
loadMemoryBarrier();
if (index == 0) {
PROTECT(t, method);
ACQUIRE(t, t->m->classLock);
@ -3630,6 +3634,8 @@ getMethodRuntimeData(Thread* t, object method)
setRoot(t, Machine::MethodRuntimeDataTable, vectorAppend
(t, root(t, Machine::MethodRuntimeDataTable), runtimeData));
storeStoreMemoryBarrier();
methodRuntimeDataIndex(t, method) = vectorSize
(t, root(t, Machine::MethodRuntimeDataTable));
}
@ -3645,12 +3651,17 @@ getJClass(Thread* t, object c)
PROTECT(t, c);
object jclass = classRuntimeDataJclass(t, getClassRuntimeData(t, c));
loadMemoryBarrier();
if (jclass == 0) {
ACQUIRE(t, t->m->classLock);
jclass = classRuntimeDataJclass(t, getClassRuntimeData(t, c));
if (jclass == 0) {
jclass = t->m->classpath->makeJclass(t, c);
storeStoreMemoryBarrier();
set(t, getClassRuntimeData(t, c), ClassRuntimeDataJclass, jclass);
}