From 4dc76a50a25f88bbb9681d68ad5648ccf04cf29b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 23 Jun 2014 17:17:13 -0600 Subject: [PATCH 1/2] fix case of JNIEnv::FindClass called from JNI_OnLoad If an JNI_OnLoad implementation calls FindClass when using the OpenJDK class library, the calling method on the Java stack will be ClassLoader.loadLibrary. However, we must use the class loader of the class attempting to load the library in this case, not the system classloader. Therefore, we now maintain a stack such that the latest class to load a library in the current thread is at the top, and we use that class whenever FindClass is called by ClassLoader.loadLibrary (via JNI_OnLoad). Note that this patch does not attempt to address the same problem for the Avian or Android class libraries, but the same strategy should work for them as well. --- src/avian/machine.h | 25 ++++++++++++++++ src/avian/target-fields.h | 60 +++++++++++++++++++-------------------- src/classpath-openjdk.cpp | 3 ++ src/continuations-x86.S | 16 +++++------ src/jnienv.cpp | 18 +++++++++--- src/machine.cpp | 1 + 6 files changed, 81 insertions(+), 42 deletions(-) diff --git a/src/avian/machine.h b/src/avian/machine.h index bfa222549e..0184d08f61 100644 --- a/src/avian/machine.h +++ b/src/avian/machine.h @@ -1421,6 +1421,30 @@ class Thread { SingleProtector protector; }; + class LibraryLoadStack: public AutoResource { + public: + LibraryLoadStack(Thread* t, object class_): + AutoResource(t), + next(t->libraryLoadStack), + class_(class_), + protector(t, &(this->class_)) + { + t->libraryLoadStack = this; + } + + ~LibraryLoadStack() { + t->libraryLoadStack = next; + } + + virtual void release() { + this->LibraryLoadStack::~LibraryLoadStack(); + } + + LibraryLoadStack* next; + object class_; + SingleProtector protector; + }; + class Checkpoint { public: Checkpoint(Thread* t): @@ -1516,6 +1540,7 @@ class Thread { unsigned heapOffset; Protector* protector; ClassInitStack* classInitStack; + LibraryLoadStack* libraryLoadStack; Resource* resource; Checkpoint* checkpoint; Runnable runnable; diff --git a/src/avian/target-fields.h b/src/avian/target-fields.h index 60e4c48c49..9efc1212e8 100644 --- a/src/avian/target-fields.h +++ b/src/avian/target-fields.h @@ -16,42 +16,42 @@ # if (TARGET_BYTES_PER_WORD == 8) #define TARGET_THREAD_EXCEPTION 80 -#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2256 -#define TARGET_THREAD_EXCEPTIONOFFSET 2264 -#define TARGET_THREAD_EXCEPTIONHANDLER 2272 +#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2264 +#define TARGET_THREAD_EXCEPTIONOFFSET 2272 +#define TARGET_THREAD_EXCEPTIONHANDLER 2280 -#define TARGET_THREAD_IP 2216 -#define TARGET_THREAD_STACK 2224 -#define TARGET_THREAD_NEWSTACK 2232 -#define TARGET_THREAD_SCRATCH 2240 -#define TARGET_THREAD_CONTINUATION 2248 -#define TARGET_THREAD_TAILADDRESS 2280 -#define TARGET_THREAD_VIRTUALCALLTARGET 2288 -#define TARGET_THREAD_VIRTUALCALLINDEX 2296 -#define TARGET_THREAD_HEAPIMAGE 2304 -#define TARGET_THREAD_CODEIMAGE 2312 -#define TARGET_THREAD_THUNKTABLE 2320 -#define TARGET_THREAD_STACKLIMIT 2368 +#define TARGET_THREAD_IP 2224 +#define TARGET_THREAD_STACK 2232 +#define TARGET_THREAD_NEWSTACK 2240 +#define TARGET_THREAD_SCRATCH 2248 +#define TARGET_THREAD_CONTINUATION 2256 +#define TARGET_THREAD_TAILADDRESS 2288 +#define TARGET_THREAD_VIRTUALCALLTARGET 2296 +#define TARGET_THREAD_VIRTUALCALLINDEX 2304 +#define TARGET_THREAD_HEAPIMAGE 2312 +#define TARGET_THREAD_CODEIMAGE 2320 +#define TARGET_THREAD_THUNKTABLE 2328 +#define TARGET_THREAD_STACKLIMIT 2376 # elif (TARGET_BYTES_PER_WORD == 4) #define TARGET_THREAD_EXCEPTION 44 -#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2164 -#define TARGET_THREAD_EXCEPTIONOFFSET 2168 -#define TARGET_THREAD_EXCEPTIONHANDLER 2172 +#define TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT 2168 +#define TARGET_THREAD_EXCEPTIONOFFSET 2172 +#define TARGET_THREAD_EXCEPTIONHANDLER 2176 -#define TARGET_THREAD_IP 2144 -#define TARGET_THREAD_STACK 2148 -#define TARGET_THREAD_NEWSTACK 2152 -#define TARGET_THREAD_SCRATCH 2156 -#define TARGET_THREAD_CONTINUATION 2160 -#define TARGET_THREAD_TAILADDRESS 2176 -#define TARGET_THREAD_VIRTUALCALLTARGET 2180 -#define TARGET_THREAD_VIRTUALCALLINDEX 2184 -#define TARGET_THREAD_HEAPIMAGE 2188 -#define TARGET_THREAD_CODEIMAGE 2192 -#define TARGET_THREAD_THUNKTABLE 2196 -#define TARGET_THREAD_STACKLIMIT 2220 +#define TARGET_THREAD_IP 2148 +#define TARGET_THREAD_STACK 2152 +#define TARGET_THREAD_NEWSTACK 2156 +#define TARGET_THREAD_SCRATCH 2160 +#define TARGET_THREAD_CONTINUATION 2164 +#define TARGET_THREAD_TAILADDRESS 2180 +#define TARGET_THREAD_VIRTUALCALLTARGET 2184 +#define TARGET_THREAD_VIRTUALCALLINDEX 2188 +#define TARGET_THREAD_HEAPIMAGE 2192 +#define TARGET_THREAD_CODEIMAGE 2196 +#define TARGET_THREAD_THUNKTABLE 2200 +#define TARGET_THREAD_STACKLIMIT 2224 # else # error diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index aa65c445a1..5eb5671f17 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -1845,6 +1845,9 @@ management_JNI_OnLoad(JavaVM*, void*); void JNICALL loadLibrary(Thread* t, object, uintptr_t* arguments) { + Thread::LibraryLoadStack stack + (t, jclassVmClass(t, reinterpret_cast(arguments[0]))); + object name = reinterpret_cast(arguments[1]); THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1); stringChars(t, name, RUNTIME_ARRAY_BODY(n)); diff --git a/src/continuations-x86.S b/src/continuations-x86.S index 071e4e7123..d088bdaf72 100644 --- a/src/continuations-x86.S +++ b/src/continuations-x86.S @@ -10,11 +10,11 @@ #ifdef __x86_64__ -#define THREAD_CONTINUATION 2248 +#define THREAD_CONTINUATION 2256 #define THREAD_EXCEPTION 80 -#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2256 -#define THREAD_EXCEPTION_OFFSET 2264 -#define THREAD_EXCEPTION_HANDLER 2272 +#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2264 +#define THREAD_EXCEPTION_OFFSET 2272 +#define THREAD_EXCEPTION_HANDLER 2280 #define CONTINUATION_NEXT 8 #define CONTINUATION_ADDRESS 32 @@ -91,11 +91,11 @@ LOCAL(vmInvoke_exit): #elif defined __i386__ -#define THREAD_CONTINUATION 2160 +#define THREAD_CONTINUATION 2164 #define THREAD_EXCEPTION 44 -#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2164 -#define THREAD_EXCEPTION_OFFSET 2168 -#define THREAD_EXCEPTION_HANDLER 2172 +#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2168 +#define THREAD_EXCEPTION_OFFSET 2172 +#define THREAD_EXCEPTION_HANDLER 2176 #define CONTINUATION_NEXT 4 #define CONTINUATION_ADDRESS 16 diff --git a/src/jnienv.cpp b/src/jnienv.cpp index be88848935..9f8e7c3fb8 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -349,10 +349,20 @@ findClass(Thread* t, uintptr_t* arguments) object caller = getCaller(t, 0); - object c = resolveClass(t, - caller ? classLoader(t, methodClass(t, caller)) - : root(t, Machine::AppLoader), - n); + object loader; + if (caller) { + if (methodClass(t, caller) == type(t, Machine::ClassLoaderType) + and t->libraryLoadStack) + { + loader = classLoader(t, t->libraryLoadStack->class_); + } else { + loader = classLoader(t, methodClass(t, caller)); + } + } else { + loader = root(t, Machine::AppLoader); + } + + object c = resolveClass(t, loader, n); if (t->m->classpath->mayInitClasses()) { PROTECT(t, c); diff --git a/src/machine.cpp b/src/machine.cpp index 93ddf5d5bc..33356f3ea5 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -3337,6 +3337,7 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent): heapOffset(0), protector(0), classInitStack(0), + libraryLoadStack(0), runnable(this), defaultHeap(static_cast (m->heap->allocate(ThreadHeapSizeInBytes))), From 5d3c612d0e3e7ad99d49683ac4c0f98b4cc3090b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 1 Jul 2014 10:18:45 -0600 Subject: [PATCH 2/2] fix JNIEnv::FindClass calls from JNI_OnLoad for all supported class libraries This also fixes the some Android build rot and updates the version of OpenSSL used. --- README.md | 19 +++-------- classpath/java/lang/ClassLoader.java | 5 ++- classpath/java/lang/Runtime.java | 6 ++-- classpath/java/lang/System.java | 4 +-- makefile | 3 ++ src/avian/machine.h | 14 ++++---- src/classpath-android.cpp | 19 +++++++++++ src/classpath-avian.cpp | 50 ++++++++++++++++++++++++---- src/classpath-openjdk.cpp | 31 +++++++++++++++-- src/continuations-x86.S | 40 ++++++++-------------- src/jnienv.cpp | 19 +++-------- test/JNI.java | 4 +++ test/jni.cpp | 18 ++++++++++ 13 files changed, 157 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 7bf40c33a2..baf68ce626 100644 --- a/README.md +++ b/README.md @@ -388,7 +388,7 @@ the following, starting from the Avian directory: git clone https://android.googlesource.com/platform/external/openssl \ external/openssl (cd external/openssl && \ - git checkout 7b972f1aa23172c4430ada7f3236fa1fd9b31756) + git checkout 1417357d893849c4b6afdd98c32b6ca1b4b19a8b) git clone https://android.googlesource.com/platform/external/zlib \ external/zlib @@ -396,12 +396,11 @@ the following, starting from the Avian directory: git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0) git clone git://git.openssl.org/openssl.git openssl-upstream - (cd openssl-upstream && \ - git checkout OpenSSL_1_0_1e) + (cd openssl-upstream && git checkout OpenSSL_1_0_1h) git clone https://github.com/dicej/android-libcore64 libcore - curl -Of http://oss.readytalk.com/avian/expat-2.1.0.tar.gz + curl -Of http://oss.readytalk.com/avian-web/expat-2.1.0.tar.gz (cd external && tar xzf ../expat-2.1.0.tar.gz && mv expat-2.1.0 expat) (cd external/expat && CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure \ @@ -417,16 +416,8 @@ NB: use 'CC="gcc -fPIC" ./Configure darwin64-x86_64-cc' when building for x86_64 OS X instead of 'CC="gcc -fPIC" ./config': (cd openssl-upstream \ - && (for x in \ - progs \ - handshake_cutthrough \ - jsse \ - channelid \ - eng_dyn_dirs \ - fix_clang_build \ - tls12_digests \ - alpn; \ - do patch -p1 < ../external/openssl/patches/$x.patch; done) \ + && (for x in ../external/openssl/patches/*.patch; \ + do patch -p1 < $x; done) \ && CC="gcc -fPIC" ./config && make) cd ../avian diff --git a/classpath/java/lang/ClassLoader.java b/classpath/java/lang/ClassLoader.java index c950a0dd74..0a75c98b6f 100644 --- a/classpath/java/lang/ClassLoader.java +++ b/classpath/java/lang/ClassLoader.java @@ -195,5 +195,8 @@ public abstract class ClassLoader { } return urls; } - + + static native Class getCaller(); + + static native void load(String name, Class caller, boolean mapName); } diff --git a/classpath/java/lang/Runtime.java b/classpath/java/lang/Runtime.java index f4f0e40718..863e0c4598 100644 --- a/classpath/java/lang/Runtime.java +++ b/classpath/java/lang/Runtime.java @@ -29,7 +29,7 @@ public class Runtime { public void load(String path) { if (path != null) { - load(path, false); + ClassLoader.load(path, ClassLoader.getCaller(), false); } else { throw new NullPointerException(); } @@ -37,7 +37,7 @@ public class Runtime { public void loadLibrary(String path) { if (path != null) { - load(path, true); + ClassLoader.load(path, ClassLoader.getCaller(), true); } else { throw new NullPointerException(); } @@ -120,8 +120,6 @@ public class Runtime { private static native int waitFor(long pid, long tid); - private static native void load(String name, boolean mapName); - private static native void kill(long pid); public native void gc(); diff --git a/classpath/java/lang/System.java b/classpath/java/lang/System.java index 7b8dd5cbb1..357ef92428 100644 --- a/classpath/java/lang/System.java +++ b/classpath/java/lang/System.java @@ -108,11 +108,11 @@ public abstract class System { private static native String doMapLibraryName(String name); public static void load(String path) { - Runtime.getRuntime().load(path); + ClassLoader.load(path, ClassLoader.getCaller(), false); } public static void loadLibrary(String name) { - Runtime.getRuntime().loadLibrary(name); + ClassLoader.load(name, ClassLoader.getCaller(), true); } public static void gc() { diff --git a/makefile b/makefile index b7afb7611e..33663cd29b 100755 --- a/makefile +++ b/makefile @@ -260,6 +260,9 @@ ifneq ($(android),) platform-lflags := -lgdi32 -lshlwapi -lwsock32 else android-cflags += -fPIC -DHAVE_SYS_UIO_H + blacklist = $(luni-native)/java_math_NativeBN.cpp + + luni-cpps := $(filter-out $(blacklist),$(luni-cpps)) icu-libs := $(android)/external/icu4c/lib/libicui18n.a \ $(android)/external/icu4c/lib/libicuuc.a \ $(android)/external/icu4c/lib/libicudata.a diff --git a/src/avian/machine.h b/src/avian/machine.h index 0184d08f61..f0cc3c3252 100644 --- a/src/avian/machine.h +++ b/src/avian/machine.h @@ -1423,11 +1423,11 @@ class Thread { class LibraryLoadStack: public AutoResource { public: - LibraryLoadStack(Thread* t, object class_): - AutoResource(t), - next(t->libraryLoadStack), - class_(class_), - protector(t, &(this->class_)) + LibraryLoadStack(Thread* t, object classLoader) + : AutoResource(t), + next(t->libraryLoadStack), + classLoader(classLoader), + protector(t, &(this->classLoader)) { t->libraryLoadStack = this; } @@ -1441,7 +1441,7 @@ class Thread { } LibraryLoadStack* next; - object class_; + object classLoader; SingleProtector protector; }; @@ -1610,6 +1610,8 @@ class Classpath { canTailCall(Thread* t, object caller, object calleeClassName, object calleeMethodName, object calleeMethodSpec) = 0; + virtual object libraryClassLoader(Thread* t, object caller) = 0; + virtual void shutDown(Thread* t) = 0; diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 99c2965ce7..7d9e6d3dc3 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -55,6 +55,8 @@ loadLibrary(Thread* t, object, uintptr_t* arguments) { object name = reinterpret_cast(arguments[1]); + Thread::LibraryLoadStack stack(t, reinterpret_cast(arguments[2])); + unsigned length = stringLength(t, name); THREAD_RUNTIME_ARRAY(t, char, n, length + 1); stringChars(t, name, RUNTIME_ARRAY_BODY(n)); @@ -568,6 +570,17 @@ class MyClasspath : public Classpath { return true; } + virtual object libraryClassLoader(Thread* t, object caller) + { + return strcmp( + "java/lang/Runtime", + reinterpret_cast( + &byteArrayBody(t, className(t, methodClass(t, caller)), 0))) + == 0 + ? t->libraryLoadStack->classLoader + : classLoader(t, methodClass(t, caller)); + } + virtual void shutDown(Thread*) { @@ -988,6 +1001,12 @@ register_org_apache_harmony_dalvik_NativeTestTarget(_JNIEnv*) return 0; } +int register_java_math_NativeBN(_JNIEnv*) +{ + // ignore + return 0; +} + extern "C" AVIAN_EXPORT int64_t JNICALL Avian_java_lang_String_compareTo (Thread* t, object, uintptr_t* arguments) diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index b7e2299adc..7bed10ce32 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -179,10 +179,37 @@ class MyClasspath : public Classpath { return fieldAtOffset(b, fieldOffset(t, field)); } - virtual bool - canTailCall(Thread*, object, object, object, object) + virtual bool canTailCall(Thread* t, + object, + object calleeClassName, + object calleeMethodName, + object) { - return true; + // we can't tail call System.load[Library] or + // Runtime.load[Library] due to their use of + // ClassLoader.getCaller, which gets confused if we elide stack + // frames. + + return ( + (strcmp("loadLibrary", + reinterpret_cast(&byteArrayBody(t, calleeMethodName, 0))) + and strcmp("load", + reinterpret_cast( + &byteArrayBody(t, calleeMethodName, 0)))) + or (strcmp( + "java/lang/System", + reinterpret_cast(&byteArrayBody(t, calleeClassName, 0))) + and strcmp("java/lang/Runtime", + reinterpret_cast( + &byteArrayBody(t, calleeClassName, 0))))); + } + + virtual object libraryClassLoader(Thread* t, object caller) + { + return (methodClass(t, caller) == type(t, Machine::ClassLoaderType) + and t->libraryLoadStack) + ? t->libraryLoadStack->classLoader + : classLoader(t, methodClass(t, caller)); } virtual void @@ -550,12 +577,23 @@ Avian_java_lang_System_identityHashCode } } +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_java_lang_ClassLoader_getCaller(Thread* t, object, uintptr_t*) +{ + return reinterpret_cast( + getJClass(t, methodClass(t, getCaller(t, 2)))); +} + extern "C" AVIAN_EXPORT void JNICALL -Avian_java_lang_Runtime_load -(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_ClassLoader_load(Thread* t, object, uintptr_t* arguments) { object name = reinterpret_cast(arguments[0]); - bool mapName = arguments[1]; + + Thread::LibraryLoadStack stack( + t, + classLoader(t, jclassVmClass(t, reinterpret_cast(arguments[1])))); + + bool mapName = arguments[2]; unsigned length = stringLength(t, name); THREAD_RUNTIME_ARRAY(t, char, n, length + 1); diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 5eb5671f17..6e63aa454f 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -844,6 +844,32 @@ class MyClasspath : public Classpath { (&byteArrayBody(t, calleeClassName, 0)))); } + virtual object libraryClassLoader(Thread* t, object caller) + { +#ifdef AVIAN_OPENJDK_SRC + return (methodClass(t, caller) == type(t, Machine::ClassLoaderType) + and t->libraryLoadStack) + ? t->libraryLoadStack->classLoader +#else + return strcmp( + "java/lang/ClassLoader$NativeLibrary", + reinterpret_cast( + &byteArrayBody(t, className(t, methodClass(t, caller)), 0))) + == 0 + ? classLoader( + t, + jclassVmClass(t, + t->m->processor->invoke( + t, + resolveMethod(t, + methodClass(t, caller), + "getFromClass", + "()Ljava/lang/Class;"), + 0))) +#endif + : classLoader(t, methodClass(t, caller)); + } + virtual void shutDown(Thread* t) { @@ -1845,8 +1871,9 @@ management_JNI_OnLoad(JavaVM*, void*); void JNICALL loadLibrary(Thread* t, object, uintptr_t* arguments) { - Thread::LibraryLoadStack stack - (t, jclassVmClass(t, reinterpret_cast(arguments[0]))); + Thread::LibraryLoadStack stack( + t, + classLoader(t, jclassVmClass(t, reinterpret_cast(arguments[0])))); object name = reinterpret_cast(arguments[1]); THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1); diff --git a/src/continuations-x86.S b/src/continuations-x86.S index d088bdaf72..53584090b8 100644 --- a/src/continuations-x86.S +++ b/src/continuations-x86.S @@ -10,12 +10,6 @@ #ifdef __x86_64__ -#define THREAD_CONTINUATION 2256 -#define THREAD_EXCEPTION 80 -#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2264 -#define THREAD_EXCEPTION_OFFSET 2272 -#define THREAD_EXCEPTION_HANDLER 2280 - #define CONTINUATION_NEXT 8 #define CONTINUATION_ADDRESS 32 #define CONTINUATION_RETURN_ADDRESS_OFFSET 40 @@ -24,7 +18,7 @@ #define CONTINUATION_BODY 64 // call the next continuation, if any - movq THREAD_CONTINUATION(%rbx),%rcx + movq TARGET_THREAD_CONTINUATION(%rbx),%rcx cmpq $0,%rcx je LOCAL(vmInvoke_exit) @@ -69,34 +63,28 @@ LOCAL(vmInvoke_continuationTest): // consume the continuation movq CONTINUATION_NEXT(%rcx),%rdi - movq %rdi,THREAD_CONTINUATION(%rbx) + movq %rdi,TARGET_THREAD_CONTINUATION(%rbx) // call the continuation unless we're handling an exception - movq THREAD_EXCEPTION(%rbx),%rsi + movq TARGET_THREAD_EXCEPTION(%rbx),%rsi cmpq $0,%rsi jne LOCAL(vmInvoke_handleException) jmp *CONTINUATION_ADDRESS(%rcx) LOCAL(vmInvoke_handleException): // we're handling an exception - call the exception handler instead - movq $0,THREAD_EXCEPTION(%rbx) - movq THREAD_EXCEPTION_STACK_ADJUSTMENT(%rbx),%rdi + movq $0,TARGET_THREAD_EXCEPTION(%rbx) + movq TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%rbx),%rdi subq %rdi,%rsp - movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi + movq TARGET_THREAD_EXCEPTIONOFFSET(%rbx),%rdi movq %rsi,(%rsp,%rdi,1) - jmp *THREAD_EXCEPTION_HANDLER(%rbx) + jmp *TARGET_THREAD_EXCEPTIONHANDLER(%rbx) LOCAL(vmInvoke_exit): #elif defined __i386__ -#define THREAD_CONTINUATION 2164 -#define THREAD_EXCEPTION 44 -#define THREAD_EXCEPTION_STACK_ADJUSTMENT 2168 -#define THREAD_EXCEPTION_OFFSET 2172 -#define THREAD_EXCEPTION_HANDLER 2176 - #define CONTINUATION_NEXT 4 #define CONTINUATION_ADDRESS 16 #define CONTINUATION_RETURN_ADDRESS_OFFSET 20 @@ -111,7 +99,7 @@ LOCAL(vmInvoke_exit): #endif // call the next continuation, if any - movl THREAD_CONTINUATION(%ebx),%ecx + movl TARGET_THREAD_CONTINUATION(%ebx),%ecx cmpl $0,%ecx je LOCAL(vmInvoke_exit) @@ -169,10 +157,10 @@ LOCAL(vmInvoke_offset): // consume the continuation movl CONTINUATION_NEXT(%ecx),%edi - movl %edi,THREAD_CONTINUATION(%ebx) + movl %edi,TARGET_THREAD_CONTINUATION(%ebx) // call the continuation unless we're handling an exception - movl THREAD_EXCEPTION(%ebx),%esi + movl TARGET_THREAD_EXCEPTION(%ebx),%esi cmpl $0,%esi jne LOCAL(vmInvoke_handleException) @@ -180,13 +168,13 @@ LOCAL(vmInvoke_offset): LOCAL(vmInvoke_handleException): // we're handling an exception - call the exception handler instead - movl $0,THREAD_EXCEPTION(%ebx) - movl THREAD_EXCEPTION_STACK_ADJUSTMENT(%ebx),%edi + movl $0,TARGET_THREAD_EXCEPTION(%ebx) + movl TARGET_THREAD_EXCEPTIONSTACKADJUSTMENT(%ebx),%edi subl %edi,%esp - movl THREAD_EXCEPTION_OFFSET(%ebx),%edi + movl TARGET_THREAD_EXCEPTIONOFFSET(%ebx),%edi movl %esi,(%esp,%edi,1) - jmp *THREAD_EXCEPTION_HANDLER(%ebx) + jmp *TARGET_THREAD_EXCEPTIONHANDLER(%ebx) LOCAL(vmInvoke_exit): diff --git a/src/jnienv.cpp b/src/jnienv.cpp index 9f8e7c3fb8..dda50462c1 100644 --- a/src/jnienv.cpp +++ b/src/jnienv.cpp @@ -349,20 +349,11 @@ findClass(Thread* t, uintptr_t* arguments) object caller = getCaller(t, 0); - object loader; - if (caller) { - if (methodClass(t, caller) == type(t, Machine::ClassLoaderType) - and t->libraryLoadStack) - { - loader = classLoader(t, t->libraryLoadStack->class_); - } else { - loader = classLoader(t, methodClass(t, caller)); - } - } else { - loader = root(t, Machine::AppLoader); - } - - object c = resolveClass(t, loader, n); + object c + = resolveClass(t, + caller ? t->m->classpath->libraryClassLoader(t, caller) + : root(t, Machine::AppLoader), + n); if (t->m->classpath->mayInitClasses()) { PROTECT(t, c); diff --git a/test/JNI.java b/test/JNI.java index 955bfc9052..a7fb40c62d 100644 --- a/test/JNI.java +++ b/test/JNI.java @@ -3,6 +3,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class JNI { + private static boolean onLoadCalled; + static { System.loadLibrary("test"); } @@ -64,6 +66,8 @@ public class JNI { public static final int field950 = 950; public static void main(String[] args) throws Exception { + expect(onLoadCalled); + expect(addDoubles (1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d, 10.0d, 11.0d, 12.0d, 13.0d, 14.0d, 15.0d, 16.0d, 17.0d, 18.0d, 19.0d, 20.0d) diff --git a/test/jni.cpp b/test/jni.cpp index 8b8d6dc8c9..6bc11e12c2 100644 --- a/test/jni.cpp +++ b/test/jni.cpp @@ -1,6 +1,24 @@ #include #include "jni-util.h" +extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) +{ + JNIEnv* e; + if (vm->GetEnv(reinterpret_cast(&e), JNI_VERSION_1_6) != JNI_OK) { + return -1; + } + + jclass c = e->FindClass("JNI"); + if (c == 0) { + return -1; + } + + e->SetStaticBooleanField( + c, e->GetStaticFieldID(c, "onLoadCalled", "Z"), true); + + return JNI_VERSION_1_6; +} + extern "C" JNIEXPORT jdouble JNICALL Java_JNI_addDoubles (JNIEnv*, jclass,