Merge branch 'master' of git://oss.readytalk.com/avian

This commit is contained in:
Josh warner 2009-08-10 13:42:57 -06:00
commit af4d82ef7e
11 changed files with 2278 additions and 19 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

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,16 +29,20 @@
# define PATH_SEPARATOR ':'
#endif
#if (defined __i386__) || (defined __POWERPC__)
#if (defined __i386__) || (defined __POWERPC__) || (defined __arm__)
# define LD "ld"
# define LLD "lld"
#ifdef __APPLE__
# define ULD "lu"
# define LX "lx"
#else
# define LX "x"
# define ULD "u"
#endif
# ifdef __MINGW32__
# define LLD "I64d"
# else
# define LLD "lld"
# endif
# ifdef __APPLE__
# define ULD "lu"
# define LX "lx"
# else
# define LX "x"
# define ULD "u"
# endif
#elif defined __x86_64__
# ifdef __MINGW32__
# define LD "I64d"

View File

@ -190,8 +190,10 @@ compareIpToMethodBounds(Thread* t, intptr_t ip, object method)
intptr_t start = methodCompiled(t, method);
if (DebugMethodTree) {
fprintf(stderr, "find 0x%"LX" in (0x%"LX",0x%"LX")\n", ip, start,
start + compiledSize(start));
fprintf(stderr, "find %p in (%p,%p)\n",
reinterpret_cast<void*>(ip),
reinterpret_cast<void*>(start),
reinterpret_cast<void*>(start + compiledSize(start)));
}
if (ip < start) {

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
@ -170,7 +174,11 @@ popLong(Thread* t)
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);

View File

@ -1049,7 +1049,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
case 4:
if (bSize == 8) {
if (BytesPerWord == 8) {
alwaysRex(c, aSize, b, a);
alwaysRex(c, bSize, b, a);
opcode(c, 0x63);
modrm(c, 0xc0, a, b);
} else {

View File

@ -35,7 +35,13 @@ public class Longs {
return a - (a % b);
}
private static int negativeOne() {
return -1;
}
public static void main(String[] args) {
expect(((long) negativeOne()) == -1);
{ long foo = 25214903884L;
int radix = 10;
expect(foo > 0);

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
log=build/log.txt
vg="nice valgrind --leak-check=full --num-callers=32 \
@ -28,7 +28,7 @@ for test in ${tests}; do
exit 1;;
esac
if (( ${?} == 0 )); then
if [ "${?}" = "0" ]; then
echo "success"
else
echo "fail"