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 object
interruptLock(Thread* t, object thread) interruptLock(Thread* t, object thread)
{ {
if (threadInterruptLock(t, thread) == 0) { object lock = threadInterruptLock(t, thread);
loadMemoryBarrier();
if (lock == 0) {
PROTECT(t, thread); PROTECT(t, thread);
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
if (threadInterruptLock(t, thread) == 0) { if (threadInterruptLock(t, thread) == 0) {
object head = makeMonitorNode(t, 0, 0); object head = makeMonitorNode(t, 0, 0);
object lock = makeMonitor(t, 0, 0, 0, head, head, 0); object lock = makeMonitor(t, 0, 0, 0, head, head, 0);
storeStoreMemoryBarrier();
set(t, thread, ThreadInterruptLock, lock); set(t, thread, ThreadInterruptLock, lock);
} }
} }

View File

@ -9586,6 +9586,8 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size)
uintptr_t uintptr_t
virtualThunk(MyThread* t, unsigned index) virtualThunk(MyThread* t, unsigned index)
{ {
ACQUIRE(t, t->m->classLock);
if (root(t, VirtualThunks) == 0 if (root(t, VirtualThunks) == 0
or wordArrayLength(t, root(t, VirtualThunks)) <= index * 2) or wordArrayLength(t, root(t, VirtualThunks)) <= index * 2)
{ {
@ -9598,16 +9600,12 @@ virtualThunk(MyThread* t, unsigned index)
setRoot(t, VirtualThunks, newArray); setRoot(t, VirtualThunks, newArray);
} }
if (wordArrayBody(t, root(t, VirtualThunks), index * 2) == 0) {
ACQUIRE(t, t->m->classLock);
if (wordArrayBody(t, root(t, VirtualThunks), index * 2) == 0) { if (wordArrayBody(t, root(t, VirtualThunks), index * 2) == 0) {
unsigned size; unsigned size;
uintptr_t thunk = compileVirtualThunk(t, index, &size); uintptr_t thunk = compileVirtualThunk(t, index, &size);
wordArrayBody(t, root(t, VirtualThunks), index * 2) = thunk; wordArrayBody(t, root(t, VirtualThunks), index * 2) = thunk;
wordArrayBody(t, root(t, VirtualThunks), (index * 2) + 1) = size; wordArrayBody(t, root(t, VirtualThunks), (index * 2) + 1) = size;
} }
}
return wordArrayBody(t, root(t, VirtualThunks), index * 2); 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 jint
methodID(Thread* t, object method) methodID(Thread* t, object method)
{ {
if (methodNativeID(t, method) == 0) { int id = methodNativeID(t, method);
loadMemoryBarrier();
if (id == 0) {
PROTECT(t, method); PROTECT(t, method);
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
@ -517,6 +521,9 @@ methodID(Thread* t, object method)
if (methodNativeID(t, method) == 0) { if (methodNativeID(t, method) == 0) {
setRoot(t, Machine::JNIMethodTable, vectorAppend setRoot(t, Machine::JNIMethodTable, vectorAppend
(t, root(t, Machine::JNIMethodTable), method)); (t, root(t, Machine::JNIMethodTable), method));
storeStoreMemoryBarrier();
methodNativeID(t, method) = vectorSize methodNativeID(t, method) = vectorSize
(t, root(t, Machine::JNIMethodTable)); (t, root(t, Machine::JNIMethodTable));
} }
@ -1164,7 +1171,11 @@ CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...)
jint jint
fieldID(Thread* t, object field) fieldID(Thread* t, object field)
{ {
if (fieldNativeID(t, field) == 0) { int id = fieldNativeID(t, field);
loadMemoryBarrier();
if (id == 0) {
PROTECT(t, field); PROTECT(t, field);
ACQUIRE(t, t->m->referenceLock); ACQUIRE(t, t->m->referenceLock);
@ -1172,6 +1183,9 @@ fieldID(Thread* t, object field)
if (fieldNativeID(t, field) == 0) { if (fieldNativeID(t, field) == 0) {
setRoot(t, Machine::JNIFieldTable, vectorAppend setRoot(t, Machine::JNIFieldTable, vectorAppend
(t, root(t, Machine::JNIFieldTable), field)); (t, root(t, Machine::JNIFieldTable), field));
storeStoreMemoryBarrier();
fieldNativeID(t, field) = vectorSize(t, root(t, Machine::JNIFieldTable)); fieldNativeID(t, field) = vectorSize(t, root(t, Machine::JNIFieldTable));
} }
} }

View File

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

View File

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