From c88e3fa23066bc1042235fb1008ea2ee78c588c1 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 16 Feb 2009 19:49:28 -0700 Subject: [PATCH] ensure stack alignment in compile-x86.S and update vmInvoke to accept frame size parameter --- src/compile-powerpc.S | 32 +++++++++--- src/compile-x86.S | 113 ++++++++++++++++++++++++------------------ src/compile.cpp | 59 ++++++++++++++-------- 3 files changed, 128 insertions(+), 76 deletions(-) diff --git a/src/compile-powerpc.S b/src/compile-powerpc.S index c7a1f54512..c4375ead1c 100644 --- a/src/compile-powerpc.S +++ b/src/compile-powerpc.S @@ -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 diff --git a/src/compile-x86.S b/src/compile-x86.S index 73e08b4bd1..1c6e47b771 100644 --- a/src/compile-x86.S +++ b/src/compile-x86.S @@ -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 diff --git a/src/compile.cpp b/src/compile.cpp index 85da676149..0d019378b5 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(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(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(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(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(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)) {