ensure stack alignment in compile-x86.S and update vmInvoke to accept frame size parameter

This commit is contained in:
Joel Dice 2009-02-16 19:49:28 -07:00
parent 17b4c20435
commit c88e3fa230
3 changed files with 128 additions and 76 deletions

View File

@ -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

View File

@ -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

View File

@ -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)) {