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.
This commit is contained in:
Joel Dice 2014-07-01 10:18:45 -06:00
parent 735eaaba21
commit 5d3c612d0e
13 changed files with 157 additions and 75 deletions

View File

@ -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

View File

@ -195,5 +195,8 @@ public abstract class ClassLoader {
}
return urls;
}
static native Class getCaller();
static native void load(String name, Class caller, boolean mapName);
}

View File

@ -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();

View File

@ -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() {

View File

@ -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

View File

@ -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;

View File

@ -55,6 +55,8 @@ loadLibrary(Thread* t, object, uintptr_t* arguments)
{
object name = reinterpret_cast<object>(arguments[1]);
Thread::LibraryLoadStack stack(t, reinterpret_cast<object>(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<char*>(
&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)

View File

@ -179,10 +179,37 @@ class MyClasspath : public Classpath {
return fieldAtOffset<int32_t>(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<char*>(&byteArrayBody(t, calleeMethodName, 0)))
and strcmp("load",
reinterpret_cast<char*>(
&byteArrayBody(t, calleeMethodName, 0))))
or (strcmp(
"java/lang/System",
reinterpret_cast<char*>(&byteArrayBody(t, calleeClassName, 0)))
and strcmp("java/lang/Runtime",
reinterpret_cast<char*>(
&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<int64_t>(
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<object>(arguments[0]);
bool mapName = arguments[1];
Thread::LibraryLoadStack stack(
t,
classLoader(t, jclassVmClass(t, reinterpret_cast<object>(arguments[1]))));
bool mapName = arguments[2];
unsigned length = stringLength(t, name);
THREAD_RUNTIME_ARRAY(t, char, n, length + 1);

View File

@ -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<char*>(
&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<object>(arguments[0])));
Thread::LibraryLoadStack stack(
t,
classLoader(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))));
object name = reinterpret_cast<object>(arguments[1]);
THREAD_RUNTIME_ARRAY(t, char, n, stringLength(t, name) + 1);

View File

@ -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):

View File

@ -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);

View File

@ -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)

View File

@ -1,6 +1,24 @@
#include <jni.h>
#include "jni-util.h"
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
JNIEnv* e;
if (vm->GetEnv(reinterpret_cast<void**>(&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,