From b96cc3c575670fefc8b174660cdc2902a108e217 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 21 Aug 2014 13:09:42 -0600 Subject: [PATCH 1/7] update to more recent version of Android class library Lots has changed since we forked Android's libcore, so merging the latest upstream code has required extensive changes to the Avian/Android port. One big change is that we now use Avian's versions of java.lang.Object, java.lang.Class, java.lang.ClassLoader, some java.lang.reflect.* classes, etc. instead of the Android versions. The main reason is that the Android versions have become very Dex/Dalvik-specific, and since Avian is based on Java class files, not dex archives, that code doesn't make sense here. This has the side benefit that we can share more native code with classpath-avian.cpp and reduce the amount of Java/C++ code duplication. --- README.md | 8 +- classpath/avian/Classes.java | 2 + .../dalvik/system/BaseDexClassLoader.java | 5 + classpath/java/lang/Class.java | 27 +- classpath/java/lang/ClassLoader.java | 11 + classpath/java/lang/reflect/Constructor.java | 8 + classpath/java/lang/reflect/Field.java | 4 +- .../java/lang/reflect/GenericDeclaration.java | 5 + classpath/java/lang/reflect/Member.java | 2 + classpath/java/lang/reflect/Method.java | 16 +- classpath/java/lang/reflect/TypeVariable.java | 5 + .../libcore/reflect/AnnotationAccess.java | 8 + classpath/sun/misc/Unsafe.java | 8 + makefile | 106 +- src/avian/classpath-common.h | 110 ++ src/builtin.cpp | 12 + src/classpath-android.cpp | 1456 +++-------------- src/classpath-avian.cpp | 140 +- src/machine.cpp | 2 + test/Misc.java | 12 +- test/ci.sh | 2 +- 21 files changed, 556 insertions(+), 1393 deletions(-) create mode 100644 classpath/dalvik/system/BaseDexClassLoader.java create mode 100644 classpath/java/lang/reflect/GenericDeclaration.java create mode 100644 classpath/java/lang/reflect/TypeVariable.java create mode 100644 classpath/libcore/reflect/AnnotationAccess.java diff --git a/README.md b/README.md index a33af84539..849fdf71cb 100644 --- a/README.md +++ b/README.md @@ -370,7 +370,7 @@ the following, starting from the Avian directory: git clone https://android.googlesource.com/platform/system/core \ system/core (cd system/core && \ - git checkout fafcabd0dd4432de3c7f5956edec23f6ed241b56) + git checkout 373c77583f9d8eab88e4321d1a2e2af8f5ae8ea7) git clone https://android.googlesource.com/platform/external/fdlibm \ external/fdlibm @@ -380,11 +380,11 @@ the following, starting from the Avian directory: git clone https://android.googlesource.com/platform/external/icu4c \ external/icu4c (cd external/icu4c && \ - git checkout 8fd45e08f1054d80a356ef8aa05659a2ba84707c) + git checkout e5311394ca22b280da41cd17059288dab3fb1ea6) git clone https://android.googlesource.com/platform/libnativehelper (cd libnativehelper && \ - git checkout cf5ac0ec696fce7fac6b324ec7d4d6da217e501c) + git checkout b14825c7c75420049e03849994265be651cc4a4e) git clone https://android.googlesource.com/platform/external/openssl \ external/openssl @@ -400,6 +400,8 @@ the following, starting from the Avian directory: (cd openssl-upstream && git checkout OpenSSL_1_0_1h) git clone https://github.com/dicej/android-libcore64 libcore + (cd libcore && \ + git checkout 69a1fd8623b85f978ead36dcf1c6c78c5ff79932) 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) diff --git a/classpath/avian/Classes.java b/classpath/avian/Classes.java index f912971688..dec14d1966 100644 --- a/classpath/avian/Classes.java +++ b/classpath/avian/Classes.java @@ -559,4 +559,6 @@ public class Classes { private static native void acquireClassLock(); private static native void releaseClassLock(); + + public static native String makeString(byte[] array, int offset, int length); } diff --git a/classpath/dalvik/system/BaseDexClassLoader.java b/classpath/dalvik/system/BaseDexClassLoader.java new file mode 100644 index 0000000000..27049cea21 --- /dev/null +++ b/classpath/dalvik/system/BaseDexClassLoader.java @@ -0,0 +1,5 @@ +package dalvik.system; + +public class BaseDexClassLoader extends ClassLoader { + public native String getLdLibraryPath(); +} diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index ef38e6ec66..93ac0d77f5 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -18,10 +18,12 @@ import avian.Classes; import avian.InnerClassReference; import java.lang.reflect.Constructor; +import java.lang.reflect.GenericDeclaration; import java.lang.reflect.Method; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -38,7 +40,9 @@ import java.security.ProtectionDomain; import java.security.Permissions; import java.security.AllPermission; -public final class Class implements Type, AnnotatedElement { +public final class Class + implements Type, AnnotatedElement, GenericDeclaration +{ private static final int PrimitiveFlag = 1 << 5; private static final int EnumFlag = 1 << 14; @@ -96,9 +100,8 @@ public final class Class implements Type, AnnotatedElement { } } - return new String - (replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1, - false); + return Classes.makeString + (replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1); } public String getCanonicalName() { @@ -496,6 +499,10 @@ public final class Class implements Type, AnnotatedElement { return (vmClass.flags & Modifier.INTERFACE) != 0; } + public boolean isAnnotation() { + return (vmClass.flags & 0x2000) != 0; + } + public Class getSuperclass() { return (vmClass.super_ == null ? null : SystemClassLoader.getClass(vmClass.super_)); } @@ -523,8 +530,8 @@ public final class Class implements Type, AnnotatedElement { public URL getResource(String path) { if (! path.startsWith("/")) { - String name = new String - (vmClass.name, 0, vmClass.name.length - 1, false); + String name = Classes.makeString + (vmClass.name, 0, vmClass.name.length - 1); int index = name.lastIndexOf('/'); if (index >= 0) { path = name.substring(0, index) + "/" + path; @@ -647,4 +654,12 @@ public final class Class implements Type, AnnotatedElement { public ProtectionDomain getProtectionDomain() { return Classes.getProtectionDomain(vmClass); } + + public TypeVariable[] getTypeParameters() { + throw new UnsupportedOperationException("not yet implemented"); + } + + public Type[] getGenericInterfaces() { + throw new UnsupportedOperationException("not yet implemented"); + } } diff --git a/classpath/java/lang/ClassLoader.java b/classpath/java/lang/ClassLoader.java index 0a75c98b6f..8f7ec5a1f9 100644 --- a/classpath/java/lang/ClassLoader.java +++ b/classpath/java/lang/ClassLoader.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.Map; import java.util.HashMap; +import java.security.ProtectionDomain; public abstract class ClassLoader { private final ClassLoader parent; @@ -92,6 +93,12 @@ public abstract class ClassLoader { (avian.Classes.defineVMClass(this, b, offset, length)); } + protected Class defineClass(String name, byte[] b, int offset, int length, + ProtectionDomain domain) + { + return defineClass(name, b, offset, length); + } + protected Class findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(); } @@ -196,6 +203,10 @@ public abstract class ClassLoader { return urls; } + protected String findLibrary(String name) { + return null; + } + static native Class getCaller(); static native void load(String name, Class caller, boolean mapName); diff --git a/classpath/java/lang/reflect/Constructor.java b/classpath/java/lang/reflect/Constructor.java index e28b56c1be..c320350846 100644 --- a/classpath/java/lang/reflect/Constructor.java +++ b/classpath/java/lang/reflect/Constructor.java @@ -44,6 +44,10 @@ public class Constructor extends AccessibleObject implements Member { return method.getModifiers(); } + public boolean isSynthetic() { + return method.isSynthetic(); + } + public String getName() { return method.getName(); } @@ -70,4 +74,8 @@ public class Constructor extends AccessibleObject implements Member { method.invoke(v, arguments); return v; } + + public Class[] getExceptionTypes() { + throw new UnsupportedOperationException("not yet implemented"); + } } diff --git a/classpath/java/lang/reflect/Field.java b/classpath/java/lang/reflect/Field.java index eb5303e742..c66a3f9bc9 100644 --- a/classpath/java/lang/reflect/Field.java +++ b/classpath/java/lang/reflect/Field.java @@ -57,13 +57,13 @@ public class Field extends AccessibleObject { } public static String getName(VMField vmField) { - return new String(vmField.name, 0, vmField.name.length - 1, false); + return Classes.makeString(vmField.name, 0, vmField.name.length - 1); } public Class getType() { return Classes.forCanonicalName (vmField.class_.loader, - new String(vmField.spec, 0, vmField.spec.length - 1, false)); + Classes.makeString(vmField.spec, 0, vmField.spec.length - 1)); } public Type getGenericType() { diff --git a/classpath/java/lang/reflect/GenericDeclaration.java b/classpath/java/lang/reflect/GenericDeclaration.java new file mode 100644 index 0000000000..d167aeb549 --- /dev/null +++ b/classpath/java/lang/reflect/GenericDeclaration.java @@ -0,0 +1,5 @@ +package java.lang.reflect; + +public interface GenericDeclaration { + TypeVariable[] getTypeParameters(); +} diff --git a/classpath/java/lang/reflect/Member.java b/classpath/java/lang/reflect/Member.java index 7f8dc10595..a21d231ff0 100644 --- a/classpath/java/lang/reflect/Member.java +++ b/classpath/java/lang/reflect/Member.java @@ -19,4 +19,6 @@ public interface Member { public int getModifiers(); public String getName(); + + public boolean isSynthetic(); } diff --git a/classpath/java/lang/reflect/Method.java b/classpath/java/lang/reflect/Method.java index 6a8e8e189d..4c6443e488 100644 --- a/classpath/java/lang/reflect/Method.java +++ b/classpath/java/lang/reflect/Method.java @@ -52,7 +52,7 @@ public class Method extends AccessibleObject implements Member { } public static String getName(VMMethod vmMethod) { - return new String(vmMethod.name, 0, vmMethod.name.length - 1, false); + return Classes.makeString(vmMethod.name, 0, vmMethod.name.length - 1); } private String getSpec() { @@ -60,7 +60,7 @@ public class Method extends AccessibleObject implements Member { } public static String getSpec(VMMethod vmMethod) { - return new String(vmMethod.spec, 0, vmMethod.spec.length - 1, false); + return Classes.makeString(vmMethod.spec, 0, vmMethod.spec.length - 1); } public Class[] getParameterTypes() { @@ -107,8 +107,8 @@ public class Method extends AccessibleObject implements Member { if (vmMethod.spec[i] == ')') { return Classes.forCanonicalName (vmMethod.class_.loader, - new String - (vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false)); + Classes.makeString + (vmMethod.spec, i + 1, vmMethod.spec.length - i - 2)); } } throw new RuntimeException(); @@ -149,8 +149,16 @@ public class Method extends AccessibleObject implements Member { return (getModifiers() & 0x80) != 0; } + public boolean isSynthetic() { + return (getModifiers() & 0x1000) != 0; + } + public Object getDefaultValue() { ClassLoader loader = getDeclaringClass().getClassLoader(); return Classes.getAnnotationDefaultValue(loader, vmMethod.addendum); } + + public Class[] getExceptionTypes() { + throw new UnsupportedOperationException("not yet implemented"); + } } diff --git a/classpath/java/lang/reflect/TypeVariable.java b/classpath/java/lang/reflect/TypeVariable.java new file mode 100644 index 0000000000..63f9dcb499 --- /dev/null +++ b/classpath/java/lang/reflect/TypeVariable.java @@ -0,0 +1,5 @@ +package java.lang.reflect; + +public interface TypeVariable extends Type { + +} diff --git a/classpath/libcore/reflect/AnnotationAccess.java b/classpath/libcore/reflect/AnnotationAccess.java new file mode 100644 index 0000000000..750fe9cadf --- /dev/null +++ b/classpath/libcore/reflect/AnnotationAccess.java @@ -0,0 +1,8 @@ +package libcore.reflect; + +import java.lang.reflect.AccessibleObject; + +public class AnnotationAccess { + public static native AccessibleObject getEnclosingMethodOrConstructor + (Class c); +} diff --git a/classpath/sun/misc/Unsafe.java b/classpath/sun/misc/Unsafe.java index 10325b04b1..6d733aa801 100644 --- a/classpath/sun/misc/Unsafe.java +++ b/classpath/sun/misc/Unsafe.java @@ -88,6 +88,14 @@ public final class Unsafe { public native void putLongVolatile(Object o, long offset, long x); + public long getLong(Object o, long offset) { + return getLongVolatile(o, offset); + } + + public void putLong(Object o, long offset, long x) { + putLongVolatile(o, offset, x); + } + public native void putOrderedLong(Object o, long offset, long x); public native void putOrderedInt(Object o, long offset, int x); diff --git a/makefile b/makefile index 2e004f3bde..45f70d2875 100755 --- a/makefile +++ b/makefile @@ -219,6 +219,7 @@ ifneq ($(android),) classpath-cflags = -DBOOT_JAVAHOME android-cflags = -I$(luni-native) \ -I$(android)/libnativehelper/include/nativehelper \ + -I$(android)/libnativehelper \ -I$(android)/system/core/include \ -I$(android)/external/zlib \ -I$(android)/external/icu4c/i18n \ @@ -234,33 +235,34 @@ ifneq ($(android),) -DJNI_JARJAR_PREFIX= \ -D__DARWIN_UNIX03=1 \ -D__PROVIDE_FIXMES \ + -DHAVE_OFF64_T \ -g3 \ -Werror luni-cpps := $(shell find $(luni-native) -name '*.cpp') + libziparchive-native := $(android)/system/core/libziparchive + libziparchive-ccs := $(libziparchive-native)/zip_archive.cc + + libutils-native := $(android)/system/core/libutils + libutils-cpps := $(libutils-native)/FileMap.cpp + libnativehelper-native := $(android)/libnativehelper libnativehelper-cpps := $(libnativehelper-native)/JniConstants.cpp \ $(libnativehelper-native)/toStringArray.cpp - crypto-native := $(android)/libcore/crypto/src/main/native - - crypto-cpps := $(crypto-native)/org_conscrypt_NativeCrypto.cpp - ifeq ($(platform),windows) - android-cflags += -D__STDC_CONSTANT_MACROS + android-cflags += -D__STDC_CONSTANT_MACROS -DHAVE_WIN32_FILEMAP blacklist = $(luni-native)/java_io_Console.cpp \ - $(luni-native)/java_lang_ProcessManager.cpp \ - $(luni-native)/java_math_NativeBN.cpp \ - $(luni-native)/libcore_net_RawSocket.cpp + $(luni-native)/java_lang_ProcessManager.cpp icu-libs := $(android)/external/icu4c/lib/sicuin.a \ $(android)/external/icu4c/lib/sicuuc.a \ $(android)/external/icu4c/lib/sicudt.a platform-lflags := -lgdi32 -lshlwapi -lwsock32 else - android-cflags += -fPIC -DHAVE_SYS_UIO_H - blacklist = $(luni-native)/java_math_NativeBN.cpp + android-cflags += -fPIC -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP + blacklist = icu-libs := $(android)/external/icu4c/lib/libicui18n.a \ $(android)/external/icu4c/lib/libicuuc.a \ @@ -272,8 +274,8 @@ ifneq ($(android),) $(icu-libs) \ $(android)/external/fdlibm/libfdm.a \ $(android)/external/expat/.libs/libexpat.a \ - $(android)/openssl-upstream/libssl.a \ $(android)/openssl-upstream/libcrypto.a \ + $(android)/openssl-upstream/libssl.a \ $(platform-lflags) \ -lstdc++ @@ -283,25 +285,46 @@ ifneq ($(android),) classpath-objects = \ $(call cpp-objects,$(luni-cpps),$(luni-native),$(build)) \ - $(call cpp-objects,$(crypto-cpps),$(crypto-native),$(build)) \ - $(call cpp-objects,$(libnativehelper-cpps),$(libnativehelper-native),$(build)) + $(call cpp-objects,$(libnativehelper-cpps),$(libnativehelper-native),$(build)) \ + $(call cc-objects,$(libziparchive-ccs),$(libziparchive-native),$(build)) \ + $(call cpp-objects,$(libutils-cpps),$(libutils-native),$(build)) luni-java = $(android)/libcore/luni/src/main/java - luni-javas := $(shell find $(luni-java) -name '*.java') + + luni-blacklist = \ + $(luni-java)/libcore/reflect/AnnotationAccess.java + + luni-javas := \ + $(filter-out $(luni-blacklist),$(shell find $(luni-java) -name '*.java')) + luni-nonjavas := $(shell find $(luni-java) -not -type d -not -name '*.java') luni-copied-nonjavas = $(call noop-files,$(luni-nonjavas),$(luni-java),) - libdvm-java = $(android)/libcore/libdvm/src/main/java - libdvm-javas := $(shell find $(libdvm-java) -name '*.java') - crypto-java = $(android)/libcore/crypto/src/main/java - crypto-javas := $(shell find $(crypto-java) -name '*.java') + dalvik-java = $(android)/libcore/dalvik/src/main/java - dalvik-javas := $(shell find $(dalvik-java) -name '*.java') + dalvik-javas := \ + $(dalvik-java)/dalvik/system/DalvikLogHandler.java \ + $(dalvik-java)/dalvik/system/CloseGuard.java \ + $(dalvik-java)/dalvik/system/VMDebug.java \ + $(dalvik-java)/dalvik/system/BlockGuard.java \ + $(dalvik-java)/dalvik/system/SocketTagger.java \ + $(dalvik-java)/dalvik/system/DalvikLogging.java \ + + libart-java = $(android)/libcore/libart/src/main/java + libart-javas := \ + $(libart-java)/dalvik/system/VMRuntime.java \ + $(libart-java)/dalvik/system/VMStack.java \ + $(libart-java)/java/lang/Thread.java \ + $(libart-java)/java/lang/ThreadGroup.java \ + $(libart-java)/java/lang/Enum.java \ + $(libart-java)/java/lang/String.java \ + $(libart-java)/java/lang/ref/Reference.java \ + $(libart-java)/java/lang/reflect/AccessibleObject.java \ + xml-java = $(android)/libcore/xml/src/main/java xml-javas := $(shell find $(xml-java) -name '*.java') android-classes = \ $(call java-classes,$(luni-javas),$(luni-java),$(build)/android) \ - $(call java-classes,$(libdvm-javas),$(libdvm-java),$(build)/android) \ - $(call java-classes,$(crypto-javas),$(crypto-java),$(build)/android) \ $(call java-classes,$(dalvik-javas),$(dalvik-java),$(build)/android) \ + $(call java-classes,$(libart-javas),$(libart-java),$(build)/android) \ $(call java-classes,$(xml-javas),$(xml-java),$(build)/android) classpath = android @@ -1113,6 +1136,7 @@ endif c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x))) cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(3)/%.o,$(x))) +cc-objects = $(foreach x,$(1),$(patsubst $(2)/%.cc,$(3)/%.o,$(x))) asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.$(asm-format),$(3)/%-asm.o,$(x))) java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x))) noop-files = $(foreach x,$(1),$(patsubst $(2)/%,$(3)/%,$(x))) @@ -1383,13 +1407,23 @@ ifneq ($(classpath),avian) ifeq ($(openjdk),) classpath-sources := $(classpath-sources) \ + $(classpath-src)/dalvik/system/BaseDexClassLoader.java \ + $(classpath-src)/libcore/reflect/AnnotationAccess.java \ $(classpath-src)/sun/reflect/ConstantPool.java \ - $(classpath-src)/java/lang/ReflectiveOperationException.java \ $(classpath-src)/java/net/ProtocolFamily.java \ $(classpath-src)/java/net/StandardProtocolFamily.java \ $(classpath-src)/sun/misc/Cleaner.java \ $(classpath-src)/sun/misc/Unsafe.java \ - $(classpath-src)/java/lang/reflect/Proxy.java + $(classpath-src)/java/lang/Object.java \ + $(classpath-src)/java/lang/Class.java \ + $(classpath-src)/java/lang/ClassLoader.java \ + $(classpath-src)/java/lang/Package.java \ + $(classpath-src)/java/lang/reflect/Proxy.java \ + $(classpath-src)/java/lang/reflect/Field.java \ + $(classpath-src)/java/lang/reflect/SignatureParser.java \ + $(classpath-src)/java/lang/reflect/Constructor.java \ + $(classpath-src)/java/lang/reflect/AccessibleObject.java \ + $(classpath-src)/java/lang/reflect/Method.java endif else classpath-sources := $(shell find $(classpath-src) -name '*.java') @@ -1590,7 +1624,10 @@ $(build)/android-src/%.cpp: $(luni-native)/%.cpp $(build)/android-src/%.cpp: $(libnativehelper-native)/%.cpp cp $(<) $(@) -$(build)/android-src/%.cpp: $(crypto-native)/%.cpp +$(build)/android-src/%.cpp: $(libziparchive-native)/%.cc + cp $(<) $(@) + +$(build)/android-src/%.cpp: $(libutils-native)/%.cpp cp $(<) $(@) $(build)/%.o: $(build)/android-src/%.cpp $(build)/android.dep @@ -1599,8 +1636,8 @@ $(build)/%.o: $(build)/android-src/%.cpp $(build)/android.dep $(cxx) $(android-cflags) $(classpath-extra-cflags) -c \ $$($(windows-path) $(<)) $(call output,$(@)) -$(build)/android.dep: $(luni-javas) $(libdvm-javas) $(crypto-javas) \ - $(dalvik-javas) $(xml-javas) $(luni-nonjavas) +$(build)/android.dep: $(luni-javas) $(dalvik-javas) $(libart-javas) \ + $(xml-javas) $(luni-nonjavas) @echo "compiling luni classes" @mkdir -p $(classpath-build) @mkdir -p $(build)/android @@ -1608,11 +1645,20 @@ $(build)/android.dep: $(luni-javas) $(libdvm-javas) $(crypto-javas) \ @mkdir -p $(build)/android-src/libexpat cp $(android)/external/fdlibm/fdlibm.h $(build)/android-src/external/fdlibm/ cp $(android)/external/expat/lib/expat*.h $(build)/android-src/libexpat/ - cp -a $(luni-java)/* $(libdvm-java)/* $(crypto-java)/* $(dalvik-java)/* \ - $(xml-java)/* $(build)/android-src/ + cp -a $(luni-java)/* $(xml-java)/* $(build)/android-src/ + rm $(call noop-files,$(luni-blacklist),$(luni-java),$(build)/android-src) + (cd $(dalvik-java) && \ + jar c $(call noop-files,$(dalvik-javas),$(dalvik-java),.)) \ + | (cd $(build)/android-src && jar x) + (cd $(libart-java) && \ + jar c $(call noop-files,$(libart-javas),$(libart-java),.)) \ + | (cd $(build)/android-src && jar x) + (cd $(classpath-src) && \ + jar c $(call noop-files,$(classpath-sources),$(classpath-src),.)) \ + | (cd $(build)/android-src && jar x) +# (cd android && jar c *) | (cd $(build)/android-src && jar x) find $(build)/android-src -name '*.java' > $(build)/android.txt - $(javac) -Xmaxerrs 1000 -d $(build)/android -sourcepath $(luni-java) \ - @$(build)/android.txt + $(javac) -Xmaxerrs 1000 -d $(build)/android @$(build)/android.txt rm $(build)/android/sun/misc/Unsafe* \ $(build)/android/java/lang/reflect/Proxy* for x in $(luni-copied-nonjavas); \ diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index 8c915c3a83..449167ea31 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -781,6 +781,116 @@ unsigned classModifiers(Thread* t, GcClass* c) return c->flags(); } +object makeMethod(Thread* t, GcJclass* class_, int index) +{ + GcMethod* method = cast( + t, cast(t, class_->vmClass()->methodTable())->body()[index]); + PROTECT(t, method); + + GcClass* c + = resolveClass(t, roots(t)->bootLoader(), "java/lang/reflect/Method"); + PROTECT(t, c); + + object instance = makeNew(t, c); + PROTECT(t, instance); + + GcMethod* constructor = resolveMethod(t, c, "", "(Lavian/VMMethod;)V"); + + t->m->processor->invoke(t, constructor, instance, method); + + if (method->name()->body()[0] == '<') { + object oldInstance = instance; + + c = resolveClass( + t, roots(t)->bootLoader(), "java/lang/reflect/Constructor"); + + object instance = makeNew(t, c); + + GcMethod* constructor + = resolveMethod(t, c, "", "(Ljava/lang/Method;)V"); + + t->m->processor->invoke(t, constructor, instance, oldInstance); + } + + return instance; +} + +int64_t getPrimitive(Thread* t, object instance, int code, int offset) +{ + switch (code) { + case ByteField: + return fieldAtOffset(instance, offset); + case BooleanField: + return fieldAtOffset(instance, offset); + case CharField: + return fieldAtOffset(instance, offset); + case ShortField: + return fieldAtOffset(instance, offset); + case IntField: + return fieldAtOffset(instance, offset); + case LongField: + return fieldAtOffset(instance, offset); + case FloatField: + return fieldAtOffset(instance, offset); + case DoubleField: + return fieldAtOffset(instance, offset); + default: + abort(t); + } +} + +void setPrimitive(Thread* t, + object instance, + int code, + int offset, + int64_t value) +{ + switch (code) { + case ByteField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case BooleanField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case CharField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case ShortField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case IntField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case LongField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case FloatField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + case DoubleField: + fieldAtOffset(instance, offset) = static_cast(value); + break; + default: + abort(t); + } +} + +int64_t invokeMethod(Thread* t, GcMethod* method, object instance, object args) +{ + THREAD_RESOURCE0(t, { + if (t->exception) { + GcThrowable* exception = t->exception; + t->exception = makeThrowable( + t, GcInvocationTargetException::Type, 0, 0, exception); + } + }); + + unsigned returnCode = method->returnCode(); + + return reinterpret_cast(translateInvokeResult( + t, returnCode, t->m->processor->invokeArray(t, method, instance, args))); +} + } // namespace vm #endif // CLASSPATH_COMMON_H diff --git a/src/builtin.cpp b/src/builtin.cpp index a91e9d7df0..979d6531ee 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -157,6 +157,18 @@ extern "C" AVIAN_EXPORT int64_t JNICALL return reinterpret_cast(defineClass(t, loader, buffer, length)); } +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_avian_Classes_makeString(Thread* t, object, uintptr_t* arguments) +{ + GcByteArray* array + = cast(t, reinterpret_cast(arguments[0])); + int offset = arguments[1]; + int length = arguments[2]; + + return reinterpret_cast( + t->m->classpath->makeString(t, array, offset, length)); +} + extern "C" AVIAN_EXPORT int64_t JNICALL Avian_avian_SystemClassLoader_findLoadedVMClass(Thread* t, object, diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 52740558e5..7994c51b48 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -69,6 +69,11 @@ void JNICALL loadLibrary(Thread* t, object, uintptr_t* arguments) } } +void JNICALL gc(Thread* t, object, uintptr_t*) +{ + collect(t, Heap::MajorCollection); +} + void JNICALL finalizeAllEnqueued(Thread*, object, uintptr_t*) { // ignore @@ -97,116 +102,6 @@ int64_t JNICALL mapData(Thread*, object, uintptr_t*); void JNICALL closeMemoryMappedFile(Thread*, GcMethod*, uintptr_t*); -object makeMethodOrConstructor(Thread* t, GcJclass* c, unsigned index) -{ - PROTECT(t, c); - - GcMethod* method = cast( - t, cast(t, c->vmClass()->methodTable())->body()[index]); - PROTECT(t, method); - - unsigned parameterCount; - unsigned returnTypeSpec; - object parameterTypes = resolveParameterJTypes(t, - method->class_()->loader(), - method->spec(), - ¶meterCount, - &returnTypeSpec); - PROTECT(t, parameterTypes); - - GcJclass* returnType = resolveJType( - t, - method->class_()->loader(), - reinterpret_cast(&method->spec()->body()[returnTypeSpec]), - method->spec()->length() - 1 - returnTypeSpec); - PROTECT(t, returnType); - - object exceptionTypes = resolveExceptionJTypes( - t, method->class_()->loader(), method->addendum()); - - if (method->name()->body()[0] == '<') { - return makeJconstructor( - t, 0, c, parameterTypes, exceptionTypes, 0, 0, 0, 0, index); - } else { - PROTECT(t, exceptionTypes); - - GcString* name = t->m->classpath->makeString( - t, method->name(), 0, method->name()->length() - 1); - - return makeJmethod(t, - 0, - index, - c, - name, - parameterTypes, - exceptionTypes, - returnType, - 0, - 0, - 0, - 0, - 0); - } -} - -object makeField(Thread* t, GcJclass* c, unsigned index) -{ - PROTECT(t, c); - - GcField* field = cast( - t, cast(t, c->vmClass()->fieldTable())->body()[index]); - - PROTECT(t, field); - - GcJclass* type = getJClass( - t, - resolveClassBySpec(t, - field->class_()->loader(), - reinterpret_cast(field->spec()->body().begin()), - field->spec()->length() - 1)); - PROTECT(t, type); - - GcString* name = t->m->classpath->makeString( - t, field->name(), 0, field->name()->length() - 1); - - return makeJfield(t, 0, c, type, 0, 0, name, index); -} - -void initVmThread(Thread* t, GcThread* thread, unsigned offset) -{ - PROTECT(t, thread); - - if (fieldAtOffset(thread, offset) == 0) { - GcClass* c = resolveClass(t, roots(t)->bootLoader(), "java/lang/VMThread"); - PROTECT(t, c); - - object instance = makeNew(t, c); - PROTECT(t, instance); - - GcMethod* constructor - = resolveMethod(t, c, "", "(Ljava/lang/Thread;)V"); - - t->m->processor->invoke(t, constructor, instance, thread); - - setField(t, thread, offset, instance); - } - - if (thread->group() == 0) { - thread->setGroup(t, t->javaThread->group()); - expect(t, thread->group()); - } -} - -void initVmThread(Thread* t, GcThread* thread) -{ - initVmThread(t, - thread, - resolveField(t, - objectClass(t, thread), - "vmThread", - "Ljava/lang/VMThread;")->offset()); -} - object translateStackTrace(Thread* t, object raw) { PROTECT(t, raw); @@ -253,9 +148,10 @@ class MyClasspath : public Classpath { { if (objectClass(t, array) == type(t, GcByteArray::Type)) { GcByteArray* byteArray = cast(t, array); - PROTECT(t, array); PROTECT(t, byteArray); + assertT(t, offset + length <= static_cast(byteArray->length())); + GcCharArray* charArray = makeCharArray(t, length); for (int i = 0; i < length; ++i) { expect(t, (byteArray->body()[offset + i] & 0x80) == 0); @@ -264,8 +160,13 @@ class MyClasspath : public Classpath { } array = charArray; + offset = 0; } else { expect(t, objectClass(t, array) == type(t, GcCharArray::Type)); + + assertT(t, + offset + length + <= static_cast(cast(t, array)->length())); } return vm::makeString(t, array, offset, length, 0); @@ -310,58 +211,35 @@ class MyClasspath : public Classpath { thread->setContextClassLoader(t, roots(t)->appLoader()); - initVmThread(t, thread); - return thread; } virtual object makeJMethod(Thread* t, GcMethod* vmMethod) { - GcArray* table = cast(t, vmMethod->class_()->methodTable()); - for (unsigned i = 0; i < table->length(); ++i) { - if (vmMethod == table->body()[i]) { - return makeMethodOrConstructor(t, getJClass(t, vmMethod->class_()), i); - } - } - abort(t); + PROTECT(t, vmMethod); + + GcJmethod* jmethod = makeJmethod(t, vmMethod, false); + + return vmMethod->name()->body()[0] == '<' + ? static_cast(makeJconstructor(t, jmethod)) + : static_cast(jmethod); } virtual GcMethod* getVMMethod(Thread* t, object jmethod) { - return cast( - t, - objectClass(t, jmethod) == type(t, GcJmethod::Type) - ? cast(t, - cast(t, jmethod) - ->declaringClass() - ->vmClass() - ->methodTable()) - ->body()[cast(t, jmethod)->slot()] - : cast(t, - cast(t, jmethod) - ->declaringClass() - ->vmClass() - ->methodTable()) - ->body()[cast(t, jmethod)->slot()]); + return objectClass(t, jmethod) == type(t, GcJmethod::Type) + ? cast(t, jmethod)->vmMethod() + : cast(t, jmethod)->method()->vmMethod(); } virtual object makeJField(Thread* t, GcField* vmField) { - GcArray* table = cast(t, vmField->class_()->fieldTable()); - for (unsigned i = 0; i < table->length(); ++i) { - if (vmField == table->body()[i]) { - return makeField(t, getJClass(t, vmField->class_()), i); - } - } - abort(t); + return makeJfield(t, vmField, false); } - virtual GcField* getVMField(Thread* t, GcJfield* jfield) + virtual GcField* getVMField(Thread* t UNUSED, GcJfield* jfield) { - return cast( - t, - cast(t, jfield->declaringClass()->vmClass()->fieldTable()) - ->body()[jfield->slot()]); + return jfield->vmField(); } virtual void clearInterrupted(Thread*) @@ -375,29 +253,13 @@ class MyClasspath : public Classpath { // later when we try to acquire it: objectMonitor(t, t->javaThread, true); - GcField* field = resolveField( - t, objectClass(t, t->javaThread), "vmThread", "Ljava/lang/VMThread;"); - - unsigned offset = field->offset(); - - THREAD_RESOURCE(t, unsigned, offset, { - object vmt = fieldAtOffset(t->javaThread, offset); - if (vmt) { - PROTECT(t, vmt); - vm::acquire(t, vmt); - fieldAtOffset(t->javaThread, offset) = 0; - vm::notifyAll(t, vmt); - vm::release(t, vmt); - } - + THREAD_RESOURCE0(t, { vm::acquire(t, t->javaThread); t->clearFlag(Thread::ActiveFlag); vm::notifyAll(t, t->javaThread); vm::release(t, t->javaThread); }); - initVmThread(t, t->javaThread, offset); - GcMethod* method = resolveMethod( t, roots(t)->bootLoader(), "java/lang/Thread", "run", "()V"); @@ -427,6 +289,17 @@ class MyClasspath : public Classpath { } } + { + GcClass* c + = resolveClass(t, roots(t)->bootLoader(), "java/lang/System", false); + + if (c) { + PROTECT(t, c); + + intercept(t, c, "gc", "()V", voidPointer(gc), updateRuntimeData); + } + } + { GcClass* c = resolveClass( t, roots(t)->bootLoader(), "java/lang/ref/FinalizerReference", false); @@ -528,20 +401,9 @@ class MyClasspath : public Classpath { return mayInitClasses_; } - virtual void boot(Thread* t) + virtual void boot(Thread*) { - GcClass* c - = resolveClass(t, roots(t)->bootLoader(), "java/lang/ClassLoader"); - PROTECT(t, c); - - GcMethod* constructor - = resolveMethod(t, c, "", "(Ljava/lang/ClassLoader;Z)V"); - PROTECT(t, constructor); - - t->m->processor->invoke(t, constructor, roots(t)->bootLoader(), 0, true); - - t->m->processor->invoke( - t, constructor, roots(t)->appLoader(), roots(t)->bootLoader(), false); + // ignore } virtual const char* bootClasspath() @@ -698,175 +560,6 @@ void JNICALL file); } -bool matchType(Thread* t, GcField* field, object o) -{ - switch (field->code()) { - case ByteField: - return objectClass(t, o) == type(t, GcByte::Type); - - case BooleanField: - return objectClass(t, o) == type(t, GcBoolean::Type); - - case CharField: - return objectClass(t, o) == type(t, GcChar::Type); - - case ShortField: - return objectClass(t, o) == type(t, GcShort::Type); - - case IntField: - return objectClass(t, o) == type(t, GcInt::Type); - - case LongField: - return objectClass(t, o) == type(t, GcLong::Type); - - case FloatField: - return objectClass(t, o) == type(t, GcFloat::Type); - - case DoubleField: - return objectClass(t, o) == type(t, GcDouble::Type); - - case ObjectField: - if (o == 0) { - return true; - } else { - PROTECT(t, o); - - GcByteArray* spec; - if (field->spec()->body()[0] == '[') { - spec = field->spec(); - } else { - spec = makeByteArray(t, field->spec()->length() - 2); - - memcpy(spec->body().begin(), - &field->spec()->body()[1], - field->spec()->length() - 3); - - spec->body()[field->spec()->length() - 3] = 0; - } - - return instanceOf(t, resolveClass(t, field->class_()->loader(), spec), o); - } - - default: - abort(t); - } -} - -object getField(Thread* t, GcField* field, object instance) -{ - PROTECT(t, field); - PROTECT(t, instance); - - initClass(t, field->class_()); - - object target; - if (field->flags() & ACC_STATIC) { - target = field->class_()->staticTable(); - } else if (instanceOf(t, field->class_(), instance)) { - target = instance; - } else { - throwNew(t, GcIllegalArgumentException::Type); - } - - unsigned offset = field->offset(); - switch (field->code()) { - case ByteField: - return makeByte(t, fieldAtOffset(target, offset)); - - case BooleanField: - return makeBoolean(t, fieldAtOffset(target, offset)); - - case CharField: - return makeChar(t, fieldAtOffset(target, offset)); - - case ShortField: - return makeShort(t, fieldAtOffset(target, offset)); - - case IntField: - return makeInt(t, fieldAtOffset(target, offset)); - - case LongField: - return makeLong(t, fieldAtOffset(target, offset)); - - case FloatField: - return makeFloat(t, fieldAtOffset(target, offset)); - - case DoubleField: - return makeDouble(t, fieldAtOffset(target, offset)); - - case ObjectField: - return fieldAtOffset(target, offset); - - default: - abort(t); - } -} - -void setField(Thread* t, GcField* field, object instance, object value) -{ - PROTECT(t, field); - PROTECT(t, instance); - PROTECT(t, value); - - if (not matchType(t, field, value)) { - throwNew(t, GcIllegalArgumentException::Type); - } - - object target; - if ((field->flags() & ACC_STATIC) != 0) { - target = field->class_()->staticTable(); - } else if (instanceOf(t, field->class_(), instance)) { - target = instance; - } else { - throwNew(t, GcIllegalArgumentException::Type); - } - PROTECT(t, target); - - initClass(t, field->class_()); - - unsigned offset = field->offset(); - switch (field->code()) { - case ByteField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case BooleanField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case CharField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case ShortField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case IntField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case LongField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case FloatField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case DoubleField: - fieldAtOffset(target, offset) = cast(t, value)->value(); - break; - - case ObjectField: - setField(t, target, offset, value); - break; - - default: - abort(t); - } -} - } // namespace local } // namespace @@ -1044,12 +737,6 @@ int 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) { @@ -1123,208 +810,11 @@ extern "C" AVIAN_EXPORT int64_t JNICALL return -1; } -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getInterfaces(Thread* t, object, uintptr_t* arguments) -{ - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - - GcClassAddendum* addendum = c->vmClass()->addendum(); - if (addendum) { - GcArray* table = cast(t, addendum->interfaceTable()); - if (table) { - PROTECT(t, table); - - object array = makeObjectArray(t, table->length()); - PROTECT(t, array); - - for (unsigned i = 0; i < table->length(); ++i) { - GcJclass* c = getJClass(t, cast(t, table->body()[i])); - setField(t, - array, - ArrayBody + (i * BytesPerWord), - reinterpret_cast(c)); - } - - return reinterpret_cast(array); - } - } - - return reinterpret_cast( - makeObjectArray(t, type(t, GcJclass::Type), 0)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getDeclaredClasses(Thread* t, - object, - uintptr_t* arguments) -{ - return reinterpret_cast(getDeclaredClasses( - t, - cast(t, reinterpret_cast(arguments[0]))->vmClass(), - arguments[1])); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_newInstanceImpl(Thread* t, - object, - uintptr_t* arguments) -{ - GcClass* c - = cast(t, reinterpret_cast(arguments[0]))->vmClass(); - - GcMethod* method = resolveMethod(t, c, "", "()V"); - PROTECT(t, method); - - object instance = makeNew(t, c); - PROTECT(t, instance); - - t->m->processor->invoke(t, method, instance); - - return reinterpret_cast(instance); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getComponentType(Thread* t, - object, - uintptr_t* arguments) -{ - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - - if (c->vmClass()->arrayDimensions()) { - uint8_t n = c->vmClass()->name()->body()[1]; - if (n != 'L' and n != '[') { - return reinterpret_cast(getJClass(t, primitiveClass(t, n))); - } else { - return reinterpret_cast( - getJClass(t, c->vmClass()->arrayElementClass())); - } - } else { - return 0; - } -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_classForName(Thread* t, object, uintptr_t* arguments) -{ - object name = reinterpret_cast(arguments[0]); - PROTECT(t, name); - - GcClassLoader* loader - = cast(t, reinterpret_cast(arguments[2])); - PROTECT(t, loader); - - GcMethod* method = resolveMethod( - t, - roots(t)->bootLoader(), - "avian/Classes", - "forName", - "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"); - - return reinterpret_cast(t->m->processor->invoke( - t, method, 0, name, static_cast(arguments[1]), loader)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getDeclaredField(Thread* t, - object, - uintptr_t* arguments) -{ - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - PROTECT(t, c); - - object name = reinterpret_cast(arguments[1]); - PROTECT(t, name); - - GcMethod* method = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "findField", - "(Lavian/VMClass;Ljava/lang/String;)I"); - - int index = cast( - t, t->m->processor->invoke(t, method, 0, c->vmClass(), name)) - ->value(); - - if (index >= 0) { - return reinterpret_cast(local::makeField(t, c, index)); - } else { - return 0; - } -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getDeclaredConstructorOrMethod(Thread* t, - object, - uintptr_t* arguments) -{ - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - PROTECT(t, c); - - object name = reinterpret_cast(arguments[1]); - PROTECT(t, name); - - object parameterTypes = reinterpret_cast(arguments[2]); - PROTECT(t, parameterTypes); - - GcMethod* method - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "findMethod", - "(Lavian/VMClass;Ljava/lang/String;[Ljava/lang/Class;)I"); - - int index = cast(t, - t->m->processor->invoke( - t, method, 0, c->vmClass(), name, parameterTypes)) - ->value(); - - if (index >= 0) { - return reinterpret_cast( - local::makeMethodOrConstructor(t, c, index)); - } else { - return 0; - } -} - extern "C" AVIAN_EXPORT int64_t JNICALL Avian_avian_SystemClassLoader_findLoadedVMClass(Thread*, object, uintptr_t*); -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMClassLoader_findLoadedClass(Thread* t, - object method, - uintptr_t* arguments) -{ - int64_t v - = Avian_avian_SystemClassLoader_findLoadedVMClass(t, method, arguments); - - if (v) { - return reinterpret_cast( - getJClass(t, cast(t, reinterpret_cast(v)))); - } else { - return 0; - } -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMClassLoader_defineClass__Ljava_lang_ClassLoader_2Ljava_lang_String_2_3BII( - Thread* t, - object method, - uintptr_t* arguments) -{ - uintptr_t args[] = {arguments[0], arguments[2], arguments[3], arguments[4]}; - - int64_t v = Avian_avian_Classes_defineVMClass(t, method, args); - - if (v) { - return reinterpret_cast( - getJClass(t, cast(t, reinterpret_cast(v)))); - } else { - return 0; - } -} - extern "C" AVIAN_EXPORT int64_t JNICALL Avian_dalvik_system_VMRuntime_bootClassPath(Thread* t, object, uintptr_t*) { @@ -1374,6 +864,12 @@ extern "C" AVIAN_EXPORT void JNICALL collect(t, Heap::MajorCollection); } +extern "C" AVIAN_EXPORT jlong JNICALL + Avian_java_lang_Runtime_maxMemory(Thread* t, object, uintptr_t*) +{ + return t->m->heap->limit(); +} + extern "C" AVIAN_EXPORT void JNICALL Avian_java_lang_Runtime_nativeExit(Thread* t, object, uintptr_t* arguments) { @@ -1410,108 +906,101 @@ extern "C" AVIAN_EXPORT void JNICALL arguments[4]); } +extern "C" AVIAN_EXPORT void JNICALL + Avian_java_lang_System_arraycopyCharUnchecked(Thread* t, + object method, + uintptr_t* arguments) +{ + Avian_java_lang_System_arraycopy(t, method, arguments); +} + +extern "C" AVIAN_EXPORT void JNICALL + Avian_java_lang_System_arraycopyByteUnchecked(Thread* t, + object method, + uintptr_t* arguments) +{ + Avian_java_lang_System_arraycopy(t, method, arguments); +} + extern "C" AVIAN_EXPORT int64_t JNICALL Avian_sun_misc_Unsafe_objectFieldOffset(Thread* t, object, uintptr_t* arguments) { - GcJfield* jfield = cast(t, reinterpret_cast(arguments[1])); - return cast( - t, - cast(t, jfield->declaringClass()->vmClass()->fieldTable()) - ->body()[jfield->slot()])->offset(); + return cast(t, reinterpret_cast(arguments[1])) + ->vmField() + ->offset(); } extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_VMThread_interrupt(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_Thread_nativeInterrupt(Thread* t, + object, + uintptr_t* arguments) { - object vmThread = reinterpret_cast(arguments[0]); - PROTECT(t, vmThread); - - GcField* field = resolveField( - t, objectClass(t, vmThread), "thread", "Ljava/lang/Thread;"); - interrupt( t, reinterpret_cast( - cast(t, fieldAtOffset(vmThread, field->offset())) - ->peer())); + cast(t, reinterpret_cast(arguments[0]))->peer())); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMThread_interrupted(Thread* t, object, uintptr_t*) + Avian_java_lang_Thread_interrupted(Thread* t, object, uintptr_t*) { return getAndClearInterrupted(t, t); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMThread_isInterrupted(Thread* t, - object, - uintptr_t* arguments) + Avian_java_lang_Thread_isInterrupted(Thread* t, + object, + uintptr_t* arguments) { - object vmThread = reinterpret_cast(arguments[0]); - PROTECT(t, vmThread); - - GcField* field = resolveField( - t, objectClass(t, vmThread), "thread", "Ljava/lang/Thread;"); - - return cast(t, fieldAtOffset(vmThread, field->offset())) + return cast(t, reinterpret_cast(arguments[0])) ->interrupted(); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMThread_getStatus(Thread*, object, uintptr_t*) + Avian_java_lang_Thread_nativeGetStatus(Thread*, object, uintptr_t*) { // todo return 1; } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMThread_currentThread(Thread* t, object, uintptr_t*) + Avian_java_lang_Thread_currentThread(Thread* t, object, uintptr_t*) { return reinterpret_cast(t->javaThread); } extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_VMThread_create(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_Thread_nativeCreate(Thread* t, object, uintptr_t* arguments) { - GcThread* thread = cast(t, reinterpret_cast(arguments[0])); - PROTECT(t, thread); - - local::initVmThread(t, thread); - startThread(t, thread); + startThread(t, cast(t, reinterpret_cast(arguments[0]))); } extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_VMThread_sleep(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_Thread_sleep(Thread* t, object, uintptr_t* arguments) { + object lock = reinterpret_cast(arguments[0]); + PROTECT(t, lock); + int64_t milliseconds; - memcpy(&milliseconds, arguments, 8); + memcpy(&milliseconds, arguments + 1, 8); if (arguments[2] > 0) ++milliseconds; if (milliseconds <= 0) milliseconds = 1; - if (t->javaThread->sleepLock() == 0) { - object lock = makeJobject(t); - t->javaThread->setSleepLock(t, lock); - } - - acquire(t, t->javaThread->sleepLock()); - vm::wait(t, t->javaThread->sleepLock(), milliseconds); - release(t, t->javaThread->sleepLock()); + acquire(t, lock); + vm::wait(t, lock, milliseconds); + release(t, lock); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_VMThread_holdsLock(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_Thread_nativeHoldsLock(Thread* t, + object, + uintptr_t* arguments) { - object vmThread = reinterpret_cast(arguments[0]); - PROTECT(t, vmThread); - - GcField* field = resolveField( - t, objectClass(t, vmThread), "thread", "Ljava/lang/Thread;"); - - if (cast(t, fieldAtOffset(vmThread, field->offset())) + if (cast(t, reinterpret_cast(arguments[0])) != t->javaThread) { throwNew(t, GcIllegalStateException::Type, @@ -1525,7 +1014,7 @@ extern "C" AVIAN_EXPORT int64_t JNICALL } extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_VMThread_yield(Thread* t, object, uintptr_t*) + Avian_java_lang_Thread_yield(Thread* t, object, uintptr_t*) { t->m->system->yield(); } @@ -1573,6 +1062,46 @@ extern "C" AVIAN_EXPORT int64_t JNICALL return reinterpret_cast(v.loader); } +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_dalvik_system_VMStack_getClosestUserClassLoader(Thread* t, + object, + uintptr_t* arguments) +{ + GcClassLoader* boot + = cast(t, reinterpret_cast(arguments[0])); + + GcClassLoader* app + = cast(t, reinterpret_cast(arguments[1])); + + class Visitor : public Processor::StackVisitor { + public: + Visitor(Thread* t, GcClassLoader* boot, GcClassLoader* app) + : t(t), loader(0), boot(boot), app(app) + { + } + + virtual bool visit(Processor::StackWalker* walker) + { + GcClassLoader* loader = walker->method()->class_()->loader(); + if (loader == boot or loader == app) { + return true; + } else { + this->loader = loader; + return false; + } + } + + Thread* t; + GcClassLoader* loader; + GcClassLoader* boot; + GcClassLoader* app; + } v(t, boot, app); + + t->m->processor->walkStack(t, &v); + + return reinterpret_cast(v.loader); +} + extern "C" AVIAN_EXPORT int64_t JNICALL Avian_dalvik_system_VMStack_getClasses(Thread* t, object, uintptr_t*) { @@ -1700,6 +1229,32 @@ extern "C" AVIAN_EXPORT int64_t JNICALL return v; } +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_java_lang_Object_toString(Thread* t, object, uintptr_t* arguments) +{ + object this_ = reinterpret_cast(arguments[0]); + + unsigned hash = objectHash(t, this_); + GcString* s = makeString( + t, "%s@0x%x", objectClass(t, this_)->name()->body().begin(), hash); + + return reinterpret_cast(s); +} + +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_java_lang_Object_getVMClass(Thread* t, object, uintptr_t* arguments) +{ + return reinterpret_cast( + objectClass(t, reinterpret_cast(arguments[0]))); +} + +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_java_lang_Object_clone(Thread* t, object, uintptr_t* arguments) +{ + return reinterpret_cast( + clone(t, reinterpret_cast(arguments[0]))); +} + extern "C" AVIAN_EXPORT void JNICALL Avian_java_lang_Object_wait(Thread* t, object, uintptr_t* arguments) { @@ -1715,13 +1270,6 @@ extern "C" AVIAN_EXPORT void JNICALL notifyAll(t, reinterpret_cast(arguments[0])); } -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Object_getClass(Thread* t, object, uintptr_t* arguments) -{ - return reinterpret_cast( - getJClass(t, objectClass(t, reinterpret_cast(arguments[0])))); -} - extern "C" AVIAN_EXPORT int64_t JNICALL Avian_java_lang_Object_hashCode(Thread* t, object, uintptr_t* arguments) { @@ -1729,633 +1277,80 @@ extern "C" AVIAN_EXPORT int64_t JNICALL } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Object_internalClone(Thread* t, - object, - uintptr_t* arguments) + Avian_java_lang_reflect_Method_getCaller(Thread* t, object, uintptr_t*) { - return reinterpret_cast( - clone(t, reinterpret_cast(arguments[1]))); + return reinterpret_cast(getCaller(t, 2)); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getModifiers(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_reflect_Method_invoke(Thread* t, + object, + uintptr_t* arguments) { - return classModifiers( - t, cast(t, reinterpret_cast(arguments[0]))->vmClass()); + return invokeMethod(t, + cast(t, reinterpret_cast(arguments[0])), + reinterpret_cast(arguments[1]), + reinterpret_cast(arguments[2])); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getSuperclass(Thread* t, object, uintptr_t* arguments) + Avian_java_lang_reflect_Field_getObject(Thread*, + object, + uintptr_t* arguments) { - GcClass* c - = cast(t, reinterpret_cast(arguments[0]))->vmClass(); - if (c->flags() & ACC_INTERFACE) { - return 0; - } else { - GcClass* s = c->super(); - return s ? reinterpret_cast(getJClass(t, s)) : 0; - } + return reinterpret_cast(fieldAtOffset( + reinterpret_cast(arguments[0]), arguments[1])); +} + +extern "C" AVIAN_EXPORT void JNICALL + Avian_java_lang_reflect_Field_setObject(Thread* t, + object, + uintptr_t* arguments) +{ + setField(t, + reinterpret_cast(arguments[0]), + arguments[1], + reinterpret_cast(arguments[2])); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_desiredAssertionStatus(Thread*, object, uintptr_t*) + Avian_java_lang_reflect_Field_getPrimitive(Thread* t, + object, + uintptr_t* arguments) { - return 1; + return getPrimitive( + t, reinterpret_cast(arguments[0]), arguments[1], arguments[2]); +} + +extern "C" AVIAN_EXPORT void JNICALL + Avian_java_lang_reflect_Field_setPrimitive(Thread* t, + object, + uintptr_t* arguments) +{ + int64_t value; + memcpy(&value, arguments + 3, 8); + + setPrimitive(t, + reinterpret_cast(arguments[0]), + arguments[1], + arguments[2], + value); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getNameNative(Thread* t, object, uintptr_t* arguments) -{ - GcByteArray* name = cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->name(); - - THREAD_RUNTIME_ARRAY(t, char, s, name->length()); - replace('/', - '.', - RUNTIME_ARRAY_BODY(s), - reinterpret_cast(name->body().begin())); - - return reinterpret_cast( - makeString(t, "%s", RUNTIME_ARRAY_BODY(s))); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_isInterface(Thread* t, object, uintptr_t* arguments) -{ - return (cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->flags() & ACC_INTERFACE) != 0; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_isPrimitive(Thread* t, object, uintptr_t* arguments) -{ - return (cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->vmFlags() & PrimitiveFlag) != 0; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_isAnonymousClass(Thread* t, - object, - uintptr_t* arguments) -{ - GcByteArray* name = cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->name(); - - for (unsigned i = 0; i < name->length() - 1; ++i) { - int c = name->body()[i]; - if (c != '$' and (c < '0' or c > '9')) { - return false; - } - } - - return true; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getClassLoader(Thread* t, - object, - uintptr_t* arguments) -{ - return reinterpret_cast( - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->loader()); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_isAssignableFrom(Thread* t, - object, - uintptr_t* arguments) -{ - GcJclass* this_ = cast(t, reinterpret_cast(arguments[0])); - GcJclass* that = cast(t, reinterpret_cast(arguments[1])); - - if (LIKELY(that)) { - return isAssignableFrom(t, this_->vmClass(), that->vmClass()); - } else { - throwNew(t, GcNullPointerException::Type); - } -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_isInstance(Thread* t, object, uintptr_t* arguments) -{ - GcJclass* this_ = cast(t, reinterpret_cast(arguments[0])); - object o = reinterpret_cast(arguments[1]); - - if (o) { - return instanceOf(t, this_->vmClass(), o); - } else { - return 0; - } -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getDeclaredMethods(Thread* t, + Avian_java_lang_reflect_Constructor_make(Thread* t, object, uintptr_t* arguments) { - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - PROTECT(t, c); - - bool publicOnly = arguments[1]; - - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getMethods", - "(Lavian/VMClass;Z)[Ljava/lang/reflect/Method;"); + return reinterpret_cast( + make(t, cast(t, reinterpret_cast(arguments[0])))); +} +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_java_lang_ref_Reference_get(Thread* t, object, uintptr_t* arguments) +{ return reinterpret_cast( - t->m->processor->invoke(t, get, 0, c->vmClass(), publicOnly)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Class_getDeclaredFields(Thread* t, - object, - uintptr_t* arguments) -{ - GcJclass* c = cast(t, reinterpret_cast(arguments[0])); - PROTECT(t, c); - - bool publicOnly = arguments[1]; - - GcMethod* get = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getFields", - "(Lavian/VMClass;Z)[Ljava/lang/reflect/Field;"); - - return reinterpret_cast( - t->m->processor->invoke(t, get, 0, c->vmClass(), publicOnly)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_invokeNative(Thread* t, - object, - uintptr_t* arguments) -{ - object instance = reinterpret_cast(arguments[1]); - object args = reinterpret_cast(arguments[2]); - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[3])) - ->vmClass() - ->methodTable())->body()[arguments[6]]); - - return reinterpret_cast(invoke(t, method, instance, args)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_getMethodModifiers(Thread* t, - object, - uintptr_t* arguments) -{ - return cast( - t, - cast( - t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->methodTable())->body()[arguments[1]])->flags(); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_isAnnotationPresent(Thread* t, - object, - uintptr_t* arguments) -{ - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->methodTable())->body()[arguments[1]]); - - GcMethodAddendum* addendum = method->addendum(); - if (addendum) { - object table = addendum->annotationTable(); - if (table) { - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - if (objectArrayBody(t, objectArrayBody(t, table, i), 1) - == reinterpret_cast(arguments[2])) { - return true; - } - } - } - } - - return false; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_getAnnotation(Thread* t, - object, - uintptr_t* arguments) -{ - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->methodTable())->body()[arguments[1]]); - - GcMethodAddendum* addendum = method->addendum(); - if (addendum) { - object table = addendum->annotationTable(); - if (table) { - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - if (objectArrayBody(t, objectArrayBody(t, table, i), 1) - == reinterpret_cast(arguments[2])) { - PROTECT(t, method); - PROTECT(t, table); - - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getAnnotation", - "(Ljava/lang/ClassLoader;[Ljava/lang/Object;)" - "Ljava/lang/annotation/Annotation;"); - - return reinterpret_cast( - t->m->processor->invoke(t, - get, - 0, - method->class_()->loader(), - objectArrayBody(t, table, i))); - } - } - } - } - - return false; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_getDeclaredAnnotations(Thread* t, - object, - uintptr_t* arguments) -{ - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->methodTable())->body()[arguments[1]]); - - GcMethodAddendum* addendum = method->addendum(); - if (addendum) { - object table = addendum->annotationTable(); - if (table) { - PROTECT(t, method); - PROTECT(t, table); - - object array = makeObjectArray( - t, - resolveClass( - t, roots(t)->bootLoader(), "java/lang/annotation/Annotation"), - objectArrayLength(t, table)); - PROTECT(t, array); - - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getAnnotation", - "(Ljava/lang/ClassLoader;[Ljava/lang/Object;)" - "Ljava/lang/annotation/Annotation;"); - PROTECT(t, get); - - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - object a = t->m->processor->invoke(t, - get, - 0, - method->class_()->loader(), - objectArrayBody(t, table, i)); - - setField(t, array, ArrayBody + (i * BytesPerWord), a); - } - - return reinterpret_cast(array); - } - } - - return reinterpret_cast(makeObjectArray( - t, - resolveClass( - t, roots(t)->bootLoader(), "java/lang/annotation/Annotation"), - 0)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getDeclaredAnnotations(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->fieldTable())->body()[arguments[1]]); - - GcFieldAddendum* addendum = field->addendum(); - if (addendum) { - object table = addendum->annotationTable(); - if (table) { - PROTECT(t, field); - PROTECT(t, table); - - object array = makeObjectArray( - t, - resolveClass( - t, roots(t)->bootLoader(), "java/lang/annotation/Annotation"), - objectArrayLength(t, table)); - PROTECT(t, array); - - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getAnnotation", - "(Ljava/lang/ClassLoader;[Ljava/lang/Object;)" - "Ljava/lang/annotation/Annotation;"); - PROTECT(t, get); - - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - object a = t->m->processor->invoke( - t, - get, - 0, - cast(t, reinterpret_cast(arguments[0]))->loader(), - objectArrayBody(t, table, i)); - - setField(t, array, ArrayBody + (i * BytesPerWord), a); - } - - return reinterpret_cast(array); - } - } - - return reinterpret_cast(makeObjectArray( - t, - resolveClass( - t, roots(t)->bootLoader(), "java/lang/annotation/Annotation"), - 0)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Method_getDefaultValue(Thread* t, - object, - uintptr_t* arguments) -{ - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[1])) - ->vmClass() - ->methodTable())->body()[arguments[2]]); - - GcMethodAddendum* addendum = method->addendum(); - if (addendum) { - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getAnnotationDefaultValue", - "(Ljava/lang/ClassLoader;Lavian/MethodAddendum;)" - "Ljava/lang/Object;"); - - return reinterpret_cast(t->m->processor->invoke( - t, get, 0, method->class_()->loader(), addendum)); - } - - return 0; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Constructor_constructNative(Thread* t, - object, - uintptr_t* arguments) -{ - object args = reinterpret_cast(arguments[1]); - PROTECT(t, args); - - GcClass* c - = cast(t, reinterpret_cast(arguments[2]))->vmClass(); - PROTECT(t, c); - - initClass(t, c); - - GcMethod* method = cast( - t, cast(t, c->methodTable())->body()[arguments[4]]); - PROTECT(t, method); - - object instance = makeNew(t, c); - PROTECT(t, instance); - - t->m->processor->invokeArray(t, method, instance, args); - - return reinterpret_cast(instance); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getField(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[2])) - ->vmClass() - ->fieldTable())->body()[arguments[4]]); - - PROTECT(t, field); - - object instance = reinterpret_cast(arguments[1]); - PROTECT(t, instance); - - return reinterpret_cast(local::getField(t, field, instance)); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getIField(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[2])) - ->vmClass() - ->fieldTable())->body()[arguments[4]]); - - PROTECT(t, field); - - object instance = reinterpret_cast(arguments[1]); - PROTECT(t, instance); - - return cast(t, local::getField(t, field, instance))->value(); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getJField(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[2])) - ->vmClass() - ->fieldTable())->body()[arguments[4]]); - - PROTECT(t, field); - - object instance = reinterpret_cast(arguments[1]); - PROTECT(t, instance); - - return cast(t, local::getField(t, field, instance))->value(); -} - -extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_reflect_Field_setField(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[2])) - ->vmClass() - ->fieldTable())->body()[arguments[4]]); - - PROTECT(t, field); - - object instance = reinterpret_cast(arguments[1]); - PROTECT(t, instance); - - object value = reinterpret_cast(arguments[6]); - PROTECT(t, value); - - local::setField(t, field, instance, value); -} - -extern "C" AVIAN_EXPORT void JNICALL - Avian_java_lang_reflect_Field_setIField(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[2])) - ->vmClass() - ->fieldTable())->body()[arguments[4]]); - - object instance = reinterpret_cast(arguments[1]); - PROTECT(t, instance); - - object value = reinterpret_cast(makeInt(t, arguments[7])); - - local::setField(t, field, instance, value); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getFieldModifiers(Thread* t, - object, - uintptr_t* arguments) -{ - return cast( - t, - cast( - t, - cast(t, reinterpret_cast(arguments[1])) - ->vmClass() - ->fieldTable())->body()[arguments[2]])->flags(); -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getAnnotation(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->fieldTable())->body()[arguments[1]]); - - GcFieldAddendum* addendum = field->addendum(); - if (addendum) { - object table = addendum->annotationTable(); - if (table) { - for (unsigned i = 0; i < objectArrayLength(t, table); ++i) { - if (objectArrayBody(t, objectArrayBody(t, table, i), 1) - == reinterpret_cast(arguments[2])) { - PROTECT(t, field); - PROTECT(t, table); - - GcMethod* get - = resolveMethod(t, - roots(t)->bootLoader(), - "avian/Classes", - "getAnnotation", - "(Ljava/lang/ClassLoader;[Ljava/lang/Object;)" - "Ljava/lang/annotation/Annotation;"); - - return reinterpret_cast( - t->m->processor->invoke(t, - get, - 0, - field->class_()->loader(), - objectArrayBody(t, table, i))); - } - } - } - } - - return false; -} - -extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_reflect_Field_getSignatureAnnotation(Thread* t, - object, - uintptr_t* arguments) -{ - GcField* field = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[1])) - ->vmClass() - ->fieldTable())->body()[arguments[2]]); - - GcFieldAddendum* addendum = field->addendum(); - if (addendum) { - GcByteArray* signature = cast(t, addendum->signature()); - if (signature) { - object array = makeObjectArray(t, 1); - PROTECT(t, array); - - GcString* string = t->m->classpath->makeString( - t, signature, 0, signature->length() - 1); - - setField(t, array, ArrayBody, string); - - return reinterpret_cast(array); - } - } - - return reinterpret_cast(makeObjectArray(t, 0)); + cast(t, reinterpret_cast(arguments[0]))->target()); } extern "C" AVIAN_EXPORT int64_t JNICALL @@ -2376,21 +1371,34 @@ extern "C" AVIAN_EXPORT int64_t JNICALL } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments) + Avian_avian_Classes_getVMClass(Thread* t, object, uintptr_t* arguments) { - return reinterpret_cast(local::makeMethodOrConstructor( - t, - cast(t, reinterpret_cast(arguments[0])), - arguments[1])); + return reinterpret_cast( + objectClass(t, reinterpret_cast(arguments[0]))); } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_avian_Classes_makeField(Thread* t, object, uintptr_t* arguments) + Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments) { - return reinterpret_cast(local::makeField( - t, - cast(t, reinterpret_cast(arguments[0])), - arguments[1])); + return reinterpret_cast( + makeMethod(t, + cast(t, reinterpret_cast(arguments[0])), + arguments[1])); +} + +extern "C" AVIAN_EXPORT int64_t JNICALL + Avian_avian_Classes_isAssignableFrom(Thread* t, + object, + uintptr_t* arguments) +{ + GcClass* this_ = cast(t, reinterpret_cast(arguments[0])); + GcClass* that = cast(t, reinterpret_cast(arguments[1])); + + if (LIKELY(that)) { + return vm::isAssignableFrom(t, this_, that); + } else { + throwNew(t, GcNullPointerException::Type); + } } extern "C" AVIAN_EXPORT int64_t JNICALL diff --git a/src/classpath-avian.cpp b/src/classpath-avian.cpp index 85821a7025..4f8740cc90 100644 --- a/src/classpath-avian.cpp +++ b/src/classpath-avian.cpp @@ -343,30 +343,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL object, uintptr_t* arguments) { - object instance = reinterpret_cast(arguments[0]); - int code = arguments[1]; - int offset = arguments[2]; - - switch (code) { - case ByteField: - return fieldAtOffset(instance, offset); - case BooleanField: - return fieldAtOffset(instance, offset); - case CharField: - return fieldAtOffset(instance, offset); - case ShortField: - return fieldAtOffset(instance, offset); - case IntField: - return fieldAtOffset(instance, offset); - case LongField: - return fieldAtOffset(instance, offset); - case FloatField: - return fieldAtOffset(instance, offset); - case DoubleField: - return fieldAtOffset(instance, offset); - default: - abort(t); - } + return getPrimitive( + t, reinterpret_cast(arguments[0]), arguments[1], arguments[2]); } extern "C" AVIAN_EXPORT int64_t JNICALL @@ -374,10 +352,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL object, uintptr_t* arguments) { - object instance = reinterpret_cast(arguments[0]); - int offset = arguments[1]; - - return reinterpret_cast(fieldAtOffset(instance, offset)); + return reinterpret_cast(fieldAtOffset( + reinterpret_cast(arguments[0]), arguments[1])); } extern "C" AVIAN_EXPORT void JNICALL @@ -385,40 +361,14 @@ extern "C" AVIAN_EXPORT void JNICALL object, uintptr_t* arguments) { - object instance = reinterpret_cast(arguments[0]); - int code = arguments[1]; - int offset = arguments[2]; int64_t value; memcpy(&value, arguments + 3, 8); - switch (code) { - case ByteField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case BooleanField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case CharField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case ShortField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case IntField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case LongField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case FloatField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - case DoubleField: - fieldAtOffset(instance, offset) = static_cast(value); - break; - default: - abort(t); - } + setPrimitive(t, + reinterpret_cast(arguments[0]), + arguments[1], + arguments[2], + value); } extern "C" AVIAN_EXPORT void JNICALL @@ -426,11 +376,10 @@ extern "C" AVIAN_EXPORT void JNICALL object, uintptr_t* arguments) { - object instance = reinterpret_cast(arguments[0]); - int offset = arguments[1]; - object value = reinterpret_cast(arguments[2]); - - setField(t, instance, offset, value); + setField(t, + reinterpret_cast(arguments[0]), + arguments[1], + reinterpret_cast(arguments[2])); } extern "C" AVIAN_EXPORT int64_t JNICALL @@ -438,9 +387,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL object, uintptr_t* arguments) { - GcClass* c = cast(t, reinterpret_cast(arguments[0])); - - return reinterpret_cast(make(t, c)); + return reinterpret_cast( + make(t, cast(t, reinterpret_cast(arguments[0])))); } extern "C" AVIAN_EXPORT int64_t JNICALL @@ -454,22 +402,10 @@ extern "C" AVIAN_EXPORT int64_t JNICALL object, uintptr_t* arguments) { - GcMethod* method = cast(t, reinterpret_cast(arguments[0])); - object instance = reinterpret_cast(arguments[1]); - object args = reinterpret_cast(arguments[2]); - - THREAD_RESOURCE0(t, { - if (t->exception) { - GcThrowable* exception = t->exception; - t->exception = makeThrowable( - t, GcInvocationTargetException::Type, 0, 0, exception); - } - }); - - unsigned returnCode = method->returnCode(); - - return reinterpret_cast(translateInvokeResult( - t, returnCode, t->m->processor->invokeArray(t, method, instance, args))); + return invokeMethod(t, + cast(t, reinterpret_cast(arguments[0])), + reinterpret_cast(arguments[1]), + reinterpret_cast(arguments[2])); } extern "C" AVIAN_EXPORT int64_t JNICALL @@ -809,38 +745,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments) { - GcMethod* method = cast( - t, - cast(t, - cast(t, reinterpret_cast(arguments[0])) - ->vmClass() - ->methodTable())->body()[arguments[1]]); - PROTECT(t, method); - - GcClass* c - = resolveClass(t, roots(t)->bootLoader(), "java/lang/reflect/Method"); - PROTECT(t, c); - - object instance = makeNew(t, c); - PROTECT(t, instance); - - GcMethod* constructor = resolveMethod(t, c, "", "(Lavian/VMMethod;)V"); - - t->m->processor->invoke(t, constructor, instance, method); - - if (method->name()->body()[0] == '<') { - object oldInstance = instance; - - c = resolveClass( - t, roots(t)->bootLoader(), "java/lang/reflect/Constructor"); - - object instance = makeNew(t, c); - - GcMethod* constructor - = resolveMethod(t, c, "", "(Ljava/lang/Method;)V"); - - t->m->processor->invoke(t, constructor, instance, oldInstance); - } - - return reinterpret_cast(instance); + return reinterpret_cast( + makeMethod(t, + cast(t, reinterpret_cast(arguments[0])), + arguments[1])); } diff --git a/src/machine.cpp b/src/machine.cpp index ecc30b3361..8647ad0ff8 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -5665,6 +5665,8 @@ void runFinalizeThread(Thread* t) GcCleaner* cleanList = 0; PROTECT(t, cleanList); + fprintf(stderr, "run finalize thread!\n"); + while (true) { { ACQUIRE(t, t->m->stateLock); diff --git a/test/Misc.java b/test/Misc.java index ef78345a56..ec3bd0bd25 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -316,21 +316,21 @@ public class Misc { expect(staticRan); expect(System.getProperty("java.class.path").equals - (System.getProperties().get("java.class.path"))); + (System.getProperties().getProperty("java.class.path"))); expect(System.getProperty("path.separator").equals - (System.getProperties().get("path.separator"))); + (System.getProperties().getProperty("path.separator"))); expect(System.getProperty("user.dir").equals - (System.getProperties().get("user.dir"))); + (System.getProperties().getProperty("user.dir"))); expect(System.getProperty("java.io.tmpdir").equals - (System.getProperties().get("java.io.tmpdir"))); + (System.getProperties().getProperty("java.io.tmpdir"))); System.setProperty("buzzy.buzzy.bim.bam", "dippy dopey flim flam"); expect(System.getProperty("buzzy.buzzy.bim.bam").equals - (System.getProperties().get("buzzy.buzzy.bim.bam"))); + (System.getProperties().getProperty("buzzy.buzzy.bim.bam"))); expect(System.getProperty("buzzy.buzzy.bim.bam").equals ("dippy dopey flim flam")); @@ -338,7 +338,7 @@ public class Misc { System.getProperties().put("buzzy.buzzy.bim.bam", "yippy yappy yin yang"); expect(System.getProperty("buzzy.buzzy.bim.bam").equals - (System.getProperties().get("buzzy.buzzy.bim.bam"))); + (System.getProperties().getProperty("buzzy.buzzy.bim.bam"))); expect(System.getProperty("buzzy.buzzy.bim.bam").equals ("yippy yappy yin yang")); diff --git a/test/ci.sh b/test/ci.sh index b48f0355c1..7040c7b921 100755 --- a/test/ci.sh +++ b/test/ci.sh @@ -49,7 +49,7 @@ run make ${flags} process=interpret ${make_target} run make ${flags} mode=debug bootimage=true ${make_target} && \ run make ${flags} bootimage=true ${make_target} -! has_flag openjdk && \ +(! has_flag openjdk && ! has_flag android) && \ run make ${flags} openjdk=$JAVA_HOME ${make_target} run make ${flags} tails=true continuations=true heapdump=true ${make_target} From 7f4c0b3118bd1b2d25a528e06c021d11c43e2cf7 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 22 Aug 2014 07:05:58 -0600 Subject: [PATCH 2/7] fix SSL stack and Android JAR resource loading --- README.md | 5 +++++ classpath/java/lang/Class.java | 4 +++- makefile | 27 +++++++++++++++++++++++++-- src/android/stubs.cpp | 7 +++++++ src/classpath-android.cpp | 5 +++++ src/machine.cpp | 2 -- 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 849fdf71cb..e314b6fb21 100644 --- a/README.md +++ b/README.md @@ -396,6 +396,11 @@ the following, starting from the Avian directory: (cd external/zlib && \ git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0) + git clone https://android.googlesource.com/platform/external/conscrypt \ + external/conscrypt + (cd external/conscrypt && \ + git checkout 076138ff29d805ec5a32d6ad96a18ef08c7f1b11) + git clone git://git.openssl.org/openssl.git openssl-upstream (cd openssl-upstream && git checkout OpenSSL_1_0_1h) diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index 93ac0d77f5..3aa35d06a8 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -529,7 +529,9 @@ public final class Class } public URL getResource(String path) { - if (! path.startsWith("/")) { + if (path.startsWith("/")) { + path = path.substring(1); + } else { String name = Classes.makeString (vmClass.name, 0, vmClass.name.length - 1); int index = name.lastIndexOf('/'); diff --git a/makefile b/makefile index 45f70d2875..4e3a5c5884 100755 --- a/makefile +++ b/makefile @@ -226,6 +226,7 @@ ifneq ($(android),) -I$(android)/external/icu4c/common \ -I$(android)/external/expat \ -I$(android)/external/openssl/include \ + -I$(android)/external/openssl \ -I$(android)/libcore/include \ -I$(build)/android-src/external/fdlibm \ -I$(build)/android-src \ @@ -236,6 +237,7 @@ ifneq ($(android),) -D__DARWIN_UNIX03=1 \ -D__PROVIDE_FIXMES \ -DHAVE_OFF64_T \ + -DSTATIC_LIB \ -g3 \ -Werror @@ -251,6 +253,9 @@ ifneq ($(android),) libnativehelper-cpps := $(libnativehelper-native)/JniConstants.cpp \ $(libnativehelper-native)/toStringArray.cpp + crypto-native := $(android)/external/conscrypt/src/main/native + crypto-cpps := $(crypto-native)/org_conscrypt_NativeCrypto.cpp + ifeq ($(platform),windows) android-cflags += -D__STDC_CONSTANT_MACROS -DHAVE_WIN32_FILEMAP blacklist = $(luni-native)/java_io_Console.cpp \ @@ -274,8 +279,8 @@ ifneq ($(android),) $(icu-libs) \ $(android)/external/fdlibm/libfdm.a \ $(android)/external/expat/.libs/libexpat.a \ - $(android)/openssl-upstream/libcrypto.a \ $(android)/openssl-upstream/libssl.a \ + $(android)/openssl-upstream/libcrypto.a \ $(platform-lflags) \ -lstdc++ @@ -285,6 +290,7 @@ ifneq ($(android),) classpath-objects = \ $(call cpp-objects,$(luni-cpps),$(luni-native),$(build)) \ + $(call cpp-objects,$(crypto-cpps),$(crypto-native),$(build)) \ $(call cpp-objects,$(libnativehelper-cpps),$(libnativehelper-native),$(build)) \ $(call cc-objects,$(libziparchive-ccs),$(libziparchive-native),$(build)) \ $(call cpp-objects,$(libutils-cpps),$(libutils-native),$(build)) @@ -299,6 +305,12 @@ ifneq ($(android),) luni-nonjavas := $(shell find $(luni-java) -not -type d -not -name '*.java') luni-copied-nonjavas = $(call noop-files,$(luni-nonjavas),$(luni-java),) + crypto-java = $(android)/external/conscrypt/src/main/java + crypto-javas := $(shell find $(crypto-java) -name '*.java') + + crypto-platform-java = $(android)/external/conscrypt/src/platform/java + crypto-platform-javas := $(shell find $(crypto-platform-java) -name '*.java') + dalvik-java = $(android)/libcore/dalvik/src/main/java dalvik-javas := \ $(dalvik-java)/dalvik/system/DalvikLogHandler.java \ @@ -323,6 +335,8 @@ ifneq ($(android),) xml-javas := $(shell find $(xml-java) -name '*.java') android-classes = \ $(call java-classes,$(luni-javas),$(luni-java),$(build)/android) \ + $(call java-classes,$(crypto-javas),$(crypto-java),$(build)/android) \ + $(call java-classes,$(crypto-platform-javas),$(crypto-platform-java),$(build)/android) \ $(call java-classes,$(dalvik-javas),$(dalvik-java),$(build)/android) \ $(call java-classes,$(libart-javas),$(libart-java),$(build)/android) \ $(call java-classes,$(xml-javas),$(xml-java),$(build)/android) @@ -1624,6 +1638,9 @@ $(build)/android-src/%.cpp: $(luni-native)/%.cpp $(build)/android-src/%.cpp: $(libnativehelper-native)/%.cpp cp $(<) $(@) +$(build)/android-src/%.cpp: $(crypto-native)/%.cpp + cp $(<) $(@) + $(build)/android-src/%.cpp: $(libziparchive-native)/%.cc cp $(<) $(@) @@ -1637,7 +1654,7 @@ $(build)/%.o: $(build)/android-src/%.cpp $(build)/android.dep $$($(windows-path) $(<)) $(call output,$(@)) $(build)/android.dep: $(luni-javas) $(dalvik-javas) $(libart-javas) \ - $(xml-javas) $(luni-nonjavas) + $(xml-javas) $(luni-nonjavas) $(crypto-javas) $(crypto-platform-javas) @echo "compiling luni classes" @mkdir -p $(classpath-build) @mkdir -p $(build)/android @@ -1653,6 +1670,12 @@ $(build)/android.dep: $(luni-javas) $(dalvik-javas) $(libart-javas) \ (cd $(libart-java) && \ jar c $(call noop-files,$(libart-javas),$(libart-java),.)) \ | (cd $(build)/android-src && jar x) + (cd $(crypto-java) && \ + jar c $(call noop-files,$(crypto-javas),$(crypto-java),.)) \ + | (cd $(build)/android-src && jar x) + (cd $(crypto-platform-java) && \ + jar c $(call noop-files,$(crypto-platform-javas),$(crypto-platform-java),.)) \ + | (cd $(build)/android-src && jar x) (cd $(classpath-src) && \ jar c $(call noop-files,$(classpath-sources),$(classpath-src),.)) \ | (cd $(build)/android-src && jar x) diff --git a/src/android/stubs.cpp b/src/android/stubs.cpp index 7fe9362a3d..0c1295d464 100644 --- a/src/android/stubs.cpp +++ b/src/android/stubs.cpp @@ -15,3 +15,10 @@ void JniConstants::init(_JNIEnv*) { // ignore } + +struct _JavaVM; + +int libconscrypt_JNI_OnLoad(_JavaVM*, void*) +{ + return 0; +} diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 7994c51b48..69d5ab81cf 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -9,6 +9,7 @@ details. */ struct JavaVM; +struct _JavaVM; struct _JNIEnv; struct JniConstants { @@ -17,6 +18,8 @@ struct JniConstants { extern "C" int JNI_OnLoad(JavaVM*, void*); +int libconscrypt_JNI_OnLoad(_JavaVM*, void*); + #define _POSIX_C_SOURCE 200112L #undef _GNU_SOURCE #include "avian/machine.h" @@ -393,6 +396,8 @@ class MyClasspath : public Classpath { JNI_OnLoad(reinterpret_cast< ::JavaVM*>(t->m), 0); + libconscrypt_JNI_OnLoad(reinterpret_cast< ::_JavaVM*>(t->m), 0); + mayInitClasses_ = true; } diff --git a/src/machine.cpp b/src/machine.cpp index 8647ad0ff8..ecc30b3361 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -5665,8 +5665,6 @@ void runFinalizeThread(Thread* t) GcCleaner* cleanList = 0; PROTECT(t, cleanList); - fprintf(stderr, "run finalize thread!\n"); - while (true) { { ACQUIRE(t, t->m->stateLock); From 58cbf5face48118500c7bba57d6c496542ad9b07 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Fri, 22 Aug 2014 16:07:44 -0600 Subject: [PATCH 3/7] fix Android thread enumeration --- src/types.def | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.def b/src/types.def index 6623ac44ea..a140503eba 100644 --- a/src/types.def +++ b/src/types.def @@ -179,6 +179,7 @@ (require uint8_t interrupted) (require uint8_t unparked) (alias peer uint64_t eetop) + (alias peer uint64_t nativePeer) (require uint64_t peer)) (type threadGroup java/lang/ThreadGroup) From 6e209e292503c896cf4054468912632a42b1ccf8 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 2 Sep 2014 10:14:04 -0600 Subject: [PATCH 4/7] a couple of tweaks to get Mac/Android tests passing --- makefile | 5 +++-- src/classpath-android.cpp | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index 4e3a5c5884..6c9cc74476 100755 --- a/makefile +++ b/makefile @@ -236,10 +236,10 @@ ifneq ($(android),) -DJNI_JARJAR_PREFIX= \ -D__DARWIN_UNIX03=1 \ -D__PROVIDE_FIXMES \ - -DHAVE_OFF64_T \ -DSTATIC_LIB \ -g3 \ - -Werror + -Werror \ + -Wno-shift-count-overflow luni-cpps := $(shell find $(luni-native) -name '*.cpp') @@ -285,6 +285,7 @@ ifneq ($(android),) -lstdc++ ifeq ($(platform),linux) + android-cflags += -DHAVE_OFF64_T classpath-lflags += -lrt endif diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 69d5ab81cf..37e3abf04b 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -254,13 +254,14 @@ class MyClasspath : public Classpath { { // force monitor creation so we don't get an OutOfMemory error // later when we try to acquire it: - objectMonitor(t, t->javaThread, true); + objectMonitor(t, t->javaThread->lock(), true); THREAD_RESOURCE0(t, { - vm::acquire(t, t->javaThread); + vm::acquire(t, t->javaThread->lock()); t->clearFlag(Thread::ActiveFlag); - vm::notifyAll(t, t->javaThread); - vm::release(t, t->javaThread); + t->javaThread->peer() = 0; + vm::notifyAll(t, t->javaThread->lock()); + vm::release(t, t->javaThread->lock()); }); GcMethod* method = resolveMethod( From 1ca3e9a5498e8b76cede18d3c1db0c2561129b16 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 15 Sep 2014 08:57:30 -0600 Subject: [PATCH 5/7] add Avian_java_lang_Thread_nativeSetName stub --- src/classpath-android.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index 37e3abf04b..f8a2883611 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -983,6 +983,12 @@ extern "C" AVIAN_EXPORT void JNICALL startThread(t, cast(t, reinterpret_cast(arguments[0]))); } +extern "C" AVIAN_EXPORT void JNICALL + Avian_java_lang_Thread_nativeSetName(Thread*, object, uintptr_t*) +{ + // ignore +} + extern "C" AVIAN_EXPORT void JNICALL Avian_java_lang_Thread_sleep(Thread* t, object, uintptr_t* arguments) { From 5119c81d7d756e10c5dafdb521dec484116ee117 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 18 Sep 2014 11:53:53 -0600 Subject: [PATCH 6/7] update README.md to reflect conscrypt fork --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e314b6fb21..42b3e99859 100644 --- a/README.md +++ b/README.md @@ -396,10 +396,9 @@ the following, starting from the Avian directory: (cd external/zlib && \ git checkout 15b6223aa57a347ce113729253802cb2fdeb4ad0) - git clone https://android.googlesource.com/platform/external/conscrypt \ - external/conscrypt + git clone https://github.com/dicej/android-conscrypt external/conscrypt (cd external/conscrypt && \ - git checkout 076138ff29d805ec5a32d6ad96a18ef08c7f1b11) + git checkout a96719f834232634e9160873bd4c44834b84eb15) git clone git://git.openssl.org/openssl.git openssl-upstream (cd openssl-upstream && git checkout OpenSSL_1_0_1h) @@ -434,7 +433,11 @@ for x86_64 OS X instead of 'CC="gcc -fPIC" ./config': Note that we use https://github.com/dicej/android-libcore64 above instead of the upstream https://android.googlesource.com/platform/libcore repository, since -the former has patches to provide better support for non-Linux platforms. +the former has patches to provide better support for non-Linux +platforms. We have also forked +https://android.googlesource.com/platform/external/conscrypt as +https://github.com/dicej/android-conscrypt to patch that project as +well. Also note that we use the upstream OpenSSL repository and apply the Android patches to it. This is because it is not clear how to build From ffb0f9b345f419a0d2be2a3ccc376e4d7e2c0884 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 29 Sep 2014 11:08:41 -0600 Subject: [PATCH 7/7] provide slightly more complete Thread.nativeGetStatus implementation This fixes SimpleFramework (which depends on Thread.getState returning Thread.State.NEW for unstarted threads) when using the Android class library. --- src/classpath-android.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/classpath-android.cpp b/src/classpath-android.cpp index f8a2883611..0d71913b0d 100644 --- a/src/classpath-android.cpp +++ b/src/classpath-android.cpp @@ -965,10 +965,14 @@ extern "C" AVIAN_EXPORT int64_t JNICALL } extern "C" AVIAN_EXPORT int64_t JNICALL - Avian_java_lang_Thread_nativeGetStatus(Thread*, object, uintptr_t*) + Avian_java_lang_Thread_nativeGetStatus(Thread*, + object, + uintptr_t* arguments) { - // todo - return 1; + enum { New, Runnable, Blocked, Waiting, TimedWaiting, Terminated }; + + // todo: more detail? (e.g. waiting, terminated, etc.) + return arguments[1] ? Runnable : New; } extern "C" AVIAN_EXPORT int64_t JNICALL