From b96cc3c575670fefc8b174660cdc2902a108e217 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 21 Aug 2014 13:09:42 -0600 Subject: [PATCH] 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}