From 686c2352c102fef3e0a09d4e513eed2d7b1aef6a Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 22 Feb 2013 17:23:59 -0700 Subject: [PATCH] all tests now pass for Android class library build --- makefile | 6 ++ src/classpath-android.cpp | 138 +++++++++++++++++++++++++++++++++++--- src/classpath-common.h | 43 ++++++++++++ src/classpath-openjdk.cpp | 43 ------------ 4 files changed, 178 insertions(+), 52 deletions(-) diff --git a/makefile b/makefile index 68a6fec003..cbe41b04f6 100755 --- a/makefile +++ b/makefile @@ -152,6 +152,7 @@ ifneq ($(android),) options := $(options)-android classpath-jar-dep = $(build)/android.dep luni-native = $(android)/libcore/luni/src/main/native + classpath-cflags = -DBOOT_JAVAHOME android-cflags := -I$(luni-native) \ -I$(android)/libnativehelper/include/nativehelper \ -I$(android)/core/include \ @@ -189,6 +190,11 @@ ifneq ($(android),) $(call java-classes,$(dalvik-javas),$(dalvik-java),$(build)/android) \ $(call java-classes,$(xml-javas),$(xml-java),$(build)/android) classpath = android + + javahome-files = tzdata + javahome-object = $(build)/javahome-jar.o + boot-javahome-object = $(build)/boot-javahome.o + build-javahome = $(android)/bionic/libc/zoneinfo endif ifeq ($(classpath),avian) diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 34455a4a51..bf753540b0 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -42,6 +42,12 @@ appLoader(Thread* t, object, uintptr_t*) return reinterpret_cast(root(t, Machine::AppLoader)); } +int64_t JNICALL +mapData(Thread*, object, uintptr_t*); + +void JNICALL +closeMemoryMappedFile(Thread*, object, uintptr_t*); + object makeMethodOrConstructor(Thread* t, object c, unsigned index) { @@ -319,29 +325,50 @@ class MyClasspath : public Classpath { virtual void preBoot(Thread* t) { - { object runtimeClass = resolveClass + { object c = resolveClass (t, root(t, Machine::BootLoader), "java/lang/Runtime", false); - if (runtimeClass) { - PROTECT(t, runtimeClass); + if (c) { + PROTECT(t, c); - intercept(t, runtimeClass, "loadLibrary", + intercept(t, c, "loadLibrary", "(Ljava/lang/String;Ljava/lang/ClassLoader;)V", voidPointer(loadLibrary)); } } - { object classLoaderClass = resolveClass + { object c = resolveClass (t, root(t, Machine::BootLoader), "java/lang/ClassLoader", false); - if (classLoaderClass) { - PROTECT(t, classLoaderClass); + if (c) { + PROTECT(t, c); - intercept(t, classLoaderClass, "createSystemClassLoader", - "()Ljava/lang/ClassLoader;", + intercept(t, c, "createSystemClassLoader", "()Ljava/lang/ClassLoader;", voidPointer(appLoader)); } } + + { object c = resolveClass + (t, root(t, Machine::BootLoader), "libcore/util/ZoneInfoDB", false); + + if (c) { + PROTECT(t, c); + + intercept(t, c, "mapData", "()Llibcore/io/MemoryMappedFile;", + voidPointer(mapData)); + } + } + + { object c = resolveClass + (t, root(t, Machine::BootLoader), "libcore/io/MemoryMappedFile", + false); + + if (c) { + PROTECT(t, c); + + intercept(t, c, "close", "()V", voidPointer(closeMemoryMappedFile)); + } + } JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0); } @@ -409,12 +436,78 @@ class MyClasspath : public Classpath { virtual void dispose() { + if (tzdata) { + tzdata->dispose(); + } allocator->free(this, sizeof(*this)); } Allocator* allocator; + System::Region* tzdata; }; +int64_t JNICALL +mapData(Thread* t, object, uintptr_t*) +{ + object c = resolveClass + (t, root(t, Machine::BootLoader), "libcore/io/MemoryMappedFile"); + PROTECT(t, c); + + object instance = makeNew(t, c); + PROTECT(t, instance); + + object constructor = resolveMethod(t, c, "", "(JJ)V"); + + const char* jar = "javahomeJar"; + Finder* finder = getFinder(t, jar, strlen(jar)); + if (finder) { + System::Region* r = finder->find("tzdata"); + if (r) { + MyClasspath* cp = static_cast(t->m->classpath); + + expect(t, cp->tzdata == 0); + + cp->tzdata = r; + + t->m->processor->invoke + (t, constructor, instance, reinterpret_cast(r->start()), + static_cast(r->length())); + + return reinterpret_cast(instance); + } + } + + throwNew(t, Machine::RuntimeExceptionType); +} + +void JNICALL +closeMemoryMappedFile(Thread* t, object method, uintptr_t* arguments) +{ + object file = reinterpret_cast(arguments[0]); + PROTECT(t, file); + + MyClasspath* cp = static_cast(t->m->classpath); + + if (cp->tzdata) { + object field = resolveField(t, objectClass(t, file), "address", "J"); + + if (fieldAtOffset(file, fieldOffset(t, field)) + == reinterpret_cast(cp->tzdata->start())) + { + cp->tzdata->dispose(); + cp->tzdata = 0; + + fieldAtOffset(file, fieldOffset(t, field)) = 0; + return; + } + } + + t->m->processor->invoke + (t, nativeInterceptOriginal + (t, methodRuntimeDataNative(t, getMethodRuntimeData(t, method))), + file); +} + } // namespace local } // namespace @@ -999,6 +1092,22 @@ Avian_java_lang_Math_floor return doubleToBits(floor(bitsToDouble(v))); } +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_ceil +(Thread*, object, uintptr_t* arguments) +{ + int64_t v; memcpy(&v, arguments, 8); + return doubleToBits(ceil(bitsToDouble(v))); +} + +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Math_log +(Thread*, object, uintptr_t* arguments) +{ + int64_t v; memcpy(&v, arguments, 8); + return doubleToBits(log(bitsToDouble(v))); +} + extern "C" JNIEXPORT int64_t JNICALL Avian_java_lang_Float_intBitsToFloat (Thread*, object, uintptr_t* arguments) @@ -1019,6 +1128,17 @@ Avian_java_lang_Float_floatToIntBits } } +extern "C" JNIEXPORT int64_t JNICALL +Avian_java_lang_Double_doubleToRawLongBits +(Thread*, object, uintptr_t* arguments) +{ + int64_t v; memcpy(&v, arguments, 8); + // todo: do we need to do NaN checks as in + // Avian_java_lang_Float_floatToIntBits above? If so, update + // Double.doubleToRawLongBits in the Avian class library too. + return v; +} + extern "C" JNIEXPORT void JNICALL Avian_java_lang_Object_wait (Thread* t, object, uintptr_t* arguments) diff --git a/src/classpath-common.h b/src/classpath-common.h index 8ad6bd30fb..c13d447386 100644 --- a/src/classpath-common.h +++ b/src/classpath-common.h @@ -612,6 +612,49 @@ intercept(Thread* t, object c, const char* name, const char* spec, } } +Finder* +getFinder(Thread* t, const char* name, unsigned nameLength) +{ + ACQUIRE(t, t->m->referenceLock); + + for (object p = root(t, Machine::VirtualFileFinders); + p; p = finderNext(t, p)) + { + if (byteArrayLength(t, finderName(t, p)) == nameLength + and strncmp(reinterpret_cast + (&byteArrayBody(t, finderName(t, p), 0)), + name, nameLength)) + { + return static_cast(finderFinder(t, p)); + } + } + + object n = makeByteArray(t, nameLength + 1); + memcpy(&byteArrayBody(t, n, 0), name, nameLength); + + void* p = t->m->libraries->resolve + (reinterpret_cast(&byteArrayBody(t, n, 0))); + + if (p) { + uint8_t* (*function)(unsigned*); + memcpy(&function, &p, BytesPerWord); + + unsigned size; + uint8_t* data = function(&size); + if (data) { + Finder* f = makeFinder(t->m->system, t->m->heap, data, size); + object finder = makeFinder + (t, f, n, root(t, Machine::VirtualFileFinders)); + + setRoot(t, Machine::VirtualFileFinders, finder); + + return f; + } + } + + return 0; +} + } // namespace vm #endif//CLASSPATH_COMMON_H diff --git a/src/classpath-openjdk.cpp b/src/classpath-openjdk.cpp index ea49d403d3..1b44fdada5 100644 --- a/src/classpath-openjdk.cpp +++ b/src/classpath-openjdk.cpp @@ -886,49 +886,6 @@ struct jvm_version_info { unsigned: 32; }; -Finder* -getFinder(Thread* t, const char* name, unsigned nameLength) -{ - ACQUIRE(t, t->m->referenceLock); - - for (object p = root(t, Machine::VirtualFileFinders); - p; p = finderNext(t, p)) - { - if (byteArrayLength(t, finderName(t, p)) == nameLength - and strncmp(reinterpret_cast - (&byteArrayBody(t, finderName(t, p), 0)), - name, nameLength)) - { - return static_cast(finderFinder(t, p)); - } - } - - object n = makeByteArray(t, nameLength + 1); - memcpy(&byteArrayBody(t, n, 0), name, nameLength); - - void* p = t->m->libraries->resolve - (reinterpret_cast(&byteArrayBody(t, n, 0))); - - if (p) { - uint8_t* (*function)(unsigned*); - memcpy(&function, &p, BytesPerWord); - - unsigned size; - uint8_t* data = function(&size); - if (data) { - Finder* f = makeFinder(t->m->system, t->m->heap, data, size); - object finder = makeFinder - (t, f, n, root(t, Machine::VirtualFileFinders)); - - setRoot(t, Machine::VirtualFileFinders, finder); - - return f; - } - } - - return 0; -} - bool pathEqual(const char* a, const char* b, unsigned length) {