mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
ensure stack alignment in compile-x86.S and update vmInvoke to accept frame size parameter
This commit is contained in:
parent
17b4c20435
commit
c88e3fa230
@ -14,8 +14,7 @@
|
||||
|
||||
#define BYTES_PER_WORD 4
|
||||
#define LINKAGE_AREA 6
|
||||
#define GPR_COUNT 8
|
||||
#define MEMORY_BASE BYTES_PER_WORD * (LINKAGE_AREA + GPR_COUNT)
|
||||
#define ARGUMENT_BASE BYTES_PER_WORD * LINKAGE_AREA
|
||||
|
||||
#define LOCAL(x) L##x
|
||||
|
||||
@ -32,13 +31,16 @@ vmInvoke:
|
||||
|
||||
// r3: thread
|
||||
// r4: function
|
||||
// r5: parameters
|
||||
// r6: parameterCount
|
||||
// r5: arguments
|
||||
// r6: argumentFootprint
|
||||
// r7: frameSize
|
||||
// r8: returnType (ignored)
|
||||
// r8: returnType
|
||||
|
||||
// r9: temporary
|
||||
|
||||
// save return type
|
||||
stw r8,44(r1)
|
||||
|
||||
// allocate stack space, adding room for callee-saved registers
|
||||
addi r9,r7,80
|
||||
stwux r1,r1,r9
|
||||
@ -75,7 +77,7 @@ vmInvoke:
|
||||
|
||||
LOCAL(loop):
|
||||
lwzx r17,r16,r5
|
||||
addi r18,r16,MEMORY_BASE
|
||||
addi r18,r16,ARGUMENT_BASE
|
||||
stwx r17,r18,r1
|
||||
addi r16,r16,BYTES_PER_WORD
|
||||
|
||||
@ -113,6 +115,24 @@ LOCAL(test):
|
||||
lwz r30,68(r9)
|
||||
lwz r31,72(r9)
|
||||
|
||||
// handle return value based on expected type
|
||||
lwz r8,44(r1)
|
||||
|
||||
LOCAL(void):
|
||||
cmplw VOID_TYPE,r8
|
||||
bne LOCAL(int64)
|
||||
b LOCAL(exit)
|
||||
|
||||
LOCAL(int64):
|
||||
cmplw INT64_TYPE,r8
|
||||
bne LOCAL(int32)
|
||||
b LOCAL(exit)
|
||||
|
||||
LOCAL(int32):
|
||||
mr r3,r4
|
||||
li r3,0
|
||||
|
||||
LOCAL(exit):
|
||||
// load return address
|
||||
lwz r0,8(r1)
|
||||
mtlr r0
|
||||
|
@ -20,31 +20,39 @@
|
||||
vmInvoke:
|
||||
pushq %rbp
|
||||
movq %rsp,%rbp
|
||||
|
||||
// push callee-saved registers
|
||||
pushq %rbx
|
||||
pushq %r12
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
pushq %r15
|
||||
|
||||
// %rdi: thread
|
||||
// %rsi: function
|
||||
// %rdx: stack
|
||||
// %rcx: stackSize
|
||||
// %r8 : returnType
|
||||
// %rdx: arguments
|
||||
// %rcx: argumentFootprint
|
||||
// %r8 : frameSize
|
||||
// %r9 : returnType (ignored)
|
||||
|
||||
// allocate stack space, adding room for callee-saved registers
|
||||
subq %r8,%rsp
|
||||
subq $48,%rsp
|
||||
|
||||
// save callee-saved registers
|
||||
movq %rsp,%r9
|
||||
addq %r8,%r9
|
||||
|
||||
movq %rbx,0(%r9)
|
||||
movq %r12,8(%r9)
|
||||
movq %r13,16(%r9)
|
||||
movq %r14,24(%r9)
|
||||
movq %r15,32(%r9)
|
||||
|
||||
// we use rbx to hold the thread pointer, by convention
|
||||
mov %rdi,%rbx
|
||||
|
||||
// copy arguments into place
|
||||
pushq %rcx
|
||||
movq $0,%r9
|
||||
jmp LOCAL(test)
|
||||
|
||||
LOCAL(loop):
|
||||
push (%rdx,%r9,8)
|
||||
inc %r9
|
||||
movq (%rdx,%r9,1),%r8
|
||||
movq %r8,(%rsp,%r9,1)
|
||||
addq $8,%r9
|
||||
|
||||
LOCAL(test):
|
||||
cmpq %rcx,%r9
|
||||
@ -52,23 +60,21 @@ LOCAL(test):
|
||||
|
||||
// call function
|
||||
call *%rsi
|
||||
|
||||
// pop arguments
|
||||
mov -48(%rbp),%rcx
|
||||
sal $3,%rcx
|
||||
addq %rcx,%rsp
|
||||
|
||||
// pop argument stack size
|
||||
addq $8,%rsp
|
||||
|
||||
// pop callee-saved registers
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %rbx
|
||||
// restore stack pointer
|
||||
movq %rbp,%rsp
|
||||
|
||||
movq %rbp,%rsp
|
||||
// restore callee-saved registers
|
||||
movq %rsp,%r9
|
||||
subq $48,%r9
|
||||
|
||||
movq 0(%r9),%rbx
|
||||
movq 8(%r9),%r12
|
||||
movq 16(%r9),%r13
|
||||
movq 24(%r9),%r14
|
||||
movq 32(%r9),%r15
|
||||
|
||||
// return
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
@ -84,28 +90,37 @@ vmInvoke:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
// ebx, esi and edi are callee-saved registers
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
|
||||
// 8(%ebp): thread
|
||||
// 12(%ebp): function
|
||||
// 16(%ebp): stack
|
||||
// 20(%ebp): stackSize
|
||||
// 24(%ebp): returnType
|
||||
// 16(%ebp): arguments
|
||||
// 20(%ebp): argumentFootprint
|
||||
// 24(%ebp): frameSize
|
||||
// 28(%ebp): returnType
|
||||
|
||||
// allocate stack space, adding room for callee-saved registers
|
||||
subl 24(%ebp),%esp
|
||||
subl $16,%esp
|
||||
|
||||
// save callee-saved registers
|
||||
movl %esp,%ecx
|
||||
addl 24(%ebp),%ecx
|
||||
|
||||
movl %ebx,0(%ecx)
|
||||
movl %esi,4(%ecx)
|
||||
movl %edi,8(%ecx)
|
||||
|
||||
// we use ebx to hold the thread pointer, by convention
|
||||
mov 8(%ebp),%ebx
|
||||
|
||||
// copy arguments into place
|
||||
movl $0,%ecx
|
||||
mov 16(%ebp),%edx
|
||||
movl 16(%ebp),%edx
|
||||
jmp LOCAL(test)
|
||||
|
||||
LOCAL(loop):
|
||||
push (%edx,%ecx,4)
|
||||
inc %ecx
|
||||
movl (%edx,%ecx,1),%eax
|
||||
movl %eax,(%esp,%ecx,1)
|
||||
addl $4,%ecx
|
||||
|
||||
LOCAL(test):
|
||||
cmpl 20(%ebp),%ecx
|
||||
@ -113,14 +128,20 @@ LOCAL(test):
|
||||
|
||||
// call function
|
||||
call *12(%ebp)
|
||||
|
||||
// restore stack pointer
|
||||
movl %ebp,%esp
|
||||
|
||||
// restore callee-saved registers
|
||||
movl %esp,%ecx
|
||||
subl $16,%ecx
|
||||
|
||||
// pop arguments
|
||||
mov 20(%ebp),%ecx
|
||||
sal $2,%ecx
|
||||
addl %ecx,%esp
|
||||
movl 0(%ecx),%ebx
|
||||
movl 4(%ecx),%esi
|
||||
movl 8(%ecx),%edi
|
||||
|
||||
// handle return value based on expected type
|
||||
movl 24(%ebp),%ecx
|
||||
movl 28(%ebp),%ecx
|
||||
|
||||
LOCAL(void):
|
||||
cmpl $VOID_TYPE,%ecx
|
||||
@ -136,10 +157,6 @@ LOCAL(int32):
|
||||
movl $0,%edx
|
||||
|
||||
LOCAL(exit):
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
|
@ -19,15 +19,15 @@
|
||||
using namespace vm;
|
||||
|
||||
extern "C" uint64_t
|
||||
vmInvoke(void* thread, void* function, void* stack, unsigned stackSize,
|
||||
unsigned returnType);
|
||||
vmInvoke(void* thread, void* function, void* arguments,
|
||||
unsigned argumentFootprint, unsigned frameSize, unsigned returnType);
|
||||
|
||||
extern "C" void
|
||||
vmCall();
|
||||
|
||||
namespace {
|
||||
|
||||
const bool DebugCompile = true;
|
||||
const bool DebugCompile = false;
|
||||
const bool DebugNatives = false;
|
||||
const bool DebugCallTable = false;
|
||||
const bool DebugMethodTree = false;
|
||||
@ -4649,12 +4649,14 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
||||
|
||||
class ArgumentList {
|
||||
public:
|
||||
ArgumentList(Thread* t, uintptr_t* array, bool* objectMask, object this_,
|
||||
const char* spec, bool indirectObjects, va_list arguments):
|
||||
ArgumentList(Thread* t, uintptr_t* array, unsigned size, bool* objectMask,
|
||||
object this_, const char* spec, bool indirectObjects,
|
||||
va_list arguments):
|
||||
t(static_cast<MyThread*>(t)),
|
||||
array(array),
|
||||
objectMask(objectMask),
|
||||
position(0),
|
||||
size(size),
|
||||
position(size),
|
||||
protector(this)
|
||||
{
|
||||
if (this_) {
|
||||
@ -4685,12 +4687,13 @@ class ArgumentList {
|
||||
}
|
||||
}
|
||||
|
||||
ArgumentList(Thread* t, uintptr_t* array, bool* objectMask, object this_,
|
||||
const char* spec, object arguments):
|
||||
ArgumentList(Thread* t, uintptr_t* array, unsigned size, bool* objectMask,
|
||||
object this_, const char* spec, object arguments):
|
||||
t(static_cast<MyThread*>(t)),
|
||||
array(array),
|
||||
objectMask(objectMask),
|
||||
position(0),
|
||||
size(size),
|
||||
position(size),
|
||||
protector(this)
|
||||
{
|
||||
if (this_) {
|
||||
@ -4720,34 +4723,41 @@ class ArgumentList {
|
||||
}
|
||||
|
||||
void addObject(object v) {
|
||||
assert(t, position);
|
||||
|
||||
-- position;
|
||||
array[position] = reinterpret_cast<uintptr_t>(v);
|
||||
objectMask[position] = true;
|
||||
++ position;
|
||||
}
|
||||
|
||||
void addInt(uintptr_t v) {
|
||||
assert(t, position);
|
||||
|
||||
-- position;
|
||||
array[position] = v;
|
||||
objectMask[position] = false;
|
||||
++ position;
|
||||
}
|
||||
|
||||
void addLong(uint64_t v) {
|
||||
assert(t, position >= 2);
|
||||
|
||||
position -= 2;
|
||||
|
||||
if (BytesPerWord == 8) {
|
||||
memcpy(array + position + 1, &v, 8);
|
||||
memcpy(array + position, &v, 8);
|
||||
} else {
|
||||
// push words in reverse order, since they will be switched back
|
||||
// when pushed on the stack:
|
||||
array[position] = v >> 32;
|
||||
array[position + 1] = v;
|
||||
array[position] = v;
|
||||
array[position + 1] = v >> 32;
|
||||
}
|
||||
|
||||
objectMask[position] = false;
|
||||
objectMask[position + 1] = false;
|
||||
position += 2;
|
||||
}
|
||||
|
||||
MyThread* t;
|
||||
uintptr_t* array;
|
||||
bool* objectMask;
|
||||
unsigned size;
|
||||
unsigned position;
|
||||
|
||||
class MyProtector: public Thread::Protector {
|
||||
@ -4755,7 +4765,7 @@ class ArgumentList {
|
||||
MyProtector(ArgumentList* list): Protector(list->t), list(list) { }
|
||||
|
||||
virtual void visit(Heap::Visitor* v) {
|
||||
for (unsigned i = 0; i < list->position; ++i) {
|
||||
for (unsigned i = list->position; i < list->size; ++i) {
|
||||
if (list->objectMask[i]) {
|
||||
v->visit(reinterpret_cast<object*>(list->array + i));
|
||||
}
|
||||
@ -4782,9 +4792,14 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
||||
trace.nativeMethod = method;
|
||||
}
|
||||
|
||||
unsigned count = arguments->size - arguments->position;
|
||||
|
||||
result = vmInvoke
|
||||
(t, reinterpret_cast<void*>(methodAddress(t, method)),
|
||||
arguments->array, arguments->position, returnType);
|
||||
arguments->array + arguments->position,
|
||||
count * BytesPerWord,
|
||||
t->arch->alignFrameSize(count) * BytesPerWord,
|
||||
returnType);
|
||||
}
|
||||
|
||||
if (t->exception) {
|
||||
@ -5076,7 +5091,7 @@ class MyProcessor: public Processor {
|
||||
unsigned size = methodParameterFootprint(t, method);
|
||||
uintptr_t array[size];
|
||||
bool objectMask[size];
|
||||
ArgumentList list(t, array, objectMask, this_, spec, arguments);
|
||||
ArgumentList list(t, array, size, objectMask, this_, spec, arguments);
|
||||
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -5107,7 +5122,7 @@ class MyProcessor: public Processor {
|
||||
uintptr_t array[size];
|
||||
bool objectMask[size];
|
||||
ArgumentList list
|
||||
(t, array, objectMask, this_, spec, indirectObjects, arguments);
|
||||
(t, array, size, objectMask, this_, spec, indirectObjects, arguments);
|
||||
|
||||
PROTECT(t, method);
|
||||
|
||||
@ -5133,7 +5148,7 @@ class MyProcessor: public Processor {
|
||||
uintptr_t array[size];
|
||||
bool objectMask[size];
|
||||
ArgumentList list
|
||||
(t, array, objectMask, this_, methodSpec, false, arguments);
|
||||
(t, array, size, objectMask, this_, methodSpec, false, arguments);
|
||||
|
||||
object method = resolveMethod(t, className, methodName, methodSpec);
|
||||
if (LIKELY(t->exception == 0)) {
|
||||
|
Loading…
Reference in New Issue
Block a user