adapt native method call code to new calling convention

This commit is contained in:
Joel Dice 2009-04-25 11:49:56 -06:00
parent de84afe2fe
commit 1ed7c0d94c
4 changed files with 66 additions and 20 deletions

View File

@ -273,10 +273,13 @@ class Assembler {
virtual bool reserved(int register_) = 0;
virtual unsigned frameFootprint(unsigned footprint) = 0;
virtual unsigned argumentFootprint(unsigned footprint) = 0;
virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0;
virtual unsigned stackAlignmentInWords() = 0;
virtual bool matchCall(void* returnAddress, void* target) = 0;
virtual void updateCall(UnaryOperation op, bool assertAlignment,
@ -322,7 +325,6 @@ class Assembler {
virtual Architecture* arch() = 0;
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0;
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) = 0;
virtual void pushFrame(unsigned argumentCount, ...) = 0;
virtual void allocateFrame(unsigned footprint) = 0;
virtual void popFrame() = 0;
@ -331,6 +333,8 @@ class Assembler {
int framePointerSurrogate) = 0;
virtual void popFrameAndPopArgumentsAndReturn(unsigned argumentFootprint)
= 0;
virtual void popFrameAndUpdateStackAndReturn(unsigned stackOffsetFromThread)
= 0;
virtual void apply(Operation op) = 0;

View File

@ -378,7 +378,7 @@ alignedFrameSize(MyThread* t, object method)
(localSize(t, method)
- methodParameterFootprint(t, method)
+ codeMaxStack(t, methodCode(t, method))
+ t->arch->argumentFootprint(MaxNativeCallFootprint));
+ t->arch->frameFootprint(MaxNativeCallFootprint));
}
unsigned
@ -4835,6 +4835,17 @@ invokeNative2(MyThread* t, object method)
default: abort(t);
}
if (t->arch->argumentFootprint(footprint)
> t->arch->stackAlignmentInWords())
{
t->stack = static_cast<uintptr_t*>(t->stack)
+ (t->arch->argumentFootprint(footprint)
- t->arch->stackAlignmentInWords());
}
t->stack = static_cast<uintptr_t*>(t->stack)
- t->arch->frameReturnAddressSize();
} else {
result = 0;
}
@ -6119,9 +6130,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p,
Assembler::Constant proc(&(nativeContext.promise));
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
a->popFrame();
a->apply(Return);
a->popFrameAndUpdateStackAndReturn(difference(&(t->stack), t));
a->endBlock(false)->resolve(0, 0);
}

View File

@ -65,6 +65,7 @@ inline int sth(int rs, int ra, int i) { return D(44, rs, ra, i); }
inline int sthx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 407, 0); }
inline int stw(int rs, int ra, int i) { return D(36, rs, ra, i); }
inline int stwu(int rs, int ra, int i) { return D(37, rs, ra, i); }
inline int stwux(int rs, int ra, int i) { return X(31, rs, ra, rb, 183, 0); }
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
@ -907,9 +908,15 @@ moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src,
{
assert(c, srcSize == BytesPerWord);
assert(c, dstSize == BytesPerWord);
assert(c, dst->index == NoRegister);
issue(c, stwu(src->low, dst->base, dst->offset));
if (dst->index == NoRegister) {
issue(c, stwu(src->low, dst->base, dst->offset));
} else {
assert(c, dst->offset == 0);
assert(c, dst->scale == 1);
issue(c, stwux(src->low, dst->base, dst->index));
}
}
void
@ -2034,6 +2041,26 @@ class MyAssembler: public Assembler {
return_(&c);
}
virtual void popFrameAndUpdateStackAndReturn(unsigned stackOffset) {
popFrame();
Register tmp1(0);
Memory stackSrc(StackRegister, 0);
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp1);
Register tmp2(arch_->returnLow());
Memory newStackSrc(ThreadRegister, stackOffsetFromThread);
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &tmp2);
Register stack(StackRegister);
subR(&c, BytesPerWord, &tmp2, &stack, &tmp2);
Memory stackDst(StackRegister, 0, tmp2.low);
moveAndUpdateRM(&c, BytesPerWord, &tmp1, BytesPerWord, &stackDst);
return_(&c);
}
virtual void apply(Operation op) {
arch_->c.operations[op](&c);
}

View File

@ -2062,7 +2062,7 @@ class MyArchitecture: public Assembler::Architecture {
}
}
virtual unsigned stackPadding(unsigned footprint) {
virtual unsigned frameFootprint(unsigned footprint) {
return max(footprint > argumentRegisterCount() ?
footprint - argumentRegisterCount() : 0,
StackAlignmentInWords);
@ -2097,6 +2097,10 @@ class MyArchitecture: public Assembler::Architecture {
}
}
virtual unsigned stackAlignmentInWords() {
return StackAlignmentInWords;
}
virtual bool matchCall(void* returnAddress, void* target) {
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
int32_t actualOffset; memcpy(&actualOffset, instruction + 1, 4);
@ -2346,18 +2350,6 @@ class MyAssembler: public Assembler {
BytesPerWord, MemoryOperand, &baseDst);
}
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) {
Register stack(rsp);
Memory stackDst(rbx, stackOffset);
apply(Move, BytesPerWord, MemoryOperand, &stackDst,
BytesPerWord, RegisterOperand, &stack);
Register base(rbp);
Memory baseDst(rbx, baseOffset);
apply(Move, BytesPerWord, MemoryOperand, &baseDst,
BytesPerWord, RegisterOperand, &base);
}
virtual void pushFrame(unsigned argumentCount, ...) {
struct {
unsigned size;
@ -2483,6 +2475,20 @@ class MyAssembler: public Assembler {
}
}
virtual void popFrameAndUpdateStackAndReturn(unsigned stackOffsetFromThread)
{
popFrame();
Register returnAddress(rcx);
popR(&c, BytesPerWord, &returnAddress);
Register stack(rsp);
Memory stackSrc(rbx, stackOffsetFromThread);
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack);
jumpR(&c, BytesPerWord, &returnAddress);
}
virtual void apply(Operation op) {
arch_->c.operations[op](&c);
}