diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index ff063982e6..a9e4c3a834 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -578,28 +578,33 @@ invoke(Thread* t, object method, object instance, object args) // running: void intercept(Thread* t, object c, const char* name, const char* spec, - void* function) + void* function, bool updateRuntimeData) { object m = findMethodOrNull(t, c, name, spec); if (m) { PROTECT(t, m); - object clone = methodClone(t, m); + object clone; + if (updateRuntimeData) { + clone = methodClone(t, m); - // make clone private to prevent vtable updates at compilation - // time. Otherwise, our interception might be bypassed by calls - // through the vtable. - methodFlags(t, clone) |= ACC_PRIVATE; + // make clone private to prevent vtable updates at compilation + // time. Otherwise, our interception might be bypassed by calls + // through the vtable. + methodFlags(t, clone) |= ACC_PRIVATE; + } methodFlags(t, m) |= ACC_NATIVE; - object native = makeNativeIntercept(t, function, true, clone); - - PROTECT(t, native); - - object runtimeData = getMethodRuntimeData(t, m); - - set(t, runtimeData, MethodRuntimeDataNative, native); + if (updateRuntimeData) { + object native = makeNativeIntercept(t, function, true, clone); + + PROTECT(t, native); + + object runtimeData = getMethodRuntimeData(t, m); + + set(t, runtimeData, MethodRuntimeDataNative, native); + } } else { // If we can't find the method, just ignore it, since ProGuard may // have stripped it out as unused. Otherwise, the code below can diff --git a/src/avian/machine.h b/src/avian/machine.h index b4409551c3..5c57bc18e2 100644 --- a/src/avian/machine.h +++ b/src/avian/machine.h @@ -1564,6 +1564,9 @@ class Classpath { virtual void resolveNative(Thread* t, object method) = 0; + virtual void + interceptMethods(Thread* t) = 0; + virtual void preBoot(Thread* t) = 0; diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 93af185a92..3098b7be8d 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -152,28 +152,6 @@ initVmThread(Thread* t, object thread) } } -void JNICALL -createThread(Thread* t, object method, uintptr_t* arguments) -{ - object thread = reinterpret_cast(arguments[0]); - PROTECT(t, thread); - - object group = reinterpret_cast(arguments[1]); - PROTECT(t, group); - - object name = reinterpret_cast(arguments[2]); - PROTECT(t, name); - - int64_t stackSize; memcpy(&stackSize, arguments + 3, 8); - - initVmThread(t, thread); - - t->m->processor->invoke - (t, nativeInterceptOriginal - (t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))), - thread, group, name, stackSize); -} - object translateStackTrace(Thread* t, object raw) { @@ -359,17 +337,9 @@ class MyClasspath : public Classpath { vm::resolveNative(t, method); } - virtual void - preBoot(Thread* t) + void + interceptMethods(Thread* t, bool updateRuntimeData) { - // Android's System.initSystemProperties throws an NPE if - // LD_LIBRARY_PATH is not set as of this writing: -#ifdef PLATFORM_WINDOWS - _wputenv(L"LD_LIBRARY_PATH=dummy"); -#else - setenv("LD_LIBRARY_PATH", "", false); -#endif - { object c = resolveClass (t, root(t, Machine::BootLoader), "java/lang/Runtime", false); @@ -378,7 +348,7 @@ class MyClasspath : public Classpath { intercept(t, c, "loadLibrary", "(Ljava/lang/String;Ljava/lang/ClassLoader;)V", - voidPointer(loadLibrary)); + voidPointer(loadLibrary), updateRuntimeData); } } @@ -389,7 +359,7 @@ class MyClasspath : public Classpath { PROTECT(t, c); intercept(t, c, "createSystemClassLoader", "()Ljava/lang/ClassLoader;", - voidPointer(appLoader)); + voidPointer(appLoader), updateRuntimeData); } } @@ -400,7 +370,7 @@ class MyClasspath : public Classpath { PROTECT(t, c); intercept(t, c, "mapData", "()Llibcore/io/MemoryMappedFile;", - voidPointer(mapData)); + voidPointer(mapData), updateRuntimeData); } } @@ -411,23 +381,31 @@ class MyClasspath : public Classpath { if (c) { PROTECT(t, c); - intercept(t, c, "close", "()V", voidPointer(closeMemoryMappedFile)); + intercept(t, c, "close", "()V", voidPointer(closeMemoryMappedFile), + updateRuntimeData); } } + } - { object c = resolveClass - (t, root(t, Machine::BootLoader), "java/lang/Thread", false); + virtual void + interceptMethods(Thread* t) + { + interceptMethods(t, false); + } - if (c) { - PROTECT(t, c); - - intercept(t, c, "create", - "(Ljava/lang/ThreadGroup;Ljava/lang/Runnable;" - "Ljava/lang/String;J)V", - voidPointer(createThread)); - } - } + virtual void + preBoot(Thread* t) + { + // Android's System.initSystemProperties throws an NPE if + // LD_LIBRARY_PATH is not set as of this writing: +#ifdef PLATFORM_WINDOWS + _wputenv(L"LD_LIBRARY_PATH=(dummy)"); +#else + setenv("LD_LIBRARY_PATH", "", false); +#endif + interceptMethods(t, true); + JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0); } @@ -1101,7 +1079,11 @@ extern "C" JNIEXPORT void JNICALL Avian_java_lang_VMThread_create (Thread* t, object, uintptr_t* arguments) { - startThread(t, reinterpret_cast(arguments[0])); + object thread = reinterpret_cast(arguments[0]); + PROTECT(t, thread); + + local::initVmThread(t, thread); + startThread(t, thread); } extern "C" JNIEXPORT void JNICALL @@ -1195,6 +1177,35 @@ Avian_java_lang_Math_sin return doubleToBits(sin(bitsToDouble(v))); } +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_sqrt +(Thread*, object, uintptr_t* arguments) +{ + int64_t v; memcpy(&v, arguments, 8); + return doubleToBits(sqrt(bitsToDouble(v))); +} + +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_abs__I +(Thread*, object, uintptr_t* arguments) +{ + return abs(static_cast(arguments[0])); +} + +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_abs__J +(Thread*, object, uintptr_t* arguments) +{ + return llabs(arguments[0]); +} + +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_abs__F +(Thread*, object, uintptr_t* arguments) +{ + return floatToBits(abs(bitsToFloat(arguments[0]))); +} + extern "C" JNIEXPORT int64_t JNICALL Avian_java_lang_Float_intBitsToFloat (Thread*, object, uintptr_t* arguments) diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index 5617b92070..64c56fc389 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -109,6 +109,12 @@ class MyClasspath : public Classpath { vm::resolveNative(t, method); } + virtual void + interceptMethods(Thread*) + { + // ignore + } + virtual void preBoot(Thread*) { diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index 6350ef5938..d50059ff2e 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -352,7 +352,7 @@ object makeJfield(Thread* t, object vmField, int index = -1); void -interceptFileOperations(Thread*); +interceptFileOperations(Thread*, bool); void clearInterrupted(Thread*); @@ -614,9 +614,16 @@ class MyClasspath : public Classpath { vm::notifyAll(t, t->javaThread); vm::release(t, t->javaThread); + object e = t->exception; + PROTECT(t, e); + + t->exception = 0; + t->m->processor->invoke (t, root(t, Machine::ThreadTerminated), threadGroup(t, t->javaThread), t->javaThread); + + t->exception = e; }); object method = resolveMethod @@ -643,6 +650,14 @@ class MyClasspath : public Classpath { vm::resolveNative(t, method); } + virtual void + interceptMethods(Thread* t UNUSED) + { +#ifdef AVIAN_OPENJDK_SRC + interceptFileOperations(t, false); +#endif + } + virtual void preBoot(Thread*) { @@ -662,7 +677,7 @@ class MyClasspath : public Classpath { "threadTerminated", "(Ljava/lang/Thread;)V")); #ifdef AVIAN_OPENJDK_SRC - interceptFileOperations(t); + interceptFileOperations(t, true); #else // not AVIAN_OPENJDK_SRC expect(t, loadLibrary(t, libraryPath, "verify", true, true)); expect(t, loadLibrary(t, libraryPath, "java", true, true)); @@ -1957,7 +1972,7 @@ loadLibrary(Thread* t, object, uintptr_t* arguments) } void -interceptFileOperations(Thread* t) +interceptFileOperations(Thread* t, bool updateRuntimeData) { MyClasspath* cp = static_cast(t->m->classpath); @@ -2000,22 +2015,22 @@ interceptFileOperations(Thread* t) cp->fileInputStreamFdField = fieldOffset(t, fileInputStreamFdField); intercept(t, fileInputStreamClass, "open", "(Ljava/lang/String;)V", - voidPointer(openFile)); + voidPointer(openFile), updateRuntimeData); intercept(t, fileInputStreamClass, "read", "()I", - voidPointer(readByteFromFile)); + voidPointer(readByteFromFile), updateRuntimeData); intercept(t, fileInputStreamClass, "readBytes", "([BII)I", - voidPointer(readBytesFromFile)); + voidPointer(readBytesFromFile), updateRuntimeData); intercept(t, fileInputStreamClass, "skip", "(J)J", - voidPointer(skipBytesInFile)); + voidPointer(skipBytesInFile), updateRuntimeData); intercept(t, fileInputStreamClass, "available", "()I", - voidPointer(availableBytesInFile)); + voidPointer(availableBytesInFile), updateRuntimeData); intercept(t, fileInputStreamClass, "close0", "()V", - voidPointer(closeFile)); + voidPointer(closeFile), updateRuntimeData); } } } @@ -2033,40 +2048,42 @@ interceptFileOperations(Thread* t) cp->zipFileJzfileField = fieldOffset(t, zipFileJzfileField); intercept(t, zipFileClass, "open", "(Ljava/lang/String;IJZ)J", - voidPointer(openZipFile)); + voidPointer(openZipFile), updateRuntimeData); intercept(t, zipFileClass, "getTotal", "(J)I", - voidPointer(getZipFileEntryCount)); + voidPointer(getZipFileEntryCount), updateRuntimeData); intercept(t, zipFileClass, "getEntry", "(J[BZ)J", - voidPointer(getZipFileEntry)); + voidPointer(getZipFileEntry), updateRuntimeData); intercept(t, zipFileClass, "getEntryBytes", "(JI)[B", - voidPointer(getZipFileEntryBytes)); + voidPointer(getZipFileEntryBytes), updateRuntimeData); intercept(t, zipFileClass, "getNextEntry", "(JI)J", - voidPointer(getNextZipFileEntry)); + voidPointer(getNextZipFileEntry), updateRuntimeData); intercept(t, zipFileClass, "getEntryMethod", "(J)I", - voidPointer(getZipFileEntryMethod)); + voidPointer(getZipFileEntryMethod), updateRuntimeData); intercept(t, zipFileClass, "freeEntry", "(JJ)V", - voidPointer(freeZipFileEntry)); + voidPointer(freeZipFileEntry), updateRuntimeData); intercept(t, zipFileClass, "read", "(JJJ[BII)I", - voidPointer(readZipFileEntry)); + voidPointer(readZipFileEntry), updateRuntimeData); intercept(t, zipFileClass, "getEntryCSize", "(J)J", - voidPointer(getZipFileEntryCompressedSize)); + voidPointer(getZipFileEntryCompressedSize), + updateRuntimeData); intercept(t, zipFileClass, "getEntrySize", "(J)J", - voidPointer(getZipFileEntryUncompressedSize)); + voidPointer(getZipFileEntryUncompressedSize), + updateRuntimeData); intercept(t, zipFileClass, "getZipMessage", "(J)Ljava/lang/String;", - voidPointer(getZipMessage)); + voidPointer(getZipMessage), updateRuntimeData); intercept(t, zipFileClass, "close", "(J)V", - voidPointer(closeZipFile)); + voidPointer(closeZipFile), updateRuntimeData); } } } @@ -2077,7 +2094,7 @@ interceptFileOperations(Thread* t) if (jarFileClass) { intercept(t, jarFileClass, "getMetaInfEntryNames", "()[Ljava/lang/String;", - voidPointer(getJarFileMetaInfEntryNames)); + voidPointer(getJarFileMetaInfEntryNames), updateRuntimeData); } } @@ -2097,27 +2114,27 @@ interceptFileOperations(Thread* t) PROTECT(t, fsClass); intercept(t, fsClass, gbaMethodName, "(Ljava/io/File;)I", - voidPointer(getFileAttributes)); + voidPointer(getFileAttributes), updateRuntimeData); intercept(t, fsClass, "checkAccess", "(Ljava/io/File;I)Z", - voidPointer(checkFileAccess)); + voidPointer(checkFileAccess), updateRuntimeData); intercept(t, fsClass, "getLength", "(Ljava/io/File;)J", - voidPointer(getFileLength)); + voidPointer(getFileLength), updateRuntimeData); } } intercept(t, type(t, Machine::ClassLoaderType), "loadLibrary", "(Ljava/lang/Class;Ljava/lang/String;Z)V", - voidPointer(loadLibrary)); + voidPointer(loadLibrary), updateRuntimeData); intercept(t, type(t, Machine::ClassLoaderType), "getBootstrapResource", "(Ljava/lang/String;)Ljava/net/URL;", - voidPointer(getBootstrapResource)); + voidPointer(getBootstrapResource), updateRuntimeData); intercept(t, type(t, Machine::ClassLoaderType), "getBootstrapResources", "(Ljava/lang/String;)Ljava/util/Enumeration;", - voidPointer(getBootstrapResources)); + voidPointer(getBootstrapResources), updateRuntimeData); } object diff --git a/src/tools/bootimage-generator/main.cpp b/src/tools/bootimage-generator/main.cpp index d27d250ab8..eac0b17de8 100644 --- a/src/tools/bootimage-generator/main.cpp +++ b/src/tools/bootimage-generator/main.cpp @@ -285,6 +285,8 @@ makeCodeImage(Thread* t, Zone* zone, BootImage* image, uint8_t* code, { PROTECT(t, typeMaps); + t->m->classpath->interceptMethods(t); + object constants = 0; PROTECT(t, constants);