mirror of
https://github.com/corda/corda.git
synced 2025-02-14 14:42:32 +00:00
add appropriate memory barriers to double-checked locking code
This commit is contained in:
parent
88c95615c7
commit
7c30e44601
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user