added ARM interpreted mode supported

This commit is contained in:
jet 2009-08-06 11:52:36 -06:00
parent 6d27274aea
commit 1ffe46a545
8 changed files with 2300 additions and 124 deletions

View File

@ -27,6 +27,7 @@
# include <netdb.h>
# include <sys/select.h>
# include <netinet/tcp.h>
# include <sys/socket.h>
#endif
#define java_nio_channels_SelectionKey_OP_READ 1L

163
makefile
View File

@ -18,6 +18,10 @@ bootimage-platform = \
$(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
platform = $(bootimage-platform)
ifeq ($(platform),windows)
arch = i386
endif
mode = fast
process = compile
@ -39,23 +43,6 @@ endif
ifeq ($(continuations),true)
options := $(options)-continuations
endif
ifdef gnu
options := $(options)-gnu
gnu-sources = $(src)/gnu.cpp
gnu-jar = $(gnu)/share/classpath/glibj.zip
gnu-libraries = \
$(gnu)/lib/classpath/libjavaio.a \
$(gnu)/lib/classpath/libjavalang.a \
$(gnu)/lib/classpath/libjavalangreflect.a \
$(gnu)/lib/classpath/libjavamath.a \
$(gnu)/lib/classpath/libjavanet.a \
$(gnu)/lib/classpath/libjavanio.a \
$(gnu)/lib/classpath/libjavautil.a
gnu-object-dep = $(build)/gnu-object.dep
gnu-cflags = -DBOOT_BUILTINS=\"javaio,javalang,javalangreflect,javamath,javanet,javanio,javautil\" -DAVIAN_GNU
gnu-lflags = -lgmp
gnu-objects = $(shell find $(build)/gnu-objects -name "*.o")
endif
root = $(shell (cd .. && pwd))
build = build
@ -66,12 +53,6 @@ src = src
classpath = classpath
test = test
ifdef gnu
avian-classpath-build = $(build)/avian-classpath
else
avian-classpath-build = $(classpath-build)
endif
input = List
build-cxx = g++
@ -102,14 +83,13 @@ warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
common-cflags = $(warnings) -fno-rtti -fno-exceptions -fno-omit-frame-pointer \
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(native-build) \
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
$(gnu-cflags)
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden \
"-I$(JAVA_HOME)/include/linux" -I$(src) -pthread
cflags = $(build-cflags)
common-lflags = -lm -lz $(gnu-lflags)
common-lflags = -lm -lz
build-lflags =
@ -140,6 +120,21 @@ ifeq ($(arch),powerpc)
object-format = elf32-powerpc
pointer-size = 4
endif
ifeq ($(arch),arm)
lflags := -L/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/lib -L$(root)/arm/lib $(lflags)
cflags := -I/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/include -I$(root)/arm/include $(cflags)
asm = arm
object-arch = arm
object-format = elf32-littlearm
pointer-size = 4
cxx = arm-unknown-linux-gnu-g++
cc = arm-unknown-linux-gnu-gcc
ar = arm-unknown-linux-gnu-ar
ranlib = arm-unknown-linux-gnu-ranlib
objcopy = arm-unknown-linux-gnu-objcopy
strip = arm-unknown-linux-gnu-strip
endif
ifeq ($(platform),darwin)
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src)
@ -187,21 +182,6 @@ ifeq ($(platform),windows)
native-path = cygpath -m
endif
endif
ifeq ($(arch),x86_64)
cxx = x86_64-pc-mingw32-g++
cc = x86_64-pc-mingw32-gcc
dlltool = x86_64-pc-mingw32-dlltool
ar = x86_64-pc-mingw32-ar
ranlib = x86_64-pc-mingw32-ranlib
objcopy = x86_64-pc-mingw32-objcopy
strip = :
inc = "$(root)/win64/include"
lib = "$(root)/win64/lib"
pointer-size = 8
object-format = pe-x86-64
endif
endif
ifeq ($(mode),debug)
@ -267,8 +247,7 @@ vm-sources = \
$(src)/$(process).cpp \
$(src)/builtin.cpp \
$(src)/jnienv.cpp \
$(src)/process.cpp \
$(gnu-sources)
$(src)/process.cpp
vm-asm-sources = $(src)/$(asm).S
@ -350,43 +329,16 @@ classpath-sources = $(shell find $(classpath) -name '*.java')
classpath-classes = \
$(call java-classes,$(classpath-sources),$(classpath),$(classpath-build))
classpath-object = $(native-build)/classpath-jar.o
classpath-dep = $(classpath-build).dep
gnu-blacklist = \
java/lang/AbstractStringBuffer.class \
java/lang/reflect/Proxy.class
gnu-overrides = \
avian/*.class \
avian/resource/*.class \
java/lang/Class.class \
java/lang/Enum.class \
java/lang/InheritableThreadLocal.class \
java/lang/Object.class \
java/lang/StackTraceElement.class \
java/lang/String*.class \
java/lang/StringBuffer.class \
java/lang/StringBuilder.class \
java/lang/Thread.class \
java/lang/ThreadLocal.class \
java/lang/Throwable.class \
java/lang/ref/PhantomReference.class \
java/lang/ref/Reference.class \
java/lang/ref/ReferenceQueue.class \
java/lang/ref/WeakReference.class \
java/lang/reflect/AccessibleObject.class \
java/lang/reflect/Constructor.class \
java/lang/reflect/Field.class \
java/lang/reflect/Method.class
classpath-dep = $(classpath-build)/dep
test-sources = $(wildcard $(test)/*.java)
test-classes = $(call java-classes,$(test-sources),$(test),$(test-build))
test-dep = $(test-build).dep
test-dep = $(test-build)/dep
test-extra-sources = $(wildcard $(test)/extra/*.java)
test-extra-classes = \
$(call java-classes,$(test-extra-sources),$(test),$(test-build))
test-extra-dep = $(test-build)-extra.dep
test-extra-dep = $(test-build)/extra/dep
class-name = $(patsubst $(1)/%.class,%,$(2))
class-names = $(foreach x,$(2),$(call class-name,$(1),$(x)))
@ -456,24 +408,11 @@ $(native-build)/type-generator.o: \
$(classpath-build)/%.class: $(classpath)/%.java
@echo $(<)
$(classpath-dep): $(classpath-sources) $(gnu-jar)
$(classpath-dep): $(classpath-sources)
@echo "compiling classpath classes"
@mkdir -p $(avian-classpath-build)
$(javac) -d $(avian-classpath-build) \
-bootclasspath $(avian-classpath-build) \
@mkdir -p $(dir $(@))
$(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \
$(shell $(MAKE) -s --no-print-directory $(classpath-classes))
ifdef gnu
(wd=$$(pwd) && \
cd $(avian-classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(build)/overrides.jar")" \
$(gnu-overrides))
@mkdir -p $(classpath-build)
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) xf $(gnu-jar) && \
rm $(gnu-blacklist) && \
jar xf "$$($(native-path) "$${wd}/$(build)/overrides.jar")")
endif
@touch $(@)
$(test-build)/%.class: $(test)/%.java
@ -481,16 +420,16 @@ $(test-build)/%.class: $(test)/%.java
$(test-dep): $(test-sources)
@echo "compiling test classes"
@mkdir -p $(test-build)
$(javac) -d $(test-build) -bootclasspath $(classpath-build) \
@mkdir -p $(dir $(@))
$(javac) -d $(dir $(@)) -bootclasspath $(classpath-build) \
$(shell $(MAKE) -s --no-print-directory $(test-classes))
$(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(test-build) \
$(javac) -source 1.2 -target 1.1 -XDjsrlimit=0 -d $(dir $(@)) \
test/Subroutine.java
@touch $(@)
$(test-extra-dep): $(test-extra-sources)
@echo "compiling extra test classes"
@mkdir -p $(test-build)
@mkdir -p $(dir $(@))
$(javac) -d $(test-build) -bootclasspath $(classpath-build) \
$(shell $(MAKE) -s --no-print-directory $(test-extra-classes))
@touch $(@)
@ -532,9 +471,9 @@ $(boot-object): $(boot-source)
$(compile-object)
$(build)/classpath.jar: $(classpath-dep)
(wd=$$(pwd) && \
cd $(classpath-build) && \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" .)
(wd=$$(pwd); \
cd $(classpath-build); \
$(jar) c0f "$$($(native-path) "$${wd}/$(@)")" $$(find . -name '*.class'))
$(binaryToMacho): $(src)/binaryToMacho.cpp
$(cxx) $(^) -o $(@)
@ -545,8 +484,8 @@ ifeq ($(platform),darwin)
$(binaryToMacho) $(asm) $(build)/classpath.jar __TEXT __text \
__binary_classpath_jar_start __binary_classpath_jar_end > $(@)
else
(wd=$$(pwd) && \
cd $(build) && \
(wd=$$(pwd); \
cd $(build); \
$(objcopy) -I binary classpath.jar \
-O $(object-format) -B $(object-arch) "$${wd}/$(@)")
endif
@ -560,11 +499,10 @@ $(generator-objects): $(native-build)/%.o: $(src)/%.cpp
$(jni-objects): $(native-build)/%.o: $(classpath)/%.cpp
$(compile-object)
$(static-library): $(gnu-object-dep)
$(static-library): $(vm-objects) $(jni-objects) $(vm-heapwalk-objects)
@echo "creating $(@)"
rm -rf $(@)
$(ar) cru $(@) $(^) $(call gnu-objects)
$(ar) cru $(@) $(^)
$(ranlib) $(@)
$(bootimage-bin): $(bootimage-generator)
@ -576,32 +514,24 @@ ifeq ($(platform),darwin)
$(binaryToMacho) $(asm) $(<) __BOOT __boot \
__binary_bootimage_bin_start __binary_bootimage_bin_end > $(@)
else
(wd=$$(pwd) && \
cd $(native-build) && \
(wd=$$(pwd); \
cd $(native-build); \
$(objcopy) --rename-section=.data=.boot -I binary bootimage.bin \
-O $(object-format) -B $(object-arch) "$${wd}/$(@).tmp" && \
-O $(object-format) -B $(object-arch) "$${wd}/$(@).tmp"; \
$(objcopy) --set-section-flags .boot=alloc,load,code "$${wd}/$(@).tmp" \
"$${wd}/$(@)")
endif
$(gnu-object-dep): $(gnu-libraries)
@mkdir -p $(build)/gnu-objects
(cd $(build)/gnu-objects && \
for x in $(gnu-libraries); do ar x $${x}; done)
@touch $(@)
$(executable): $(gnu-object-dep)
$(executable): \
$(vm-objects) $(jni-objects) $(driver-object) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object)
@echo "linking $(@)"
ifeq ($(platform),windows)
$(dlltool) -z $(@).def $(^) $(call gnu-objects)
$(dlltool) -z $(@).def $(^)
$(dlltool) -d $(@).def -e $(@).exp
$(cc) $(@).exp $(^) $(call gnu-objects) $(lflags) -o $(@)
$(cc) $(@).exp $(^) $(lflags) -o $(@)
else
$(cc) $(^) $(call gnu-objects) $(rdynamic) $(lflags) $(bootimage-lflags) \
-o $(@)
$(cc) $(^) $(rdynamic) $(lflags) $(bootimage-lflags) -o $(@)
endif
$(strip) $(strip-all) $(@)
@ -630,13 +560,11 @@ else
$(cc) $(^) $(rdynamic) $(lflags) -o $(@)
endif
$(dynamic-library): $(gnu-object-dep)
$(dynamic-library): \
$(vm-objects) $(dynamic-object) $(jni-objects) $(vm-heapwalk-objects) \
$(boot-object) $(vm-classpath-object) $(gnu-libraries)
$(boot-object) $(vm-classpath-object)
@echo "linking $(@)"
$(cc) $(^) $(call gnu-objects) $(shared) $(lflags) $(bootimage-lflags) \
-o $(@)
$(cc) $(^) $(shared) $(lflags) $(bootimage-lflags) -o $(@)
$(strip) $(strip-all) $(@)
$(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
@ -647,3 +575,4 @@ $(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
$(generator): $(generator-objects)
@echo "linking $(@)"
$(build-cc) $(^) $(build-lflags) -o $(@)

View File

@ -21,6 +21,8 @@ vmJump(void* address, void* base, void* stack, void* thread,
# include "x86.h"
#elif defined __POWERPC__
# include "powerpc.h"
#elif defined __arm__
# include "arm.h"
#else
# error unsupported architecture
#endif

56
src/arm.S Normal file
View File

@ -0,0 +1,56 @@
/* arm.S: JNI gluecode for ARM/Linux
Copyright (c) 2008-2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
.text
.globl vmNativeCall
vmNativeCall:
/*
arguments:
r0 -> r4 : function
r1 -> r5 : stackTotal
r2 : memoryTable
r3 : memoryCount
[sp, #0] -> r6 : gprTable
*/
mov ip, sp // save stack frame
stmfd sp!, {r4-r6, lr} // save clobbered non-volatile regs
// mv args into non-volatile regs
mov r4, r0
mov r5, r1
ldr r6, [ip]
// setup stack arguments if necessary
sub sp, sp, r5 // allocate stack
mov ip, sp
.Lloop:
tst r3, r3
ldrne r0, [r2], #4
strne r0, [ip], #4
subne r3, r3, #4
bne .Lloop
// setup argument registers if necessary
tst r6, r6
ldmneia r6, {r0-r3}
blx r4 // call function
add sp, sp, r5 // deallocate stack
ldmfd sp!, {r4-r6, pc} // restore non-volatile regs and return
.globl vmJump
vmJump:
mov sp, r2
mov r4, r3
ldmia sp, {r0,r1}
mov pc, lr

2043
src/arm.cpp Normal file

File diff suppressed because it is too large Load Diff

119
src/arm.h Normal file
View File

@ -0,0 +1,119 @@
/* Copyright (c) 2008-2009, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef ARM_H
#define ARM_H
#include "types.h"
#include "common.h"
#define IP_REGISTER(context) (context->uc_mcontext.gregs[15])
#define STACK_REGISTER(context) (context->uc_mcontext.gregs[13])
#define THREAD_REGISTER(context) (context->uc_mcontext.gregs[12])
extern "C" uint64_t
vmNativeCall(void* function, unsigned stackTotal, void* memoryTable,
unsigned memoryCount, void* gprTable);
namespace vm {
inline void
trap()
{
asm("nop");
}
inline void
memoryBarrier()
{
asm("nop");
}
inline void
storeStoreMemoryBarrier()
{
memoryBarrier();
}
inline void
storeLoadMemoryBarrier()
{
memoryBarrier();
}
inline void
loadMemoryBarrier()
{
memoryBarrier();
}
inline void
syncInstructionCache(const void* start UNUSED, unsigned size UNUSED)
{
asm("nop");
}
inline uint64_t
dynamicCall(void* function, uintptr_t* arguments, uint8_t* argumentTypes,
unsigned argumentCount, unsigned argumentsSize,
unsigned returnType UNUSED)
{
const unsigned GprCount = 4;
uintptr_t gprTable[GprCount];
unsigned gprIndex = 0;
uintptr_t stack[argumentsSize / BytesPerWord];
unsigned stackIndex = 0;
unsigned ai = 0;
for (unsigned ati = 0; ati < argumentCount; ++ ati) {
switch (argumentTypes[ati]) {
case DOUBLE_TYPE:
case INT64_TYPE: {
if (gprIndex + (8 / BytesPerWord) <= GprCount) {
memcpy(gprTable + gprIndex, arguments + ai, 8);
gprIndex += 8 / BytesPerWord;
} else if (gprIndex == GprCount-1) { // split between last GPR and stack
memcpy(gprTable + gprIndex, arguments + ai, 4);
++gprIndex;
memcpy(stack + stackIndex, arguments + ai + 4, 4);
++stackIndex;
} else {
memcpy(stack + stackIndex, arguments + ai, 8);
stackIndex += 8 / BytesPerWord;
}
ai += 8 / BytesPerWord;
} break;
default: {
if (gprIndex < GprCount) {
gprTable[gprIndex++] = arguments[ai];
} else {
stack[stackIndex++] = arguments[ai];
}
++ ai;
} break;
}
}
if (gprIndex < GprCount) { // pad since assembly loads all GPRs
memset(gprTable + gprIndex, 0, (GprCount-gprIndex)*4);
gprIndex = GprCount;
}
unsigned stackSize = stackIndex*BytesPerWord + ((stackIndex & 1) << 2);
return vmNativeCall
(function, stackSize, stack, stackIndex * BytesPerWord,
(gprIndex ? gprTable : 0));
}
} // namespace vm
#endif // ARM_H

View File

@ -29,7 +29,7 @@
# define PATH_SEPARATOR ':'
#endif
#if (defined __i386__) || (defined __POWERPC__)
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
# define LD "ld"
# define LLD "lld"
#ifdef __APPLE__

View File

@ -117,7 +117,11 @@ pushLong(Thread* t, uint64_t v)
inline void
pushDouble(Thread* t, double v)
{
pushLong(t, doubleToBits(v));
uint64_t w = doubleToBits(v);
#ifdef __arm__
w = w << 32 | w >> 32;
#endif
pushLong(t, w);
}
inline object
@ -167,10 +171,14 @@ popLong(Thread* t)
return (b << 32) | a;
}
inline float
inline double
popDouble(Thread* t)
{
return bitsToDouble(popLong(t));
uint64_t v = popLong(t);
#ifdef __arm__
v = v << 32 | v >> 32;
#endif
return bitsToDouble(v);
}
inline object
@ -560,8 +568,17 @@ pushResult(Thread* t, unsigned returnCode, uint64_t result, bool indirect)
pushInt(t, result);
break;
case LongField:
case DoubleField:
#ifdef __arm__
result = result << 32 | result >> 32;
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
}
pushLong(t, result);
break;
#endif
case LongField:
if (DebugRun) {
fprintf(stderr, "result: %"LLD"\n", result);
}
@ -611,8 +628,17 @@ marshalArguments(Thread* t, uintptr_t* args, unsigned i, unsigned count,
args[offset++] = peekInt(t, sp++);
break;
case INT64_TYPE:
case DOUBLE_TYPE: {
case DOUBLE_TYPE:
#ifdef __arm__
{
uint64_t v = peekLong(t, sp);
v = v << 32 | v >> 32;
memcpy(args + offset, &v, 8);
offset += (8 / BytesPerWord);
sp += 2;
} break;
#endif
case INT64_TYPE: {
uint64_t v = peekLong(t, sp);
memcpy(args + offset, &v, 8);
offset += (8 / BytesPerWord);