From 7152c3fdb325885e71db62ead73355e6ac8035b0 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 15 Mar 2011 19:34:00 -0600 Subject: [PATCH] handle volatile fields properly in JNI Get/Set methods This commit ensures that we use the proper memory barriers or locking necessary to preserve volatile semantics for such fields when accessed or updated via JNI. --- classpath/avian/VMField.java | 2 +- src/jnienv.cpp | 818 ++++++++++++++++++++++++++++++----- src/machine.cpp | 3 +- src/machine.h | 1 + 4 files changed, 714 insertions(+), 110 deletions(-) diff --git a/classpath/avian/VMField.java b/classpath/avian/VMField.java index 70752ac943..8df0d426c5 100644 --- a/classpath/avian/VMField.java +++ b/classpath/avian/VMField.java @@ -15,7 +15,7 @@ public class VMField { public byte code; public short flags; public short offset; - public short index; + public int nativeID; public byte[] name; public byte[] spec; public FieldAddendum addendum; diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 3d17a22949..9ed2ce4815 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -20,12 +20,6 @@ namespace { namespace local { -const uintptr_t InterfaceMethodID -= (static_cast(1) << (BitsPerWord - 1)); - -const uintptr_t NonVirtualMethodID -= (static_cast(1) << (BitsPerWord - 2)); - jint JNICALL AttachCurrentThread(Machine* m, Thread** t, void*) { @@ -559,9 +553,11 @@ GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec) return run(t, getStaticMethodID, arguments); } -inline object +object getMethod(Thread* t, jmethodID m) { + assert(t, m); + object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1); assert(t, (methodFlags(t, method) & ACC_STATIC) == 0); @@ -883,9 +879,11 @@ CallVoidMethod(Thread* t, jobject o, jmethodID m, ...) va_end(a); } -inline object +object getStaticMethod(Thread* t, jmethodID m) { + assert(t, m); + object method = vectorBody(t, root(t, Machine::JNIMethodTable), m - 1); assert(t, methodFlags(t, method) & ACC_STATIC); @@ -1143,6 +1141,24 @@ CallStaticVoidMethod(Thread* t, jclass c, jmethodID m, ...) va_end(a); } +jint +fieldID(Thread* t, object field) +{ + if (fieldNativeID(t, field) == 0) { + PROTECT(t, field); + + ACQUIRE(t, t->m->referenceLock); + + if (fieldNativeID(t, field) == 0) { + setRoot(t, Machine::JNIFieldTable, vectorAppend + (t, root(t, Machine::JNIFieldTable), field)); + fieldNativeID(t, field) = vectorSize(t, root(t, Machine::JNIFieldTable)); + } + } + + return fieldNativeID(t, field); +} + uint64_t getFieldID(Thread* t, uintptr_t* arguments) { @@ -1150,7 +1166,7 @@ getFieldID(Thread* t, uintptr_t* arguments) const char* name = reinterpret_cast(arguments[1]); const char* spec = reinterpret_cast(arguments[2]); - return fieldOffset(t, resolveField(t, jclassVmClass(t, *c), name, spec)); + return fieldID(t, resolveField(t, jclassVmClass(t, *c), name, spec)); } jfieldID JNICALL @@ -1173,293 +1189,881 @@ GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec) return run(t, getFieldID, arguments); } +object +getField(Thread* t, jfieldID f) +{ + assert(t, f); + + object field = vectorBody(t, root(t, Machine::JNIFieldTable), f - 1); + + assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0); + + return field; +} + +uint64_t +getObjectField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return reinterpret_cast + (makeLocalReference(t, cast(*o, fieldOffset(t, field)))); +} + jobject JNICALL GetObjectField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return makeLocalReference(t, cast(*o, field)); + return reinterpret_cast(run(t, getObjectField, arguments)); +} + +uint64_t +getBooleanField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jboolean JNICALL GetBooleanField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getBooleanField, arguments); +} + +uint64_t +getByteField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jbyte JNICALL GetByteField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getByteField, arguments); +} + +uint64_t +getCharField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jchar JNICALL GetCharField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getCharField, arguments); +} + +uint64_t +getShortField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jshort JNICALL GetShortField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getShortField, arguments); +} + +uint64_t +getIntField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jint JNICALL GetIntField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getIntField, arguments); +} + +uint64_t +getLongField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast(*o, fieldOffset(t, field)); } jlong JNICALL GetLongField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return run(t, getLongField, arguments); +} + +uint64_t +getFloatField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return floatToBits(cast(*o, fieldOffset(t, field))); } jfloat JNICALL GetFloatField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return bitsToFloat(run(t, getFloatField, arguments)); +} + +uint64_t +getDoubleField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return doubleToBits(cast(*o, fieldOffset(t, field))); } jdouble JNICALL GetDoubleField(Thread* t, jobject o, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field }; - return cast(*o, field); + return bitsToDouble(run(t, getDoubleField, arguments)); +} + +uint64_t +setObjectField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jobject v = reinterpret_cast(arguments[2]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + set(t, *o, fieldOffset(t, field), (v ? *v : 0)); + + return 1; } void JNICALL SetObjectField(Thread* t, jobject o, jfieldID field, jobject v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + reinterpret_cast(v) }; - set(t, *o, field, (v ? *v : 0)); + run(t, setObjectField, arguments); +} + +uint64_t +setBooleanField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jboolean v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetBooleanField(Thread* t, jobject o, jfieldID field, jboolean v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + v }; - cast(*o, field) = v; + run(t, setBooleanField, arguments); +} + +uint64_t +setByteField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jbyte v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetByteField(Thread* t, jobject o, jfieldID field, jbyte v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + v }; - cast(*o, field) = v; + run(t, setByteField, arguments); +} + +uint64_t +setCharField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jchar v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetCharField(Thread* t, jobject o, jfieldID field, jchar v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + v }; - cast(*o, field) = v; + run(t, setCharField, arguments); +} + +uint64_t +setShortField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jshort v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetShortField(Thread* t, jobject o, jfieldID field, jshort v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + v }; - cast(*o, field) = v; + run(t, setShortField, arguments); +} + +uint64_t +setIntField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jint v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetIntField(Thread* t, jobject o, jfieldID field, jint v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + v }; - cast(*o, field) = v; + run(t, setIntField, arguments); +} + +uint64_t +setLongField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jlong v; memcpy(&v, arguments + 2, sizeof(jlong)); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetLongField(Thread* t, jobject o, jfieldID field, jlong v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[2 + (sizeof(jlong) / BytesPerWord)]; + arguments[0] = reinterpret_cast(o); + arguments[1] = field; + memcpy(arguments + 2, &v, sizeof(jlong)); - cast(*o, field) = v; + run(t, setLongField, arguments); +} + +uint64_t +setFloatField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jfloat v = bitsToFloat(arguments[2]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetFloatField(Thread* t, jobject o, jfieldID field, jfloat v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + floatToBits(v) }; - cast(*o, field) = v; + run(t, setFloatField, arguments); +} + +uint64_t +setDoubleField(Thread* t, uintptr_t* arguments) +{ + jobject o = reinterpret_cast(arguments[0]); + object field = getField(t, arguments[1]); + jdouble v = bitsToDouble(arguments[2]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast(*o, fieldOffset(t, field)) = v; + + return 1; } void JNICALL SetDoubleField(Thread* t, jobject o, jfieldID field, jdouble v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(o), + field, + doubleToBits(v) }; - cast(*o, field) = v; + run(t, setDoubleField, arguments); +} + +object +getStaticField(Thread* t, jfieldID f) +{ + assert(t, f); + + object field = vectorBody(t, root(t, Machine::JNIFieldTable), f - 1); + + assert(t, fieldFlags(t, field) & ACC_STATIC); + + return field; +} + +uint64_t +getStaticObjectField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return reinterpret_cast + (makeLocalReference + (t, cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)))); } jobject JNICALL -GetStaticObjectField(Thread* t, jclass c, jfieldID field) +GetStaticObjectField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return makeLocalReference - (t, cast(classStaticTable(t, jclassVmClass(t, *c)), field)); + return reinterpret_cast(run(t, getStaticObjectField, arguments)); +} + +uint64_t +getStaticBooleanField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jboolean JNICALL -GetStaticBooleanField(Thread* t, jclass c, jfieldID field) +GetStaticBooleanField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticBooleanField, arguments); +} + +uint64_t +getStaticByteField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jbyte JNICALL -GetStaticByteField(Thread* t, jclass c, jfieldID field) +GetStaticByteField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticByteField, arguments); +} + +uint64_t +getStaticCharField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jchar JNICALL -GetStaticCharField(Thread* t, jclass c, jfieldID field) +GetStaticCharField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticCharField, arguments); +} + +uint64_t +getStaticShortField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jshort JNICALL -GetStaticShortField(Thread* t, jclass c, jfieldID field) +GetStaticShortField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticShortField, arguments); +} + +uint64_t +getStaticIntField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jint JNICALL -GetStaticIntField(Thread* t, jclass c, jfieldID field) +GetStaticIntField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticIntField, arguments); +} + +uint64_t +getStaticLongField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)); } jlong JNICALL -GetStaticLongField(Thread* t, jclass c, jfieldID field) +GetStaticLongField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return run(t, getStaticLongField, arguments); +} + +uint64_t +getStaticFloatField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return floatToBits + (cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field))); } jfloat JNICALL -GetStaticFloatField(Thread* t, jclass c, jfieldID field) +GetStaticFloatField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return bitsToFloat(run(t, getStaticFloatField, arguments)); +} + +uint64_t +getStaticDoubleField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_READ(t, field); + + return doubleToBits + (cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field))); } jdouble JNICALL -GetStaticDoubleField(Thread* t, jclass c, jfieldID field) +GetStaticDoubleField(Thread* t, jobject c, jfieldID field) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field }; - return cast(classStaticTable(t, jclassVmClass(t, *c)), field); + return bitsToDouble(run(t, getStaticDoubleField, arguments)); } -void JNICALL -SetStaticObjectField(Thread* t, jclass c, jfieldID field, jobject v) +uint64_t +setStaticObjectField(Thread* t, uintptr_t* arguments) { - ENTER(t, Thread::ActiveState); - - set(t, classStaticTable(t, jclassVmClass(t, *c)), field, (v ? *v : 0)); -} - -void JNICALL -SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v) -{ - ENTER(t, Thread::ActiveState); + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jobject v = reinterpret_cast(arguments[2]); - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + set(t, classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field), + (v ? *v : 0)); + + return 1; } void JNICALL -SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v) +SetStaticObjectField(Thread* t, jobject c, jfieldID field, jobject v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + reinterpret_cast(v) }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticObjectField, arguments); +} + +uint64_t +setStaticBooleanField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jboolean v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v) +SetStaticBooleanField(Thread* t, jobject c, jfieldID field, jboolean v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + v }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticBooleanField, arguments); +} + +uint64_t +setStaticByteField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jbyte v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v) +SetStaticByteField(Thread* t, jobject c, jfieldID field, jbyte v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + v }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticByteField, arguments); +} + +uint64_t +setStaticCharField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jchar v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v) +SetStaticCharField(Thread* t, jobject c, jfieldID field, jchar v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + v }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticCharField, arguments); +} + +uint64_t +setStaticShortField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jshort v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v) +SetStaticShortField(Thread* t, jobject c, jfieldID field, jshort v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + v }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticShortField, arguments); +} + +uint64_t +setStaticIntField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jint v = arguments[2]; + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v) +SetStaticIntField(Thread* t, jobject c, jfieldID field, jint v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[] = { reinterpret_cast(c), + field, + v }; - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticIntField, arguments); +} + +uint64_t +setStaticLongField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jlong v; memcpy(&v, arguments + 2, sizeof(jlong)); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; } void JNICALL -SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v) +SetStaticLongField(Thread* t, jobject c, jfieldID field, jlong v) { - ENTER(t, Thread::ActiveState); + uintptr_t arguments[2 + (sizeof(jlong) / BytesPerWord)]; + arguments[0] = reinterpret_cast(c); + arguments[1] = field; + memcpy(arguments + 2, &v, sizeof(jlong)); - cast(classStaticTable(t, jclassVmClass(t, *c)), field) = v; + run(t, setStaticLongField, arguments); +} + +uint64_t +setStaticFloatField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jfloat v = bitsToFloat(arguments[2]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; +} + +void JNICALL +SetStaticFloatField(Thread* t, jobject c, jfieldID field, jfloat v) +{ + uintptr_t arguments[] = { reinterpret_cast(c), + field, + floatToBits(v) }; + + run(t, setStaticFloatField, arguments); +} + +uint64_t +setStaticDoubleField(Thread* t, uintptr_t* arguments) +{ + jobject c = reinterpret_cast(arguments[0]); + object field = getStaticField(t, arguments[1]); + jdouble v = bitsToDouble(arguments[2]); + + PROTECT(t, field); + ACQUIRE_FIELD_FOR_WRITE(t, field); + + cast + (classStaticTable(t, jclassVmClass(t, *c)), fieldOffset(t, field)) = v; + + return 1; +} + +void JNICALL +SetStaticDoubleField(Thread* t, jobject c, jfieldID field, jdouble v) +{ + uintptr_t arguments[] = { reinterpret_cast(c), + field, + doubleToBits(v) }; + + run(t, setStaticDoubleField, arguments); } jobject JNICALL @@ -2318,8 +2922,6 @@ append(char** p, const char* value, unsigned length, char tail) uint64_t boot(Thread* t, uintptr_t*) { - t->javaThread = t->m->classpath->makeThread(t, 0); - setRoot(t, Machine::NullPointerException, makeThrowable (t, Machine::NullPointerExceptionType)); diff --git a/src/machine.cpp b/src/machine.cpp index e1bf8aadec..016fe4bf97 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1075,7 +1075,7 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool) code, flags, 0, // offset - i, + 0, // native ID singletonObject(t, pool, name - 1), singletonObject(t, pool, spec - 1), addendum, @@ -2388,6 +2388,7 @@ Thread::init() setRoot(this, Machine::ClassRuntimeDataTable, makeVector(this, 0, 0)); setRoot(this, Machine::MethodRuntimeDataTable, makeVector(this, 0, 0)); setRoot(this, Machine::JNIMethodTable, makeVector(this, 0, 0)); + setRoot(this, Machine::JNIFieldTable, makeVector(this, 0, 0)); m->localThread->set(this); diff --git a/src/machine.h b/src/machine.h index 11c9b7ce11..a9f6122e97 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1256,6 +1256,7 @@ class Machine { ClassRuntimeDataTable, MethodRuntimeDataTable, JNIMethodTable, + JNIFieldTable, ShutdownHooks, FinalizerThread, ObjectsToFinalize,