all tests now pass for Android class library build

This commit is contained in:
Joel Dice 2013-02-22 17:23:59 -07:00
parent 0a4a04cc09
commit 686c2352c1
4 changed files with 178 additions and 52 deletions

View File

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

View File

@ -42,6 +42,12 @@ appLoader(Thread* t, object, uintptr_t*)
return reinterpret_cast<uintptr_t>(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, "<init>", "(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<MyClasspath*>(t->m->classpath);
expect(t, cp->tzdata == 0);
cp->tzdata = r;
t->m->processor->invoke
(t, constructor, instance, reinterpret_cast<int64_t>(r->start()),
static_cast<int64_t>(r->length()));
return reinterpret_cast<uintptr_t>(instance);
}
}
throwNew(t, Machine::RuntimeExceptionType);
}
void JNICALL
closeMemoryMappedFile(Thread* t, object method, uintptr_t* arguments)
{
object file = reinterpret_cast<object>(arguments[0]);
PROTECT(t, file);
MyClasspath* cp = static_cast<MyClasspath*>(t->m->classpath);
if (cp->tzdata) {
object field = resolveField(t, objectClass(t, file), "address", "J");
if (fieldAtOffset<int64_t>(file, fieldOffset(t, field))
== reinterpret_cast<int64_t>(cp->tzdata->start()))
{
cp->tzdata->dispose();
cp->tzdata = 0;
fieldAtOffset<int64_t>(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)

View File

@ -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<const char*>
(&byteArrayBody(t, finderName(t, p), 0)),
name, nameLength))
{
return static_cast<Finder*>(finderFinder(t, p));
}
}
object n = makeByteArray(t, nameLength + 1);
memcpy(&byteArrayBody(t, n, 0), name, nameLength);
void* p = t->m->libraries->resolve
(reinterpret_cast<const char*>(&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

View File

@ -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<const char*>
(&byteArrayBody(t, finderName(t, p), 0)),
name, nameLength))
{
return static_cast<Finder*>(finderFinder(t, p));
}
}
object n = makeByteArray(t, nameLength + 1);
memcpy(&byteArrayBody(t, n, 0), name, nameLength);
void* p = t->m->libraries->resolve
(reinterpret_cast<const char*>(&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)
{