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.
This commit is contained in:
Joel Dice 2014-08-21 13:09:42 -06:00
parent ba808a8589
commit b96cc3c575
21 changed files with 556 additions and 1393 deletions

View File

@ -370,7 +370,7 @@ the following, starting from the Avian directory:
git clone https://android.googlesource.com/platform/system/core \ git clone https://android.googlesource.com/platform/system/core \
system/core system/core
(cd system/core && \ (cd system/core && \
git checkout fafcabd0dd4432de3c7f5956edec23f6ed241b56) git checkout 373c77583f9d8eab88e4321d1a2e2af8f5ae8ea7)
git clone https://android.googlesource.com/platform/external/fdlibm \ git clone https://android.googlesource.com/platform/external/fdlibm \
external/fdlibm external/fdlibm
@ -380,11 +380,11 @@ the following, starting from the Avian directory:
git clone https://android.googlesource.com/platform/external/icu4c \ git clone https://android.googlesource.com/platform/external/icu4c \
external/icu4c external/icu4c
(cd external/icu4c && \ (cd external/icu4c && \
git checkout 8fd45e08f1054d80a356ef8aa05659a2ba84707c) git checkout e5311394ca22b280da41cd17059288dab3fb1ea6)
git clone https://android.googlesource.com/platform/libnativehelper git clone https://android.googlesource.com/platform/libnativehelper
(cd libnativehelper && \ (cd libnativehelper && \
git checkout cf5ac0ec696fce7fac6b324ec7d4d6da217e501c) git checkout b14825c7c75420049e03849994265be651cc4a4e)
git clone https://android.googlesource.com/platform/external/openssl \ git clone https://android.googlesource.com/platform/external/openssl \
external/openssl external/openssl
@ -400,6 +400,8 @@ the following, starting from the Avian directory:
(cd openssl-upstream && git checkout OpenSSL_1_0_1h) (cd openssl-upstream && git checkout OpenSSL_1_0_1h)
git clone https://github.com/dicej/android-libcore64 libcore 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 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) (cd external && tar xzf ../expat-2.1.0.tar.gz && mv expat-2.1.0 expat)

View File

@ -559,4 +559,6 @@ public class Classes {
private static native void acquireClassLock(); private static native void acquireClassLock();
private static native void releaseClassLock(); private static native void releaseClassLock();
public static native String makeString(byte[] array, int offset, int length);
} }

View File

@ -0,0 +1,5 @@
package dalvik.system;
public class BaseDexClassLoader extends ClassLoader {
public native String getLdLibraryPath();
}

View File

@ -18,10 +18,12 @@ import avian.Classes;
import avian.InnerClassReference; import avian.InnerClassReference;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -38,7 +40,9 @@ import java.security.ProtectionDomain;
import java.security.Permissions; import java.security.Permissions;
import java.security.AllPermission; import java.security.AllPermission;
public final class Class <T> implements Type, AnnotatedElement { public final class Class <T>
implements Type, AnnotatedElement, GenericDeclaration
{
private static final int PrimitiveFlag = 1 << 5; private static final int PrimitiveFlag = 1 << 5;
private static final int EnumFlag = 1 << 14; private static final int EnumFlag = 1 << 14;
@ -96,9 +100,8 @@ public final class Class <T> implements Type, AnnotatedElement {
} }
} }
return new String return Classes.makeString
(replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1, (replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1);
false);
} }
public String getCanonicalName() { public String getCanonicalName() {
@ -496,6 +499,10 @@ public final class Class <T> implements Type, AnnotatedElement {
return (vmClass.flags & Modifier.INTERFACE) != 0; return (vmClass.flags & Modifier.INTERFACE) != 0;
} }
public boolean isAnnotation() {
return (vmClass.flags & 0x2000) != 0;
}
public Class getSuperclass() { public Class getSuperclass() {
return (vmClass.super_ == null ? null : SystemClassLoader.getClass(vmClass.super_)); return (vmClass.super_ == null ? null : SystemClassLoader.getClass(vmClass.super_));
} }
@ -523,8 +530,8 @@ public final class Class <T> implements Type, AnnotatedElement {
public URL getResource(String path) { public URL getResource(String path) {
if (! path.startsWith("/")) { if (! path.startsWith("/")) {
String name = new String String name = Classes.makeString
(vmClass.name, 0, vmClass.name.length - 1, false); (vmClass.name, 0, vmClass.name.length - 1);
int index = name.lastIndexOf('/'); int index = name.lastIndexOf('/');
if (index >= 0) { if (index >= 0) {
path = name.substring(0, index) + "/" + path; path = name.substring(0, index) + "/" + path;
@ -647,4 +654,12 @@ public final class Class <T> implements Type, AnnotatedElement {
public ProtectionDomain getProtectionDomain() { public ProtectionDomain getProtectionDomain() {
return Classes.getProtectionDomain(vmClass); return Classes.getProtectionDomain(vmClass);
} }
public TypeVariable<?>[] getTypeParameters() {
throw new UnsupportedOperationException("not yet implemented");
}
public Type[] getGenericInterfaces() {
throw new UnsupportedOperationException("not yet implemented");
}
} }

View File

@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.security.ProtectionDomain;
public abstract class ClassLoader { public abstract class ClassLoader {
private final ClassLoader parent; private final ClassLoader parent;
@ -92,6 +93,12 @@ public abstract class ClassLoader {
(avian.Classes.defineVMClass(this, b, offset, length)); (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 { protected Class findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(); throw new ClassNotFoundException();
} }
@ -196,6 +203,10 @@ public abstract class ClassLoader {
return urls; return urls;
} }
protected String findLibrary(String name) {
return null;
}
static native Class getCaller(); static native Class getCaller();
static native void load(String name, Class caller, boolean mapName); static native void load(String name, Class caller, boolean mapName);

View File

@ -44,6 +44,10 @@ public class Constructor<T> extends AccessibleObject implements Member {
return method.getModifiers(); return method.getModifiers();
} }
public boolean isSynthetic() {
return method.isSynthetic();
}
public String getName() { public String getName() {
return method.getName(); return method.getName();
} }
@ -70,4 +74,8 @@ public class Constructor<T> extends AccessibleObject implements Member {
method.invoke(v, arguments); method.invoke(v, arguments);
return v; return v;
} }
public Class<?>[] getExceptionTypes() {
throw new UnsupportedOperationException("not yet implemented");
}
} }

View File

@ -57,13 +57,13 @@ public class Field<T> extends AccessibleObject {
} }
public static String getName(VMField vmField) { 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() { public Class getType() {
return Classes.forCanonicalName return Classes.forCanonicalName
(vmField.class_.loader, (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() { public Type getGenericType() {

View File

@ -0,0 +1,5 @@
package java.lang.reflect;
public interface GenericDeclaration {
TypeVariable<?>[] getTypeParameters();
}

View File

@ -19,4 +19,6 @@ public interface Member {
public int getModifiers(); public int getModifiers();
public String getName(); public String getName();
public boolean isSynthetic();
} }

View File

@ -52,7 +52,7 @@ public class Method<T> extends AccessibleObject implements Member {
} }
public static String getName(VMMethod vmMethod) { 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() { private String getSpec() {
@ -60,7 +60,7 @@ public class Method<T> extends AccessibleObject implements Member {
} }
public static String getSpec(VMMethod vmMethod) { 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() { public Class[] getParameterTypes() {
@ -107,8 +107,8 @@ public class Method<T> extends AccessibleObject implements Member {
if (vmMethod.spec[i] == ')') { if (vmMethod.spec[i] == ')') {
return Classes.forCanonicalName return Classes.forCanonicalName
(vmMethod.class_.loader, (vmMethod.class_.loader,
new String Classes.makeString
(vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false)); (vmMethod.spec, i + 1, vmMethod.spec.length - i - 2));
} }
} }
throw new RuntimeException(); throw new RuntimeException();
@ -149,8 +149,16 @@ public class Method<T> extends AccessibleObject implements Member {
return (getModifiers() & 0x80) != 0; return (getModifiers() & 0x80) != 0;
} }
public boolean isSynthetic() {
return (getModifiers() & 0x1000) != 0;
}
public Object getDefaultValue() { public Object getDefaultValue() {
ClassLoader loader = getDeclaringClass().getClassLoader(); ClassLoader loader = getDeclaringClass().getClassLoader();
return Classes.getAnnotationDefaultValue(loader, vmMethod.addendum); return Classes.getAnnotationDefaultValue(loader, vmMethod.addendum);
} }
public Class<?>[] getExceptionTypes() {
throw new UnsupportedOperationException("not yet implemented");
}
} }

View File

@ -0,0 +1,5 @@
package java.lang.reflect;
public interface TypeVariable<T extends GenericDeclaration> extends Type {
}

View File

@ -0,0 +1,8 @@
package libcore.reflect;
import java.lang.reflect.AccessibleObject;
public class AnnotationAccess {
public static native AccessibleObject getEnclosingMethodOrConstructor
(Class<?> c);
}

View File

@ -88,6 +88,14 @@ public final class Unsafe {
public native void putLongVolatile(Object o, long offset, long x); 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 putOrderedLong(Object o, long offset, long x);
public native void putOrderedInt(Object o, long offset, int x); public native void putOrderedInt(Object o, long offset, int x);

106
makefile
View File

@ -219,6 +219,7 @@ ifneq ($(android),)
classpath-cflags = -DBOOT_JAVAHOME classpath-cflags = -DBOOT_JAVAHOME
android-cflags = -I$(luni-native) \ android-cflags = -I$(luni-native) \
-I$(android)/libnativehelper/include/nativehelper \ -I$(android)/libnativehelper/include/nativehelper \
-I$(android)/libnativehelper \
-I$(android)/system/core/include \ -I$(android)/system/core/include \
-I$(android)/external/zlib \ -I$(android)/external/zlib \
-I$(android)/external/icu4c/i18n \ -I$(android)/external/icu4c/i18n \
@ -234,33 +235,34 @@ ifneq ($(android),)
-DJNI_JARJAR_PREFIX= \ -DJNI_JARJAR_PREFIX= \
-D__DARWIN_UNIX03=1 \ -D__DARWIN_UNIX03=1 \
-D__PROVIDE_FIXMES \ -D__PROVIDE_FIXMES \
-DHAVE_OFF64_T \
-g3 \ -g3 \
-Werror -Werror
luni-cpps := $(shell find $(luni-native) -name '*.cpp') 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-native := $(android)/libnativehelper
libnativehelper-cpps := $(libnativehelper-native)/JniConstants.cpp \ libnativehelper-cpps := $(libnativehelper-native)/JniConstants.cpp \
$(libnativehelper-native)/toStringArray.cpp $(libnativehelper-native)/toStringArray.cpp
crypto-native := $(android)/libcore/crypto/src/main/native
crypto-cpps := $(crypto-native)/org_conscrypt_NativeCrypto.cpp
ifeq ($(platform),windows) 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 \ blacklist = $(luni-native)/java_io_Console.cpp \
$(luni-native)/java_lang_ProcessManager.cpp \ $(luni-native)/java_lang_ProcessManager.cpp
$(luni-native)/java_math_NativeBN.cpp \
$(luni-native)/libcore_net_RawSocket.cpp
icu-libs := $(android)/external/icu4c/lib/sicuin.a \ icu-libs := $(android)/external/icu4c/lib/sicuin.a \
$(android)/external/icu4c/lib/sicuuc.a \ $(android)/external/icu4c/lib/sicuuc.a \
$(android)/external/icu4c/lib/sicudt.a $(android)/external/icu4c/lib/sicudt.a
platform-lflags := -lgdi32 -lshlwapi -lwsock32 platform-lflags := -lgdi32 -lshlwapi -lwsock32
else else
android-cflags += -fPIC -DHAVE_SYS_UIO_H android-cflags += -fPIC -DHAVE_SYS_UIO_H -DHAVE_POSIX_FILEMAP
blacklist = $(luni-native)/java_math_NativeBN.cpp blacklist =
icu-libs := $(android)/external/icu4c/lib/libicui18n.a \ icu-libs := $(android)/external/icu4c/lib/libicui18n.a \
$(android)/external/icu4c/lib/libicuuc.a \ $(android)/external/icu4c/lib/libicuuc.a \
@ -272,8 +274,8 @@ ifneq ($(android),)
$(icu-libs) \ $(icu-libs) \
$(android)/external/fdlibm/libfdm.a \ $(android)/external/fdlibm/libfdm.a \
$(android)/external/expat/.libs/libexpat.a \ $(android)/external/expat/.libs/libexpat.a \
$(android)/openssl-upstream/libssl.a \
$(android)/openssl-upstream/libcrypto.a \ $(android)/openssl-upstream/libcrypto.a \
$(android)/openssl-upstream/libssl.a \
$(platform-lflags) \ $(platform-lflags) \
-lstdc++ -lstdc++
@ -283,25 +285,46 @@ ifneq ($(android),)
classpath-objects = \ classpath-objects = \
$(call cpp-objects,$(luni-cpps),$(luni-native),$(build)) \ $(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-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-nonjavas := $(shell find $(luni-java) -not -type d -not -name '*.java')
luni-copied-nonjavas = $(call noop-files,$(luni-nonjavas),$(luni-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-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-java = $(android)/libcore/xml/src/main/java
xml-javas := $(shell find $(xml-java) -name '*.java') xml-javas := $(shell find $(xml-java) -name '*.java')
android-classes = \ android-classes = \
$(call java-classes,$(luni-javas),$(luni-java),$(build)/android) \ $(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,$(dalvik-javas),$(dalvik-java),$(build)/android) \
$(call java-classes,$(libart-javas),$(libart-java),$(build)/android) \
$(call java-classes,$(xml-javas),$(xml-java),$(build)/android) $(call java-classes,$(xml-javas),$(xml-java),$(build)/android)
classpath = android classpath = android
@ -1113,6 +1136,7 @@ endif
c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x))) c-objects = $(foreach x,$(1),$(patsubst $(2)/%.c,$(3)/%.o,$(x)))
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(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))) asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.$(asm-format),$(3)/%-asm.o,$(x)))
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x))) java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(3)/%.class,$(x)))
noop-files = $(foreach x,$(1),$(patsubst $(2)/%,$(3)/%,$(x))) noop-files = $(foreach x,$(1),$(patsubst $(2)/%,$(3)/%,$(x)))
@ -1383,13 +1407,23 @@ ifneq ($(classpath),avian)
ifeq ($(openjdk),) ifeq ($(openjdk),)
classpath-sources := $(classpath-sources) \ classpath-sources := $(classpath-sources) \
$(classpath-src)/dalvik/system/BaseDexClassLoader.java \
$(classpath-src)/libcore/reflect/AnnotationAccess.java \
$(classpath-src)/sun/reflect/ConstantPool.java \ $(classpath-src)/sun/reflect/ConstantPool.java \
$(classpath-src)/java/lang/ReflectiveOperationException.java \
$(classpath-src)/java/net/ProtocolFamily.java \ $(classpath-src)/java/net/ProtocolFamily.java \
$(classpath-src)/java/net/StandardProtocolFamily.java \ $(classpath-src)/java/net/StandardProtocolFamily.java \
$(classpath-src)/sun/misc/Cleaner.java \ $(classpath-src)/sun/misc/Cleaner.java \
$(classpath-src)/sun/misc/Unsafe.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 endif
else else
classpath-sources := $(shell find $(classpath-src) -name '*.java') 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 $(build)/android-src/%.cpp: $(libnativehelper-native)/%.cpp
cp $(<) $(@) cp $(<) $(@)
$(build)/android-src/%.cpp: $(crypto-native)/%.cpp $(build)/android-src/%.cpp: $(libziparchive-native)/%.cc
cp $(<) $(@)
$(build)/android-src/%.cpp: $(libutils-native)/%.cpp
cp $(<) $(@) cp $(<) $(@)
$(build)/%.o: $(build)/android-src/%.cpp $(build)/android.dep $(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 \ $(cxx) $(android-cflags) $(classpath-extra-cflags) -c \
$$($(windows-path) $(<)) $(call output,$(@)) $$($(windows-path) $(<)) $(call output,$(@))
$(build)/android.dep: $(luni-javas) $(libdvm-javas) $(crypto-javas) \ $(build)/android.dep: $(luni-javas) $(dalvik-javas) $(libart-javas) \
$(dalvik-javas) $(xml-javas) $(luni-nonjavas) $(xml-javas) $(luni-nonjavas)
@echo "compiling luni classes" @echo "compiling luni classes"
@mkdir -p $(classpath-build) @mkdir -p $(classpath-build)
@mkdir -p $(build)/android @mkdir -p $(build)/android
@ -1608,11 +1645,20 @@ $(build)/android.dep: $(luni-javas) $(libdvm-javas) $(crypto-javas) \
@mkdir -p $(build)/android-src/libexpat @mkdir -p $(build)/android-src/libexpat
cp $(android)/external/fdlibm/fdlibm.h $(build)/android-src/external/fdlibm/ cp $(android)/external/fdlibm/fdlibm.h $(build)/android-src/external/fdlibm/
cp $(android)/external/expat/lib/expat*.h $(build)/android-src/libexpat/ cp $(android)/external/expat/lib/expat*.h $(build)/android-src/libexpat/
cp -a $(luni-java)/* $(libdvm-java)/* $(crypto-java)/* $(dalvik-java)/* \ cp -a $(luni-java)/* $(xml-java)/* $(build)/android-src/
$(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 find $(build)/android-src -name '*.java' > $(build)/android.txt
$(javac) -Xmaxerrs 1000 -d $(build)/android -sourcepath $(luni-java) \ $(javac) -Xmaxerrs 1000 -d $(build)/android @$(build)/android.txt
@$(build)/android.txt
rm $(build)/android/sun/misc/Unsafe* \ rm $(build)/android/sun/misc/Unsafe* \
$(build)/android/java/lang/reflect/Proxy* $(build)/android/java/lang/reflect/Proxy*
for x in $(luni-copied-nonjavas); \ for x in $(luni-copied-nonjavas); \

View File

@ -781,6 +781,116 @@ unsigned classModifiers(Thread* t, GcClass* c)
return c->flags(); return c->flags();
} }
object makeMethod(Thread* t, GcJclass* class_, int index)
{
GcMethod* method = cast<GcMethod>(
t, cast<GcArray>(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, "<init>", "(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, "<init>", "(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<int8_t>(instance, offset);
case BooleanField:
return fieldAtOffset<uint8_t>(instance, offset);
case CharField:
return fieldAtOffset<uint16_t>(instance, offset);
case ShortField:
return fieldAtOffset<int16_t>(instance, offset);
case IntField:
return fieldAtOffset<int32_t>(instance, offset);
case LongField:
return fieldAtOffset<int64_t>(instance, offset);
case FloatField:
return fieldAtOffset<uint32_t>(instance, offset);
case DoubleField:
return fieldAtOffset<uint64_t>(instance, offset);
default:
abort(t);
}
}
void setPrimitive(Thread* t,
object instance,
int code,
int offset,
int64_t value)
{
switch (code) {
case ByteField:
fieldAtOffset<int8_t>(instance, offset) = static_cast<int8_t>(value);
break;
case BooleanField:
fieldAtOffset<uint8_t>(instance, offset) = static_cast<uint8_t>(value);
break;
case CharField:
fieldAtOffset<uint16_t>(instance, offset) = static_cast<uint16_t>(value);
break;
case ShortField:
fieldAtOffset<int16_t>(instance, offset) = static_cast<int16_t>(value);
break;
case IntField:
fieldAtOffset<int32_t>(instance, offset) = static_cast<int32_t>(value);
break;
case LongField:
fieldAtOffset<int64_t>(instance, offset) = static_cast<int64_t>(value);
break;
case FloatField:
fieldAtOffset<uint32_t>(instance, offset) = static_cast<uint32_t>(value);
break;
case DoubleField:
fieldAtOffset<uint64_t>(instance, offset) = static_cast<uint64_t>(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<int64_t>(translateInvokeResult(
t, returnCode, t->m->processor->invokeArray(t, method, instance, args)));
}
} // namespace vm } // namespace vm
#endif // CLASSPATH_COMMON_H #endif // CLASSPATH_COMMON_H

View File

@ -157,6 +157,18 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
return reinterpret_cast<int64_t>(defineClass(t, loader, buffer, length)); return reinterpret_cast<int64_t>(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<GcByteArray>(t, reinterpret_cast<object>(arguments[0]));
int offset = arguments[1];
int length = arguments[2];
return reinterpret_cast<int64_t>(
t->m->classpath->makeString(t, array, offset, length));
}
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findLoadedVMClass(Thread* t, Avian_avian_SystemClassLoader_findLoadedVMClass(Thread* t,
object, object,

File diff suppressed because it is too large Load Diff

View File

@ -343,30 +343,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); return getPrimitive(
int code = arguments[1]; t, reinterpret_cast<object>(arguments[0]), arguments[1], arguments[2]);
int offset = arguments[2];
switch (code) {
case ByteField:
return fieldAtOffset<int8_t>(instance, offset);
case BooleanField:
return fieldAtOffset<uint8_t>(instance, offset);
case CharField:
return fieldAtOffset<uint16_t>(instance, offset);
case ShortField:
return fieldAtOffset<int16_t>(instance, offset);
case IntField:
return fieldAtOffset<int32_t>(instance, offset);
case LongField:
return fieldAtOffset<int64_t>(instance, offset);
case FloatField:
return fieldAtOffset<uint32_t>(instance, offset);
case DoubleField:
return fieldAtOffset<uint64_t>(instance, offset);
default:
abort(t);
}
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -374,10 +352,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); return reinterpret_cast<int64_t>(fieldAtOffset<object>(
int offset = arguments[1]; reinterpret_cast<object>(arguments[0]), arguments[1]));
return reinterpret_cast<int64_t>(fieldAtOffset<object>(instance, offset));
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
@ -385,40 +361,14 @@ extern "C" AVIAN_EXPORT void JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]);
int code = arguments[1];
int offset = arguments[2];
int64_t value; int64_t value;
memcpy(&value, arguments + 3, 8); memcpy(&value, arguments + 3, 8);
switch (code) { setPrimitive(t,
case ByteField: reinterpret_cast<object>(arguments[0]),
fieldAtOffset<int8_t>(instance, offset) = static_cast<int8_t>(value); arguments[1],
break; arguments[2],
case BooleanField: value);
fieldAtOffset<uint8_t>(instance, offset) = static_cast<uint8_t>(value);
break;
case CharField:
fieldAtOffset<uint16_t>(instance, offset) = static_cast<uint16_t>(value);
break;
case ShortField:
fieldAtOffset<int16_t>(instance, offset) = static_cast<int16_t>(value);
break;
case IntField:
fieldAtOffset<int32_t>(instance, offset) = static_cast<int32_t>(value);
break;
case LongField:
fieldAtOffset<int64_t>(instance, offset) = static_cast<int64_t>(value);
break;
case FloatField:
fieldAtOffset<uint32_t>(instance, offset) = static_cast<uint32_t>(value);
break;
case DoubleField:
fieldAtOffset<uint64_t>(instance, offset) = static_cast<uint64_t>(value);
break;
default:
abort(t);
}
} }
extern "C" AVIAN_EXPORT void JNICALL extern "C" AVIAN_EXPORT void JNICALL
@ -426,11 +376,10 @@ extern "C" AVIAN_EXPORT void JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
object instance = reinterpret_cast<object>(arguments[0]); setField(t,
int offset = arguments[1]; reinterpret_cast<object>(arguments[0]),
object value = reinterpret_cast<object>(arguments[2]); arguments[1],
reinterpret_cast<object>(arguments[2]));
setField(t, instance, offset, value);
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -438,9 +387,8 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
GcClass* c = cast<GcClass>(t, reinterpret_cast<object>(arguments[0])); return reinterpret_cast<int64_t>(
make(t, cast<GcClass>(t, reinterpret_cast<object>(arguments[0]))));
return reinterpret_cast<int64_t>(make(t, c));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL extern "C" AVIAN_EXPORT int64_t JNICALL
@ -454,22 +402,10 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
object, object,
uintptr_t* arguments) uintptr_t* arguments)
{ {
GcMethod* method = cast<GcMethod>(t, reinterpret_cast<object>(arguments[0])); return invokeMethod(t,
object instance = reinterpret_cast<object>(arguments[1]); cast<GcMethod>(t, reinterpret_cast<object>(arguments[0])),
object args = reinterpret_cast<object>(arguments[2]); reinterpret_cast<object>(arguments[1]),
reinterpret_cast<object>(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<int64_t>(translateInvokeResult(
t, returnCode, t->m->processor->invokeArray(t, method, instance, args)));
} }
extern "C" AVIAN_EXPORT int64_t JNICALL 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 extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments) Avian_avian_Classes_makeMethod(Thread* t, object, uintptr_t* arguments)
{ {
GcMethod* method = cast<GcMethod>( return reinterpret_cast<uintptr_t>(
t, makeMethod(t,
cast<GcArray>(t, cast<GcJclass>(t, reinterpret_cast<object>(arguments[0])),
cast<GcJclass>(t, reinterpret_cast<object>(arguments[0])) arguments[1]));
->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, "<init>", "(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, "<init>", "(Ljava/lang/Method;)V");
t->m->processor->invoke(t, constructor, instance, oldInstance);
}
return reinterpret_cast<uintptr_t>(instance);
} }

View File

@ -5665,6 +5665,8 @@ void runFinalizeThread(Thread* t)
GcCleaner* cleanList = 0; GcCleaner* cleanList = 0;
PROTECT(t, cleanList); PROTECT(t, cleanList);
fprintf(stderr, "run finalize thread!\n");
while (true) { while (true) {
{ {
ACQUIRE(t, t->m->stateLock); ACQUIRE(t, t->m->stateLock);

View File

@ -316,21 +316,21 @@ public class Misc {
expect(staticRan); expect(staticRan);
expect(System.getProperty("java.class.path").equals 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 expect(System.getProperty("path.separator").equals
(System.getProperties().get("path.separator"))); (System.getProperties().getProperty("path.separator")));
expect(System.getProperty("user.dir").equals expect(System.getProperty("user.dir").equals
(System.getProperties().get("user.dir"))); (System.getProperties().getProperty("user.dir")));
expect(System.getProperty("java.io.tmpdir").equals 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"); System.setProperty("buzzy.buzzy.bim.bam", "dippy dopey flim flam");
expect(System.getProperty("buzzy.buzzy.bim.bam").equals 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 expect(System.getProperty("buzzy.buzzy.bim.bam").equals
("dippy dopey flim flam")); ("dippy dopey flim flam"));
@ -338,7 +338,7 @@ public class Misc {
System.getProperties().put("buzzy.buzzy.bim.bam", "yippy yappy yin yang"); System.getProperties().put("buzzy.buzzy.bim.bam", "yippy yappy yin yang");
expect(System.getProperty("buzzy.buzzy.bim.bam").equals 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 expect(System.getProperty("buzzy.buzzy.bim.bam").equals
("yippy yappy yin yang")); ("yippy yappy yin yang"));

View File

@ -49,7 +49,7 @@ run make ${flags} process=interpret ${make_target}
run make ${flags} mode=debug bootimage=true ${make_target} && \ run make ${flags} mode=debug bootimage=true ${make_target} && \
run make ${flags} 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} openjdk=$JAVA_HOME ${make_target}
run make ${flags} tails=true continuations=true heapdump=true ${make_target} run make ${flags} tails=true continuations=true heapdump=true ${make_target}