From c8cc7d931b5ccd640ac827909dfa1c51967e4d9f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 15 Aug 2008 12:32:33 -0600 Subject: [PATCH] maintain a table to look up methods called via JNI This simplifies the JNI implementation for looking up methods. It also fixes a bug where an applications calls GetStaticMethodID with class A and then calls CallStaticMethod with class B which extends A. The old code would look in the wrong method table and thus call the wrong method. --- classpath/java/lang/reflect/Method.java | 1 + src/compile.cpp | 3 +- src/jnienv.cpp | 143 ++++++++++-------------- src/machine.cpp | 9 +- src/machine.h | 2 +- 5 files changed, 70 insertions(+), 88 deletions(-) diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 08a9d23b5f..39a9328c29 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -17,6 +17,7 @@ public class Method extends AccessibleObject implements Member { private byte parameterFootprint; private short flags; private short offset; + private int nativeID; private byte[] name; private byte[] spec; private Class class_; diff --git a/src/compile.cpp b/src/compile.cpp index 3f15fa9d28..aea9eebd58 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -4565,7 +4565,7 @@ class MyProcessor: public Processor { { return vm::makeMethod (t, vmFlags, returnCode, parameterCount, parameterFootprint, flags, - offset, name, spec, class_, code, + offset, 0, name, spec, class_, code, ::defaultThunk(static_cast(t))); } @@ -5101,6 +5101,7 @@ compile(MyThread* t, object method) methodParameterFootprint(t, method), methodFlags(t, method), methodOffset(t, method), + methodNativeID(t, method), methodName(t, method), methodSpec(t, method), methodClass(t, method), diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 96df4dd485..329e948687 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -280,6 +280,23 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec) return vm::findMethod(t, *c, n, s); } +jint +methodID(Thread* t, object method) +{ + if (methodNativeID(t, method) == 0) { + PROTECT(t, method); + + ACQUIRE(t, t->m->referenceLock); + + if (methodNativeID(t, method) == 0) { + t->m->jniMethodTable = vectorAppend(t, t->m->jniMethodTable, method); + methodNativeID(t, method) = vectorSize(t, t->m->jniMethodTable); + } + } + + return methodNativeID(t, method); +} + jmethodID JNICALL GetMethodID(Thread* t, jclass c, const char* name, const char* spec) { @@ -288,26 +305,9 @@ GetMethodID(Thread* t, jclass c, const char* name, const char* spec) object method = findMethod(t, c, name, spec); if (UNLIKELY(t->exception)) return 0; - if (classFlags(t, *c) & ACC_INTERFACE) { - PROTECT(t, method); + assert(t, (methodFlags(t, method) & ACC_STATIC) == 0); - ACQUIRE(t, t->m->referenceLock); - - for (unsigned i = 0; i < vectorSize(t, t->m->jniInterfaceTable); ++i) { - if (method == vectorBody(t, t->m->jniInterfaceTable, i)) { - return i; - } - } - - t->m->jniInterfaceTable - = vectorAppend(t, t->m->jniInterfaceTable, method); - - return (vectorSize(t, t->m->jniInterfaceTable) - 1) | InterfaceMethodID; - } else if (methodVirtual(t, method)) { - return methodOffset(t, method) + 1; - } else { - return methodOffset(t, method) | NonVirtualMethodID; - } + return methodID(t, method); } jmethodID JNICALL @@ -318,29 +318,19 @@ GetStaticMethodID(Thread* t, jclass c, const char* name, const char* spec) object method = findMethod(t, c, name, spec); if (UNLIKELY(t->exception)) return 0; - return methodOffset(t, method) + 1; + assert(t, methodFlags(t, method) & ACC_STATIC); + + return methodID(t, method); } inline object -getMethod(Thread* t, object o, jmethodID m) +getMethod(Thread* t, jmethodID m) { - if (m & InterfaceMethodID) { - return vectorBody(t, t->m->jniInterfaceTable, m & (~InterfaceMethodID)); - } else { - if (classVmFlags(t, objectClass(t, o)) & BootstrapFlag) { - PROTECT(t, o); + object method = vectorBody(t, t->m->jniMethodTable, m - 1); - resolveClass(t, className(t, objectClass(t, o))); - if (UNLIKELY(t->exception)) return 0; - } + assert(t, (methodFlags(t, method) & ACC_STATIC) == 0); - if (m & NonVirtualMethodID) { - return arrayBody(t, classMethodTable(t, objectClass(t, o)), - m & (~NonVirtualMethodID)); - } else { - return arrayBody(t, classVirtualTable(t, objectClass(t, o)), m - 1); - } - } + return method; } jobject JNICALL @@ -351,7 +341,7 @@ NewObjectV(Thread* t, jclass c, jmethodID m, va_list a) object o = make(t, *c); PROTECT(t, o); - t->m->processor->invokeList(t, getMethod(t, o, m), o, true, a); + t->m->processor->invokeList(t, getMethod(t, m), o, true, a); return makeLocalReference(t, o); } @@ -374,7 +364,7 @@ CallObjectMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); return makeLocalReference (t, t->m->processor->invokeList(t, method, *o, true, a)); } @@ -397,7 +387,7 @@ CallBooleanMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? false : (intValue(t, r) != 0)); } @@ -420,7 +410,7 @@ CallByteMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -443,7 +433,7 @@ CallCharMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -466,7 +456,7 @@ CallShortMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -489,7 +479,7 @@ CallIntMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -512,7 +502,7 @@ CallLongMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -535,7 +525,7 @@ CallFloatMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } @@ -558,7 +548,7 @@ CallDoubleMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); object r = t->m->processor->invokeList(t, method, *o, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } @@ -581,7 +571,7 @@ CallVoidMethodV(Thread* t, jobject o, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object method = getMethod(t, *o, m); + object method = getMethod(t, m); t->m->processor->invokeList(t, method, *o, true, a); } @@ -597,25 +587,22 @@ CallVoidMethod(Thread* t, jobject o, jmethodID m, ...) } inline object -getStaticMethod(Thread* t, object c, jmethodID m) +getStaticMethod(Thread* t, jmethodID m) { - if (classVmFlags(t, c) & BootstrapFlag) { - PROTECT(t, c); + object method = vectorBody(t, t->m->jniMethodTable, m - 1); - resolveClass(t, className(t, c)); - if (UNLIKELY(t->exception)) return 0; - } + assert(t, methodFlags(t, method) & ACC_STATIC); - return arrayBody(t, classMethodTable(t, c), m - 1); + return method; } jobject JNICALL -CallStaticObjectMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticObjectMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); return makeLocalReference(t, t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a)); + (t, getStaticMethod(t, m), 0, true, a)); } jobject JNICALL @@ -632,12 +619,11 @@ CallStaticObjectMethod(Thread* t, jclass c, jmethodID m, ...) } jboolean JNICALL -CallStaticBooleanMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticBooleanMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : (intValue(t, r) != 0)); } @@ -655,12 +641,11 @@ CallStaticBooleanMethod(Thread* t, jclass c, jmethodID m, ...) } jbyte JNICALL -CallStaticByteMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticByteMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -678,12 +663,11 @@ CallStaticByteMethod(Thread* t, jclass c, jmethodID m, ...) } jchar JNICALL -CallStaticCharMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticCharMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -701,12 +685,11 @@ CallStaticCharMethod(Thread* t, jclass c, jmethodID m, ...) } jshort JNICALL -CallStaticShortMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticShortMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -724,12 +707,11 @@ CallStaticShortMethod(Thread* t, jclass c, jmethodID m, ...) } jint JNICALL -CallStaticIntMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticIntMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : intValue(t, r)); } @@ -747,12 +729,11 @@ CallStaticIntMethod(Thread* t, jclass c, jmethodID m, ...) } jlong JNICALL -CallStaticLongMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticLongMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : longValue(t, r)); } @@ -770,12 +751,11 @@ CallStaticLongMethod(Thread* t, jclass c, jmethodID m, ...) } jfloat JNICALL -CallStaticFloatMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticFloatMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : bitsToFloat(intValue(t, r))); } @@ -793,12 +773,11 @@ CallStaticFloatMethod(Thread* t, jclass c, jmethodID m, ...) } jdouble JNICALL -CallStaticDoubleMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticDoubleMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - object r = t->m->processor->invokeList - (t, getStaticMethod(t, *c, m), 0, true, a); + object r = t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); return (t->exception ? 0 : bitsToDouble(longValue(t, r))); } @@ -816,11 +795,11 @@ CallStaticDoubleMethod(Thread* t, jclass c, jmethodID m, ...) } void JNICALL -CallStaticVoidMethodV(Thread* t, jclass c, jmethodID m, va_list a) +CallStaticVoidMethodV(Thread* t, jclass, jmethodID m, va_list a) { ENTER(t, Thread::ActiveState); - t->m->processor->invokeList(t, getStaticMethod(t, *c, m), 0, true, a); + t->m->processor->invokeList(t, getStaticMethod(t, m), 0, true, a); } void JNICALL diff --git a/src/machine.cpp b/src/machine.cpp index c622a35cf9..0b1840feb6 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1088,6 +1088,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) methodParameterFootprint(t, method), methodFlags(t, method), virtualCount++, + 0, methodName(t, method), methodSpec(t, method), class_, @@ -1538,7 +1539,7 @@ class HeapClient: public Heap::Client { v->visit(&(m->monitorMap)); v->visit(&(m->stringMap)); v->visit(&(m->types)); - v->visit(&(m->jniInterfaceTable)); + v->visit(&(m->jniMethodTable)); for (Reference* r = m->jniReferences; r; r = r->next) { v->visit(&(r->target)); @@ -1658,7 +1659,7 @@ Machine::Machine(System* system, Heap* heap, Finder* finder, monitorMap(0), stringMap(0), types(0), - jniInterfaceTable(0), + jniMethodTable(0), finalizers(0), tenuredFinalizers(0), finalizeQueue(0), @@ -1819,14 +1820,14 @@ Thread::init() m->monitorMap = makeWeakHashMap(this, 0, 0); m->stringMap = makeWeakHashMap(this, 0, 0); - m->jniInterfaceTable = makeVector(this, 0, 0, false); + m->jniMethodTable = makeVector(this, 0, 0, false); m->localThread->set(this); { object bootCode = makeCode(t, 0, 0, 0, 0, 0, 1, false); codeBody(t, bootCode, 0) = impdep1; object bootMethod = makeMethod - (t, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode, 0); + (t, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, bootCode, 0); PROTECT(t, bootMethod); #include "type-java-initializations.cpp" diff --git a/src/machine.h b/src/machine.h index 5ea5b5f996..0c4d841f74 100644 --- a/src/machine.h +++ b/src/machine.h @@ -1158,7 +1158,7 @@ class Machine { object monitorMap; object stringMap; object types; - object jniInterfaceTable; + object jniMethodTable; object finalizers; object tenuredFinalizers; object finalizeQueue;