mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
Merge branch 'win64' into gnu
Conflicts: makefile src/compile-x86.S src/x86.S src/x86.cpp
This commit is contained in:
commit
27d863790c
@ -23,6 +23,7 @@
|
||||
#ifdef WIN32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
|
||||
# define OPEN _open
|
||||
# define CLOSE _close
|
||||
|
@ -81,7 +81,7 @@ namespace {
|
||||
|
||||
int descriptor(JNIEnv* e, HANDLE h)
|
||||
{
|
||||
int fd = _open_osfhandle(reinterpret_cast<long>(h), 0);
|
||||
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(h), 0);
|
||||
if (fd == -1) {
|
||||
throwNew(e, "java/io/IOException", strerror(errno));
|
||||
}
|
||||
|
@ -176,6 +176,8 @@ public final class Class <T> implements Type, GenericDeclaration {
|
||||
|
||||
private Method findMethod(String name, Class[] parameterTypes) {
|
||||
if (methodTable != null) {
|
||||
if (parameterTypes == null)
|
||||
parameterTypes = new Class[0];
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (methodTable[i].getName().equals(name)
|
||||
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
||||
|
20
makefile
20
makefile
@ -18,10 +18,6 @@ bootimage-platform = \
|
||||
$(subst cygwin,windows,$(subst mingw32,windows,$(build-platform)))
|
||||
platform = $(bootimage-platform)
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
arch = i386
|
||||
endif
|
||||
|
||||
mode = fast
|
||||
process = compile
|
||||
|
||||
@ -191,6 +187,21 @@ 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)
|
||||
@ -636,4 +647,3 @@ $(executable-dynamic): $(driver-dynamic-object) $(dynamic-library)
|
||||
$(generator): $(generator-objects)
|
||||
@echo "linking $(@)"
|
||||
$(build-cc) $(^) $(build-lflags) -o $(@)
|
||||
|
||||
|
15
src/common.h
15
src/common.h
@ -40,10 +40,17 @@
|
||||
# define ULD "u"
|
||||
#endif
|
||||
#elif defined __x86_64__
|
||||
# define LD "ld"
|
||||
# define LX "lx"
|
||||
# define LLD "ld"
|
||||
# define ULD "lu"
|
||||
# ifdef __MINGW32__
|
||||
# define LD "I64d"
|
||||
# define LX "I64x"
|
||||
# define LLD "I64d"
|
||||
# define ULD "I64x"
|
||||
# else
|
||||
# define LD "ld"
|
||||
# define LX "lx"
|
||||
# define LLD "ld"
|
||||
# define ULD "lu"
|
||||
# endif
|
||||
#else
|
||||
# error "Unsupported architecture"
|
||||
#endif
|
||||
|
@ -22,18 +22,139 @@
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define THREAD_CONTINUATION 168
|
||||
#define THREAD_EXCEPTION 64
|
||||
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 176
|
||||
#define THREAD_EXCEPTION_OFFSET 184
|
||||
#define THREAD_EXCEPTION_HANDLER 192
|
||||
#ifdef __MINGW32__
|
||||
|
||||
#define CONTINUATION_NEXT 8
|
||||
#define CONTINUATION_ADDRESS 32
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 40
|
||||
#define CONTINUATION_FRAME_POINTER_OFFSET 48
|
||||
#define CONTINUATION_LENGTH 56
|
||||
#define CONTINUATION_BODY 64
|
||||
#define CALLEE_SAVED_REGISTER_FOOTPRINT 64
|
||||
|
||||
.globl GLOBAL(vmInvoke)
|
||||
GLOBAL(vmInvoke):
|
||||
pushq %rbp
|
||||
movq %rsp,%rbp
|
||||
|
||||
// %rcx: thread
|
||||
// %rdx: function
|
||||
// %r8 : arguments
|
||||
// %r9 : argumentsFootprint
|
||||
// 48(%rbp) : frameSize
|
||||
// 56(%rbp) : returnType (ignored)
|
||||
|
||||
// allocate stack space, adding room for callee-saved registers
|
||||
movl 48(%rbp),%eax
|
||||
subq %rax,%rsp
|
||||
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp
|
||||
|
||||
// save callee-saved registers
|
||||
movq %rsp,%r11
|
||||
addq %rax,%r11
|
||||
|
||||
movq %rbx,0(%r11)
|
||||
movq %r12,8(%r11)
|
||||
movq %r13,16(%r11)
|
||||
movq %r14,24(%r11)
|
||||
movq %r15,32(%r11)
|
||||
movq %rsi,40(%r11)
|
||||
movq %rdi,48(%r11)
|
||||
|
||||
// we use rbx to hold the thread pointer, by convention
|
||||
mov %rcx,%rbx
|
||||
|
||||
// copy arguments into place
|
||||
movq $0,%r11
|
||||
jmp LOCAL(vmInvoke_argumentTest)
|
||||
|
||||
LOCAL(vmInvoke_argumentLoop):
|
||||
movq (%r8,%r11,1),%rsi
|
||||
movq %rsi,(%rsp,%r11,1)
|
||||
addq $8,%r11
|
||||
|
||||
LOCAL(vmInvoke_argumentTest):
|
||||
cmpq %r9,%r11
|
||||
jb LOCAL(vmInvoke_argumentLoop)
|
||||
|
||||
// call function
|
||||
call *%rdx
|
||||
|
||||
.globl GLOBAL(vmInvoke_returnAddress)
|
||||
GLOBAL(vmInvoke_returnAddress):
|
||||
// restore stack pointer
|
||||
movq %rbp,%rsp
|
||||
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
# include "continuations-x86.S"
|
||||
#endif // AVIAN_CONTINUATIONS
|
||||
|
||||
// restore callee-saved registers (below the stack pointer, but in
|
||||
// the red zone)
|
||||
movq %rsp,%r11
|
||||
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%r11
|
||||
|
||||
movq 0(%r11),%rbx
|
||||
movq 8(%r11),%r12
|
||||
movq 16(%r11),%r13
|
||||
movq 24(%r11),%r14
|
||||
movq 32(%r11),%r15
|
||||
movq 40(%r11),%rsi
|
||||
movq 48(%r11),%rdi
|
||||
|
||||
// return
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.globl GLOBAL(vmJumpAndInvoke)
|
||||
GLOBAL(vmJumpAndInvoke):
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
// %rcx: thread
|
||||
// %rdx: address
|
||||
// %r8 : base
|
||||
// %r9 : (unused)
|
||||
// 8(%rsp): argumentFootprint
|
||||
// 16(%rsp): arguments
|
||||
// 24(%rsp): frameSize
|
||||
|
||||
movq %r8,%rbp
|
||||
|
||||
// restore (pseudo)-stack pointer (we don't want to touch the real
|
||||
// stack pointer, since we haven't copied the arguments yet)
|
||||
movq %rbp,%r9
|
||||
|
||||
// allocate new frame, adding room for callee-saved registers
|
||||
movl 24(%rsp),%eax
|
||||
subq %rax,%r9
|
||||
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%r9
|
||||
|
||||
movq %rcx,%rbx
|
||||
|
||||
// set return address
|
||||
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
|
||||
movq %r10,(%r9)
|
||||
|
||||
// copy arguments into place
|
||||
movq $0,%r11
|
||||
movq 16(%rsp),%r8
|
||||
movq 8(%rsp),%rax
|
||||
jmp LOCAL(vmJumpAndInvoke_argumentTest)
|
||||
|
||||
LOCAL(vmJumpAndInvoke_argumentLoop):
|
||||
movq (%r8,%r11,1),%r10
|
||||
movq %r10,8(%r9,%r11,1)
|
||||
addq $8,%r11
|
||||
|
||||
LOCAL(vmJumpAndInvoke_argumentTest):
|
||||
cmpq %rax,%r11
|
||||
jb LOCAL(vmJumpAndInvoke_argumentLoop)
|
||||
|
||||
// the arguments have been copied, so we can set the real stack
|
||||
// pointer now
|
||||
movq %r9,%rsp
|
||||
|
||||
jmp *%rdx
|
||||
#else // not AVIAN_CONTINUATIONS
|
||||
// vmJumpAndInvoke should only be called when continuations are
|
||||
// enabled
|
||||
int3
|
||||
#endif // not AVIAN_CONTINUATIONS
|
||||
|
||||
#else // not __MINGW32__
|
||||
|
||||
#define CALLEE_SAVED_REGISTER_FOOTPRINT 48
|
||||
|
||||
@ -88,65 +209,7 @@ GLOBAL(vmInvoke_returnAddress):
|
||||
movq %rbp,%rsp
|
||||
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
// call the next continuation, if any
|
||||
movq THREAD_CONTINUATION(%rbx),%rcx
|
||||
cmpq $0,%rcx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
// allocate a frame of size (continuation.length * BYTES_PER_WORD)
|
||||
// + CALLEE_SAVED_REGISTER_FOOTPRINT
|
||||
movq CONTINUATION_LENGTH(%rcx),%rsi
|
||||
shlq $3,%rsi
|
||||
subq %rsi,%rsp
|
||||
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp
|
||||
|
||||
// copy the continuation body into the frame
|
||||
leaq CONTINUATION_BODY(%rcx),%rdi
|
||||
|
||||
movq $0,%r9
|
||||
jmp LOCAL(vmInvoke_continuationTest)
|
||||
|
||||
LOCAL(vmInvoke_continuationLoop):
|
||||
movq (%rdi,%r9,1),%r8
|
||||
movq %r8,(%rsp,%r9,1)
|
||||
addq $8,%r9
|
||||
|
||||
LOCAL(vmInvoke_continuationTest):
|
||||
cmpq %rsi,%r9
|
||||
jb LOCAL(vmInvoke_continuationLoop)
|
||||
|
||||
// set the return address to vmInvoke_returnAddress
|
||||
movq CONTINUATION_RETURN_ADDRESS_OFFSET(%rcx),%rdi
|
||||
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
|
||||
movq %r10,(%rsp,%rdi,1)
|
||||
|
||||
// save the current base pointer in the frame and update it
|
||||
movq CONTINUATION_FRAME_POINTER_OFFSET(%rcx),%rdi
|
||||
movq %rbp,(%rsp,%rdi,1)
|
||||
addq %rsp,%rdi
|
||||
movq %rdi,%rbp
|
||||
|
||||
// consume the continuation
|
||||
movq CONTINUATION_NEXT(%rcx),%rdi
|
||||
movq %rdi,THREAD_CONTINUATION(%rbx)
|
||||
|
||||
// call the continuation unless we're handling an exception
|
||||
movq THREAD_EXCEPTION(%rbx),%rsi
|
||||
cmpq $0,%rsi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
jmp *CONTINUATION_ADDRESS(%rcx)
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movq $0,THREAD_EXCEPTION(%rbx)
|
||||
movq THREAD_EXCEPTION_STACK_ADJUSTMENT(%rbx),%rdi
|
||||
subq %rdi,%rsp
|
||||
movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi
|
||||
movq %rsi,(%rsp,%rdi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%rbx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
# include "continuations-x86.S"
|
||||
#endif // AVIAN_CONTINUATIONS
|
||||
|
||||
// restore callee-saved registers (below the stack pointer, but in
|
||||
@ -216,21 +279,10 @@ LOCAL(vmJumpAndInvoke_argumentTest):
|
||||
int3
|
||||
#endif // not AVIAN_CONTINUATIONS
|
||||
|
||||
#endif // not __MINGW32__
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
#define THREAD_CONTINUATION 96
|
||||
#define THREAD_EXCEPTION 36
|
||||
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 100
|
||||
#define THREAD_EXCEPTION_OFFSET 104
|
||||
#define THREAD_EXCEPTION_HANDLER 108
|
||||
|
||||
#define CONTINUATION_NEXT 4
|
||||
#define CONTINUATION_ADDRESS 16
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20
|
||||
#define CONTINUATION_FRAME_POINTER_OFFSET 24
|
||||
#define CONTINUATION_LENGTH 28
|
||||
#define CONTINUATION_BODY 32
|
||||
|
||||
#define CALLEE_SAVED_REGISTER_FOOTPRINT 16
|
||||
|
||||
.globl GLOBAL(vmInvoke)
|
||||
@ -286,72 +338,7 @@ vmInvoke_returnAddress:
|
||||
movl %ecx,%esp
|
||||
|
||||
#ifdef AVIAN_CONTINUATIONS
|
||||
// call the next continuation, if any
|
||||
movl THREAD_CONTINUATION(%ebx),%ecx
|
||||
cmpl $0,%ecx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
// allocate a frame of size (continuation.length * BYTES_PER_WORD)
|
||||
movl CONTINUATION_LENGTH(%ecx),%esi
|
||||
shll $2,%esi
|
||||
subl %esi,%esp
|
||||
|
||||
// copy the continuation body into the frame
|
||||
leal CONTINUATION_BODY(%ecx),%edi
|
||||
|
||||
push %eax
|
||||
push %edx
|
||||
|
||||
movl $0,%edx
|
||||
jmp LOCAL(vmInvoke_continuationTest)
|
||||
|
||||
LOCAL(vmInvoke_continuationLoop):
|
||||
movl (%edi,%edx,1),%eax
|
||||
movl %eax,8(%esp,%edx,1)
|
||||
addl $4,%edx
|
||||
|
||||
LOCAL(vmInvoke_continuationTest):
|
||||
cmpl %esi,%edx
|
||||
jb LOCAL(vmInvoke_continuationLoop)
|
||||
|
||||
pop %edx
|
||||
pop %eax
|
||||
|
||||
// set the return address to vmInvoke_returnAddress
|
||||
movl CONTINUATION_RETURN_ADDRESS_OFFSET(%ecx),%edi
|
||||
call LOCAL(getPC)
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%esi
|
||||
movl vmInvoke_returnAddress@GOT(%esi),%esi
|
||||
movl %esi,(%esp,%edi,1)
|
||||
|
||||
// save the current base pointer in the frame and update it
|
||||
movl CONTINUATION_FRAME_POINTER_OFFSET(%ecx),%edi
|
||||
movl %ebp,(%esp,%edi,1)
|
||||
addl %esp,%edi
|
||||
movl %edi,%ebp
|
||||
|
||||
// consume the continuation
|
||||
movl CONTINUATION_NEXT(%ecx),%edi
|
||||
movl %edi,THREAD_CONTINUATION(%ebx)
|
||||
|
||||
// call the continuation unless we're handling an exception
|
||||
movl THREAD_EXCEPTION(%ebx),%esi
|
||||
cmpl $0,%esi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
|
||||
jmp *CONTINUATION_ADDRESS(%ecx)
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movl $0,THREAD_EXCEPTION(%ebx)
|
||||
movl THREAD_EXCEPTION_STACK_ADJUSTMENT(%ebx),%edi
|
||||
subl %edi,%esp
|
||||
movl THREAD_EXCEPTION_OFFSET(%ebx),%edi
|
||||
movl %esi,(%esp,%edi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%ebx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
# include "continuations-x86.S"
|
||||
#endif // AVIAN_CONTINUATIONS
|
||||
|
||||
// restore callee-saved registers
|
||||
@ -443,5 +430,5 @@ LOCAL(vmJumpAndInvoke_argumentTest):
|
||||
#endif // AVIAN_CONTINUATIONS
|
||||
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
#error unsupported architecture
|
||||
#endif //def __x86_64__
|
||||
|
161
src/continuations-x86.S
Normal file
161
src/continuations-x86.S
Normal file
@ -0,0 +1,161 @@
|
||||
#ifdef __x86_64__
|
||||
|
||||
#define THREAD_CONTINUATION 168
|
||||
#define THREAD_EXCEPTION 64
|
||||
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 176
|
||||
#define THREAD_EXCEPTION_OFFSET 184
|
||||
#define THREAD_EXCEPTION_HANDLER 192
|
||||
|
||||
#define CONTINUATION_NEXT 8
|
||||
#define CONTINUATION_ADDRESS 32
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 40
|
||||
#define CONTINUATION_FRAME_POINTER_OFFSET 48
|
||||
#define CONTINUATION_LENGTH 56
|
||||
#define CONTINUATION_BODY 64
|
||||
|
||||
// call the next continuation, if any
|
||||
movq THREAD_CONTINUATION(%rbx),%rcx
|
||||
cmpq $0,%rcx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
// allocate a frame of size (continuation.length * BYTES_PER_WORD)
|
||||
// + CALLEE_SAVED_REGISTER_FOOTPRINT
|
||||
movq CONTINUATION_LENGTH(%rcx),%rsi
|
||||
shlq $3,%rsi
|
||||
subq %rsi,%rsp
|
||||
subq $CALLEE_SAVED_REGISTER_FOOTPRINT,%rsp
|
||||
|
||||
// copy the continuation body into the frame
|
||||
leaq CONTINUATION_BODY(%rcx),%rdi
|
||||
|
||||
movq $0,%r9
|
||||
jmp LOCAL(vmInvoke_continuationTest)
|
||||
|
||||
LOCAL(vmInvoke_continuationLoop):
|
||||
movq (%rdi,%r9,1),%r8
|
||||
movq %r8,(%rsp,%r9,1)
|
||||
addq $8,%r9
|
||||
|
||||
LOCAL(vmInvoke_continuationTest):
|
||||
cmpq %rsi,%r9
|
||||
jb LOCAL(vmInvoke_continuationLoop)
|
||||
|
||||
// set the return address to vmInvoke_returnAddress
|
||||
movq CONTINUATION_RETURN_ADDRESS_OFFSET(%rcx),%rdi
|
||||
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
|
||||
movq %r10,(%rsp,%rdi,1)
|
||||
|
||||
// save the current base pointer in the frame and update it
|
||||
movq CONTINUATION_FRAME_POINTER_OFFSET(%rcx),%rdi
|
||||
movq %rbp,(%rsp,%rdi,1)
|
||||
addq %rsp,%rdi
|
||||
movq %rdi,%rbp
|
||||
|
||||
// consume the continuation
|
||||
movq CONTINUATION_NEXT(%rcx),%rdi
|
||||
movq %rdi,THREAD_CONTINUATION(%rbx)
|
||||
|
||||
// call the continuation unless we're handling an exception
|
||||
movq THREAD_EXCEPTION(%rbx),%rsi
|
||||
cmpq $0,%rsi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
jmp *CONTINUATION_ADDRESS(%rcx)
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movq $0,THREAD_EXCEPTION(%rbx)
|
||||
movq THREAD_EXCEPTION_STACK_ADJUSTMENT(%rbx),%rdi
|
||||
subq %rdi,%rsp
|
||||
movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi
|
||||
movq %rsi,(%rsp,%rdi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%rbx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
#define THREAD_CONTINUATION 96
|
||||
#define THREAD_EXCEPTION 36
|
||||
#define THREAD_EXCEPTION_STACK_ADJUSTMENT 100
|
||||
#define THREAD_EXCEPTION_OFFSET 104
|
||||
#define THREAD_EXCEPTION_HANDLER 108
|
||||
|
||||
#define CONTINUATION_NEXT 4
|
||||
#define CONTINUATION_ADDRESS 16
|
||||
#define CONTINUATION_RETURN_ADDRESS_OFFSET 20
|
||||
#define CONTINUATION_FRAME_POINTER_OFFSET 24
|
||||
#define CONTINUATION_LENGTH 28
|
||||
#define CONTINUATION_BODY 32
|
||||
|
||||
// call the next continuation, if any
|
||||
movl THREAD_CONTINUATION(%ebx),%ecx
|
||||
cmpl $0,%ecx
|
||||
je LOCAL(vmInvoke_exit)
|
||||
|
||||
// allocate a frame of size (continuation.length * BYTES_PER_WORD)
|
||||
movl CONTINUATION_LENGTH(%ecx),%esi
|
||||
shll $2,%esi
|
||||
subl %esi,%esp
|
||||
|
||||
// copy the continuation body into the frame
|
||||
leal CONTINUATION_BODY(%ecx),%edi
|
||||
|
||||
push %eax
|
||||
push %edx
|
||||
|
||||
movl $0,%edx
|
||||
jmp LOCAL(vmInvoke_continuationTest)
|
||||
|
||||
LOCAL(vmInvoke_continuationLoop):
|
||||
movl (%edi,%edx,1),%eax
|
||||
movl %eax,8(%esp,%edx,1)
|
||||
addl $4,%edx
|
||||
|
||||
LOCAL(vmInvoke_continuationTest):
|
||||
cmpl %esi,%edx
|
||||
jb LOCAL(vmInvoke_continuationLoop)
|
||||
|
||||
pop %edx
|
||||
pop %eax
|
||||
|
||||
// set the return address to vmInvoke_returnAddress
|
||||
movl CONTINUATION_RETURN_ADDRESS_OFFSET(%ecx),%edi
|
||||
call LOCAL(getPC)
|
||||
addl $_GLOBAL_OFFSET_TABLE_,%esi
|
||||
movl vmInvoke_returnAddress@GOT(%esi),%esi
|
||||
movl %esi,(%esp,%edi,1)
|
||||
|
||||
// save the current base pointer in the frame and update it
|
||||
movl CONTINUATION_FRAME_POINTER_OFFSET(%ecx),%edi
|
||||
movl %ebp,(%esp,%edi,1)
|
||||
addl %esp,%edi
|
||||
movl %edi,%ebp
|
||||
|
||||
// consume the continuation
|
||||
movl CONTINUATION_NEXT(%ecx),%edi
|
||||
movl %edi,THREAD_CONTINUATION(%ebx)
|
||||
|
||||
// call the continuation unless we're handling an exception
|
||||
movl THREAD_EXCEPTION(%ebx),%esi
|
||||
cmpl $0,%esi
|
||||
jne LOCAL(vmInvoke_handleException)
|
||||
|
||||
jmp *CONTINUATION_ADDRESS(%ecx)
|
||||
|
||||
LOCAL(vmInvoke_handleException):
|
||||
// we're handling an exception - call the exception handler instead
|
||||
movl $0,THREAD_EXCEPTION(%ebx)
|
||||
movl THREAD_EXCEPTION_STACK_ADJUSTMENT(%ebx),%edi
|
||||
subl %edi,%esp
|
||||
movl THREAD_EXCEPTION_OFFSET(%ebx),%edi
|
||||
movl %esi,(%esp,%edi,1)
|
||||
|
||||
jmp *THREAD_EXCEPTION_HANDLER(%ebx)
|
||||
|
||||
LOCAL(vmInvoke_exit):
|
||||
|
||||
#else
|
||||
# error unsupported architecture
|
||||
#endif
|
||||
|
@ -62,8 +62,10 @@ AttachCurrentThread(Machine* m, Thread** t, void*)
|
||||
*t = static_cast<Thread*>(m->localThread->get());
|
||||
if (*t == 0) {
|
||||
*t = m->processor->makeThread(m, 0, m->rootThread);
|
||||
m->system->attach(&((*t)->runnable));
|
||||
|
||||
enter(*t, Thread::ActiveState);
|
||||
enter(*t, Thread::IdleState);
|
||||
|
||||
m->localThread->set(*t);
|
||||
}
|
||||
|
@ -3292,3 +3292,29 @@ vmPrintTrace(Thread* t)
|
||||
|
||||
t->m->processor->walkStack(t, &v);
|
||||
}
|
||||
|
||||
// also for debugging
|
||||
void*
|
||||
vmAddressFromLine(Thread* t, object m, unsigned line)
|
||||
{
|
||||
object code = methodCode(t, m);
|
||||
printf("code: %p\n", code);
|
||||
object lnt = codeLineNumberTable(t, code);
|
||||
printf("lnt: %p\n", lnt);
|
||||
|
||||
if (lnt) {
|
||||
unsigned last = 0;
|
||||
unsigned bottom = 0;
|
||||
unsigned top = lineNumberTableLength(t, lnt);
|
||||
for(unsigned i = bottom; i < top; i++)
|
||||
{
|
||||
LineNumber* ln = lineNumberTableBody(t, lnt, i);
|
||||
if(lineNumberLine(ln) == line)
|
||||
return reinterpret_cast<void*>(lineNumberIp(ln));
|
||||
else if(lineNumberLine(ln) > line)
|
||||
return reinterpret_cast<void*>(last);
|
||||
last = lineNumberIp(ln);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2448,4 +2448,7 @@ dumpHeap(Thread* t, FILE* out);
|
||||
void
|
||||
vmPrintTrace(vm::Thread* t);
|
||||
|
||||
void*
|
||||
vmAddressFromLine(vm::Thread* t, vm::object m, unsigned line);
|
||||
|
||||
#endif//MACHINE_H
|
||||
|
@ -55,7 +55,7 @@ run(void* r)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool Verbose = false;
|
||||
const bool Verbose = true;
|
||||
|
||||
const unsigned Waiting = 1 << 0;
|
||||
const unsigned Notified = 1 << 1;
|
||||
@ -574,11 +574,20 @@ class MySystem: public System {
|
||||
if (handler) {
|
||||
segFaultHandler = handler;
|
||||
|
||||
#ifdef __i386__
|
||||
oldSegFaultHandler = SetUnhandledExceptionFilter(handleException);
|
||||
#elif defined __x86_64__
|
||||
AddVectoredExceptionHandler(1, handleException);
|
||||
oldSegFaultHandler = 0;
|
||||
#endif
|
||||
return 0;
|
||||
} else if (segFaultHandler) {
|
||||
segFaultHandler = 0;
|
||||
#ifdef __i386__
|
||||
SetUnhandledExceptionFilter(oldSegFaultHandler);
|
||||
#elif defined __x86_64__
|
||||
//do nothing, handlers are never "unregistered" anyway
|
||||
#endif
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
@ -600,10 +609,15 @@ class MySystem: public System {
|
||||
CONTEXT context;
|
||||
rv = GetThreadContext(target->thread, &context);
|
||||
expect(this, rv);
|
||||
|
||||
#ifdef __i386__
|
||||
visitor->visit(reinterpret_cast<void*>(context.Eip),
|
||||
reinterpret_cast<void*>(context.Ebp),
|
||||
reinterpret_cast<void*>(context.Esp));
|
||||
#elif defined __x86_64__
|
||||
visitor->visit(reinterpret_cast<void*>(context.Rip),
|
||||
reinterpret_cast<void*>(context.Rbp),
|
||||
reinterpret_cast<void*>(context.Rsp));
|
||||
#endif
|
||||
|
||||
rv = ResumeThread(target->thread);
|
||||
expect(this, rv != -1);
|
||||
@ -798,7 +812,7 @@ dump(LPEXCEPTION_POINTERS e, const char* directory)
|
||||
char name[MAX_PATH];
|
||||
_timeb tb;
|
||||
_ftime(&tb);
|
||||
snprintf(name, MAX_PATH, "%s\\crash-%lld.mdmp", directory,
|
||||
snprintf(name, MAX_PATH, "%s\\crash-%"LLD".mdmp", directory,
|
||||
(static_cast<int64_t>(tb.time) * 1000)
|
||||
+ static_cast<int64_t>(tb.millitm));
|
||||
|
||||
@ -830,18 +844,31 @@ LONG CALLBACK
|
||||
handleException(LPEXCEPTION_POINTERS e)
|
||||
{
|
||||
if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||
#ifdef __i386__
|
||||
void* ip = reinterpret_cast<void*>(e->ContextRecord->Eip);
|
||||
void* base = reinterpret_cast<void*>(e->ContextRecord->Ebp);
|
||||
void* stack = reinterpret_cast<void*>(e->ContextRecord->Esp);
|
||||
void* thread = reinterpret_cast<void*>(e->ContextRecord->Ebx);
|
||||
#elif defined __x86_64__
|
||||
void* ip = reinterpret_cast<void*>(e->ContextRecord->Rip);
|
||||
void* base = reinterpret_cast<void*>(e->ContextRecord->Rbp);
|
||||
void* stack = reinterpret_cast<void*>(e->ContextRecord->Rsp);
|
||||
void* thread = reinterpret_cast<void*>(e->ContextRecord->Rbx);
|
||||
#endif
|
||||
|
||||
bool jump = system->segFaultHandler->handleSignal
|
||||
(&ip, &base, &stack, &thread);
|
||||
|
||||
#ifdef __i386__
|
||||
e->ContextRecord->Eip = reinterpret_cast<DWORD>(ip);
|
||||
e->ContextRecord->Ebp = reinterpret_cast<DWORD>(base);
|
||||
e->ContextRecord->Esp = reinterpret_cast<DWORD>(stack);
|
||||
e->ContextRecord->Ebx = reinterpret_cast<DWORD>(thread);
|
||||
#elif defined __x86_64__
|
||||
e->ContextRecord->Rip = reinterpret_cast<DWORD64>(ip);
|
||||
e->ContextRecord->Rbp = reinterpret_cast<DWORD64>(base);
|
||||
e->ContextRecord->Rsp = reinterpret_cast<DWORD64>(stack);
|
||||
e->ContextRecord->Rbx = reinterpret_cast<DWORD64>(thread);
|
||||
#endif
|
||||
|
||||
if (jump) {
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
|
161
src/x86.S
161
src/x86.S
@ -8,16 +8,145 @@
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define LOCAL(x) .L##x
|
||||
|
||||
#if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
|
||||
# define GLOBAL(x) _##x
|
||||
#else
|
||||
# define GLOBAL(x) x
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
.globl vmNativeCall
|
||||
vmNativeCall:
|
||||
#ifdef __MINGW32__
|
||||
|
||||
.globl GLOBAL(vmNativeCall)
|
||||
GLOBAL(vmNativeCall):
|
||||
pushq %rbp
|
||||
//save nonvolatile registers
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
movq %rsp, %rbp
|
||||
|
||||
|
||||
// %rcx: function
|
||||
// %rdx: arguments
|
||||
// %r8: arguments count
|
||||
// %r9: return type
|
||||
|
||||
movq %rcx, %r10
|
||||
movq %rdx, %r11
|
||||
movq %r8, %r12
|
||||
movq %r9, %r13
|
||||
|
||||
// %r10: function
|
||||
// %r11: arguments
|
||||
// %r12: arguments count
|
||||
// %r13: return type
|
||||
|
||||
//allocate initial stack space
|
||||
subq $32, %rsp
|
||||
|
||||
//first arg
|
||||
cmp $0, %r12
|
||||
je LOCAL(call)
|
||||
movq 0(%r11),%rcx
|
||||
movq 0(%r11),%xmm0
|
||||
subq $1, %r12
|
||||
|
||||
//second arg
|
||||
cmp $0, %r12
|
||||
je LOCAL(call)
|
||||
movq 8(%r11),%rdx
|
||||
movq 8(%r11),%xmm1
|
||||
subq $1, %r12
|
||||
|
||||
//third arg
|
||||
cmp $0, %r12
|
||||
je LOCAL(call)
|
||||
movq 16(%r11),%r8
|
||||
movq 16(%r11),%xmm2
|
||||
subq $1, %r12
|
||||
|
||||
//fourth arg
|
||||
cmp $0, %r12
|
||||
je LOCAL(call)
|
||||
movq 24(%r11),%r9
|
||||
movq 24(%r11),%xmm3
|
||||
subq $1, %r12
|
||||
|
||||
|
||||
//calculate stack space for arguments, aligned
|
||||
movq $8, %r15
|
||||
leaq (%r15, %r12, 8), %r15
|
||||
andq $0xFFFFFFFFFFFFFFF0, %r15
|
||||
|
||||
//reserve stack space for arguments
|
||||
subq %r15, %rsp
|
||||
|
||||
//reset the counter
|
||||
addq $3, %r12
|
||||
jmp LOCAL(loopend)
|
||||
|
||||
LOCAL(loop):
|
||||
movq (%r11, %r12, 8), %r14
|
||||
movq %r14, (%rsp, %r12, 8);
|
||||
subq $1, %r12
|
||||
|
||||
LOCAL(loopend):
|
||||
//we don't need to move arg 3 and lower
|
||||
cmpq $3, %r12
|
||||
jne LOCAL(loop)
|
||||
|
||||
LOCAL(call):
|
||||
call *%r10
|
||||
|
||||
LOCAL(void):
|
||||
cmpq $VOID_TYPE,%r13
|
||||
jne LOCAL(float)
|
||||
jmp LOCAL(exit)
|
||||
|
||||
LOCAL(float):
|
||||
cmpq $FLOAT_TYPE,%r13
|
||||
je LOCAL(copy)
|
||||
cmpq $DOUBLE_TYPE,%r13
|
||||
jne LOCAL(exit)
|
||||
|
||||
LOCAL(copy):
|
||||
movq %xmm0,%rax
|
||||
|
||||
LOCAL(exit):
|
||||
|
||||
movq %rbp, %rsp
|
||||
//return nonvolatile registers to their former state
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.globl GLOBAL(vmJump)
|
||||
GLOBAL(vmJump):
|
||||
movq 8(%rsp),%rax
|
||||
movq 16(%rsp),%rdx
|
||||
movq %rdx,%rbp
|
||||
movq %r8,%rsp
|
||||
movq %r9,%rbx
|
||||
jmp *%rcx
|
||||
|
||||
#else // not __MINGW32__
|
||||
|
||||
.globl GLOBAL(vmNativeCall)
|
||||
GLOBAL(vmNativeCall):
|
||||
pushq %rbp
|
||||
movq %rsp,%rbp
|
||||
|
||||
@ -113,8 +242,8 @@ LOCAL(exit):
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
.globl GLOBAL(vmJump)
|
||||
GLOBAL(vmJump):
|
||||
movq %rsi,%rbp
|
||||
movq %rdx,%rsp
|
||||
movq %rcx,%rbx
|
||||
@ -122,15 +251,12 @@ vmJump:
|
||||
movq %r9,%rdx
|
||||
jmp *%rdi
|
||||
|
||||
#endif // not __MINGW32__
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
# if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
|
||||
.globl _vmNativeCall
|
||||
_vmNativeCall:
|
||||
# else
|
||||
.globl vmNativeCall
|
||||
vmNativeCall:
|
||||
# endif
|
||||
.globl GLOBAL(vmNativeCall)
|
||||
GLOBAL(vmNativeCall):
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
@ -201,13 +327,8 @@ LOCAL(exit):
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
# if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
|
||||
.globl _vmJump
|
||||
_vmJump:
|
||||
# else
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
# endif
|
||||
.globl GLOBAL(vmJump)
|
||||
GLOBAL(vmJump):
|
||||
movl 4(%esp),%esi
|
||||
movl 8(%esp),%ebp
|
||||
movl 16(%esp),%ebx
|
||||
@ -216,6 +337,4 @@ vmJump:
|
||||
movl 12(%esp),%esp
|
||||
jmp *%esi
|
||||
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
||||
#endif //def __x86_64__
|
||||
|
677
src/x86.cpp
677
src/x86.cpp
File diff suppressed because it is too large
Load Diff
14
src/x86.h
14
src/x86.h
@ -58,11 +58,24 @@ dynamicCall(void* function, uintptr_t* arguments, uint8_t*,
|
||||
# define THREAD_REGISTER(context) (context->uc_mcontext.gregs[REG_RBX])
|
||||
|
||||
extern "C" uint64_t
|
||||
# ifdef __MINGW32__
|
||||
vmNativeCall(void* function, void* stack, unsigned stackSize,
|
||||
unsigned returnType);
|
||||
# else
|
||||
vmNativeCall(void* function, void* stack, unsigned stackSize,
|
||||
void* gprTable, void* sseTable, unsigned returnType);
|
||||
# endif
|
||||
|
||||
namespace vm {
|
||||
|
||||
# ifdef __MINGW32__
|
||||
inline uint64_t
|
||||
dynamicCall(void* function, uint64_t* arguments, UNUSED uint8_t* argumentTypes,
|
||||
unsigned argumentCount, unsigned, unsigned returnType)
|
||||
{
|
||||
return vmNativeCall(function, arguments, argumentCount, returnType);
|
||||
}
|
||||
# else
|
||||
inline uint64_t
|
||||
dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes,
|
||||
unsigned argumentCount, unsigned, unsigned returnType)
|
||||
@ -103,6 +116,7 @@ dynamicCall(void* function, uint64_t* arguments, uint8_t* argumentTypes,
|
||||
(gprIndex ? gprTable : 0),
|
||||
(sseIndex ? sseTable : 0), returnType);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace vm
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user