From fe24005ff0817beb317b1b922fc3916a3ca6274c Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 12 Dec 2007 11:59:45 -0700 Subject: [PATCH] remove virtual stack code due to problems with jumps, to be revisited along with other optimizations when everything is working; various bugfixes --- src/compile.S | 2 +- src/compile.cpp | 5 +- src/compiler.cpp | 254 +++++++++++++++++++++-------------------------- src/compiler.h | 1 + 4 files changed, 114 insertions(+), 148 deletions(-) diff --git a/src/compile.S b/src/compile.S index f37abea206..754d394d75 100644 --- a/src/compile.S +++ b/src/compile.S @@ -77,7 +77,7 @@ vmInvoke: // 20(%ebp): stackSize // 24(%ebp): returnType - mov 8(%ebp),%rbx + mov 8(%ebp),%ebx // reserve space for arguments subl 20(%ebp),%esp diff --git a/src/compile.cpp b/src/compile.cpp index b4e70e5296..eb6a852ab8 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -1403,7 +1403,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) } break; case areturn: - c->epilogue(); c->return_(frame->popObject()); return; @@ -2130,7 +2129,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case ireturn: case freturn: - c->epilogue(); c->return_(frame->popInt()); return; @@ -2367,7 +2365,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip) case lreturn: case dreturn: - c->epilogue(); c->return_(frame->popLong()); return; @@ -2866,7 +2863,7 @@ compile(MyThread* t, Compiler* c, object method) unsigned footprint = methodParameterFootprint(t, method); unsigned locals = codeMaxLocals(t, code); - c->sub(c->constant((locals - footprint) * BytesPerWord), c->stack()); + c->reserve(locals - footprint); Vector objectPool(t->m->system, 256); Vector traceLog(t->m->system, 1024); diff --git a/src/compiler.cpp b/src/compiler.cpp index eb5d853729..b8c1aa3e7f 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -178,10 +178,6 @@ class MyOperand: public Operand { return BytesPerWord; } - virtual StackOperand* logicalPush(Context* c) { abort(c); } - - virtual void logicalFlush(Context*, StackOperand*) { /* ignore */ } - virtual Register asRegister(Context* c) { abort(c); } virtual void release(Context*) { /* ignore */ } @@ -204,16 +200,9 @@ class MyOperand: public Operand { class RegisterOperand: public MyOperand { public: RegisterOperand(Register value): - value(value), reserved(false), stack(0) + value(value), reserved(false) { } - virtual StackOperand* logicalPush(Context* c); - - virtual void logicalFlush(Context* c UNUSED, StackOperand* s UNUSED) { - assert(c, stack == s); - stack = 0; - } - virtual Register asRegister(Context*) { return value; } @@ -236,7 +225,6 @@ class RegisterOperand: public MyOperand { Register value; bool reserved; - StackOperand* stack; }; class ImmediateOperand: public MyOperand { @@ -245,8 +233,6 @@ class ImmediateOperand: public MyOperand { value(value) { } - virtual StackOperand* logicalPush(Context* c); - virtual void apply(Context* c, Operation operation); virtual void apply(Context* c, Operation operation, MyOperand* operand) { @@ -262,8 +248,6 @@ class AbsoluteOperand: public MyOperand { value(value) { } - virtual StackOperand* logicalPush(Context* c); - virtual void apply(Context* c, Operation operation); virtual void apply(Context* c, Operation operation, MyOperand* operand) { @@ -290,7 +274,7 @@ class MemoryOperand: public MyOperand { assert(static_cast(0), scale == 1); // todo } - virtual StackOperand* logicalPush(Context* c); + virtual Register asRegister(Context*); virtual void apply(Context* c, Operation operation); @@ -336,24 +320,22 @@ class SelectionOperand: public MyOperand { class StackOperand: public MyOperand { public: - StackOperand(MyOperand* base, StackOperand* next): - base(base), next(next), flushed(false) - { - if (next) { - index = next->index + (next->footprint() / BytesPerWord); - } else { - index = 0; - } - } + StackOperand(MyOperand* base, int index, StackOperand* next): + base(base), index(index), next(next) + { } - virtual StackOperand* logicalPush(Context* c) { - return base->logicalPush(c); + virtual unsigned footprint() { + return base->footprint(); } virtual Register asRegister(Context* c) { return base->asRegister(c); } + virtual void apply(Context* c, Operation operation) { + base->apply(c, operation); + } + virtual void accept(Context* c, Operation operation, RegisterOperand* operand) { @@ -361,9 +343,8 @@ class StackOperand: public MyOperand { } MyOperand* base; - StackOperand* next; int index; - bool flushed; + StackOperand* next; }; class Context { @@ -376,7 +357,8 @@ class Context { zone(s, 8 * 1024), indirectCaller(reinterpret_cast(indirectCaller)), stack(0), - ipTable(0) + ipTable(0), + reserved(0) { ipMappings.appendAddress (new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0)); @@ -407,6 +389,7 @@ class Context { intptr_t indirectCaller; StackOperand* stack; IpMapping** ipTable; + unsigned reserved; RegisterOperand* registers[RegisterCount]; }; @@ -465,72 +448,49 @@ currentMapping(Context* c) return mapping; } -void -flush(Context* c, StackOperand* s) -{ - s->base->apply(c, MyOperand::push); - - s->base->logicalFlush(c, s); - - s->base = memory - (c, register_(c, rbp), - (s->index + 1) * BytesPerWord, 0, 1); - s->flushed = true; -} - RegisterOperand* -temporary(Context* c, bool reserve) +temporary(Context* c) { - RegisterOperand* r = 0; // we don't yet support using r9-r15 for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) { if (not c->registers[i]->reserved) { - if (c->registers[i]->stack == 0) { - if (reserve) c->registers[i]->reserved = true; - return c->registers[i]; - } else if (r == 0 or r->stack->index > c->registers[i]->stack->index) { - r = c->registers[i]; - } + c->registers[i]->reserved = true; + return c->registers[i]; } } - if (r) { - flush(c, r->stack); - return r; - } else { - abort(c); - } + abort(c); } StackOperand* -push(Context* c, MyOperand* base) +push(Context* c, MyOperand* v) { - return base->logicalPush(c); + v->apply(c, MyOperand::push); + + int index = (c->stack ? + c->stack->index + (c->stack->footprint() / BytesPerWord) : + 0); + + MyOperand* base = memory + (c, register_(c, rbp), - (c->reserved + index + 1) * BytesPerWord, 0, 1); + + return c->stack = new (c->zone.allocate(sizeof(StackOperand))) + StackOperand(base, index, c->stack); } void pop(Context* c, MyOperand* dst) { - if (c->stack->flushed) { - dst->apply(c, MyOperand::pop); - } else { - c->stack->base->apply(c, MyOperand::mov, dst); - c->stack->base->logicalFlush(c, c->stack); - } + dst->apply(c, MyOperand::pop); c->stack = c->stack->next; } MyOperand* pop(Context* c) { - MyOperand* r; - if (c->stack->flushed) { - RegisterOperand* tmp = temporary(c, true); - tmp->apply(c, MyOperand::pop); - r = tmp; - } else { - r = c->stack->base; - c->stack->base->logicalFlush(c, c->stack); - } + RegisterOperand* tmp = temporary(c); + tmp->apply(c, MyOperand::pop); + MyOperand* r = tmp; c->stack = c->stack->next; return r; } @@ -548,22 +508,6 @@ selection(Context* c, SelectionOperand::SelectionType type, MyOperand* base) } } -void -flushStack(Context* c) -{ - if (c->stack) { - StackOperand* stack[c->stack->index + 1]; - int index = c->stack->index + 1; - for (StackOperand* s = c->stack; s and not s->flushed; s = s->next) { - stack[-- index] = s; - } - - for (; index < c->stack->index + 1; ++ index) { - flush(c, stack[index]); - } - } -} - Register gpRegister(Context* c, unsigned index) { @@ -588,8 +532,6 @@ gpRegister(Context* c, unsigned index) unsigned pushArguments(Context* c, unsigned count, va_list list) { - flushStack(c); - MyOperand* arguments[count]; unsigned footprint = 0; for (unsigned i = 0; i < count; ++i) { @@ -662,24 +604,6 @@ encode(Context* c, uint8_t instruction, uint8_t zeroPrefix, } } -StackOperand* -RegisterOperand::logicalPush(Context* c) -{ - if (reserved or stack) { - RegisterOperand* tmp = temporary(c, false); - tmp->accept(c, mov, this); - c->stack = new (c->zone.allocate(sizeof(StackOperand))) - StackOperand(tmp, c->stack); - tmp->stack = c->stack; - } else { - c->stack = new (c->zone.allocate(sizeof(StackOperand))) - StackOperand(this, c->stack); - stack = c->stack; - } - - return c->stack; -} - void RegisterOperand::apply(Context* c, Operation operation) { @@ -734,6 +658,17 @@ RegisterOperand::accept(Context* c, Operation operation, ImmediateOperand* operand) { switch (operation) { + case add: + if (operand->value) { + assert(c, isInt8(operand->value)); // todo + + rex(c); + c->code.append(0x83); + c->code.append(0xc0 | value); + c->code.append(operand->value); + } + break; + case and_: if (operand->value) { rex(c); @@ -805,15 +740,21 @@ class AbsoluteMovTask: public IpTask { MyPromise* promise; }; +void +addAbsoluteMovTask(Context* c, MyPromise* p) +{ + IpMapping* mapping = currentMapping(c); + mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask))) + AbsoluteMovTask(c->code.length(), p, mapping->task); +} + void RegisterOperand::accept(Context* c, Operation operation, AbsoluteOperand* operand) { switch (operation) { case mov: { - IpMapping* mapping = currentMapping(c); - mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask))) - AbsoluteMovTask(c->code.length(), operand->value, mapping->task); + addAbsoluteMovTask(c, operand->value); accept(c, mov, immediate(c, 0)); accept(c, mov, memory(c, this, 0, 0, 1)); @@ -846,11 +787,13 @@ class DirectCallTask: public IpTask { uint8_t* address; }; -StackOperand* -ImmediateOperand::logicalPush(Context* c) +void +addDirectCallTask(Context* c, intptr_t v) { - return c->stack = new (c->zone.allocate(sizeof(StackOperand))) - StackOperand(this, c->stack); + IpMapping* mapping = currentMapping(c); + mapping->task = new (c->zone.allocate(sizeof(DirectCallTask))) + DirectCallTask + (c->code.length(), reinterpret_cast(v), mapping->task); } void @@ -865,43 +808,55 @@ ImmediateOperand::apply(Context* c, Operation operation) } break; case call: { - IpMapping* mapping = currentMapping(c); - mapping->task = new (c->zone.allocate(sizeof(DirectCallTask))) - DirectCallTask - (c->code.length(), reinterpret_cast(value), mapping->task); + addDirectCallTask(c, value); c->code.append(0xE8); c->code.append4(0); } break; + + case push: + if (isInt8(value)) { + c->code.append(0x6a); + c->code.append(value); + } else if (isInt32(value)) { + c->code.append(0x68); + c->code.append4(value); + } else { + RegisterOperand* tmp = temporary(c); + tmp->accept(c, mov, this); + tmp->apply(c, push); + tmp->release(c); + } + break; default: abort(c); } } -StackOperand* -AbsoluteOperand::logicalPush(Context* c) -{ - return c->stack = new (c->zone.allocate(sizeof(StackOperand))) - StackOperand(this, c->stack); -} - void AbsoluteOperand::apply(Context* c, Operation operation) { switch (operation) { + case push: { + addAbsoluteMovTask(c, value); + + RegisterOperand* tmp = temporary(c); + tmp->accept(c, mov, immediate(c, 0)); + memory(c, tmp, 0, 0, 1)->apply(c, push); + tmp->release(c); + } break; + default: abort(c); } } -StackOperand* -MemoryOperand::logicalPush(Context* c) +Register +MemoryOperand::asRegister(Context* c) { - RegisterOperand* tmp = temporary(c, false); + RegisterOperand* tmp = temporary(c); tmp->accept(c, mov, this); - c->stack = new (c->zone.allocate(sizeof(StackOperand))) - StackOperand(tmp, c->stack); - tmp->stack = c->stack; - return c->stack; + tmp->release(c); + return tmp->value; } void @@ -916,6 +871,10 @@ MemoryOperand::apply(Context* c, Operation operation) encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement); break; + case push: + encode(c, 0xff, 0x30, 0x70, 0xb0, rax, base->asRegister(c), displacement); + break; + default: abort(c); } } @@ -931,6 +890,12 @@ MemoryOperand::accept(Context* c, Operation operation, displacement); break; + case add: + rex(c); + encode(c, 0x01, 0, 0x40, 0x80, operand->value, base->asRegister(c), + displacement); + break; + default: abort(c); } } @@ -958,7 +923,7 @@ MemoryOperand::accept(Context* c, Operation operation, { switch (operation) { case mov: { - RegisterOperand* tmp = temporary(c, true); + RegisterOperand* tmp = temporary(c); tmp->accept(c, mov, operand); accept(c, mov, tmp); @@ -1108,7 +1073,6 @@ class MyCompiler: public Compiler { } virtual Operand* stack() { - flushStack(&c); return register_(&c, rsp); } @@ -1125,7 +1089,7 @@ class MyCompiler: public Compiler { } virtual Operand* temporary() { - return ::temporary(&c, true); + return ::temporary(&c); } virtual void release(Operand* v) { @@ -1153,7 +1117,7 @@ class MyCompiler: public Compiler { immediate(&c, c.indirectCaller)->apply(&c, MyOperand::call); - immediate(&c, footprint)->apply(&c, MyOperand::sub, register_(&c, rsp)); + immediate(&c, footprint)->apply(&c, MyOperand::add, register_(&c, rsp)); return register_(&c, rax); } @@ -1180,24 +1144,23 @@ class MyCompiler: public Compiler { static_cast(address)->apply(&c, MyOperand::call); - immediate(&c, footprint)->apply(&c, MyOperand::sub, register_(&c, rsp)); + immediate(&c, footprint)->apply(&c, MyOperand::add, register_(&c, rsp)); return register_(&c, rax); } virtual void return_(Operand* v) { static_cast(v)->apply(&c, MyOperand::mov, register_(&c, rax)); + epilogue(); ret(); } virtual Operand* call(Operand* v) { - flushStack(&c); static_cast(v)->apply(&c, MyOperand::call); return register_(&c, rax); } virtual Operand* alignedCall(Operand* v) { - flushStack(&c); static_cast(v)->apply(&c, MyOperand::alignedCall); return register_(&c, rax); } @@ -1340,6 +1303,11 @@ class MyCompiler: public Compiler { register_(&c, rsp)->apply(&c, MyOperand::mov, register_(&c, rbp)); } + virtual void reserve(unsigned size) { + sub(constant(size * BytesPerWord), stack()); + c.reserved = size; + } + virtual void epilogue() { register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp)); register_(&c, rbp)->apply(&c, MyOperand::pop); diff --git a/src/compiler.h b/src/compiler.h index 81a8cc5280..b3f98ef865 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -89,6 +89,7 @@ class Compiler { virtual Operand* select8(Operand*) = 0; virtual void prologue() = 0; + virtual void reserve(unsigned size) = 0; virtual void epilogue() = 0; virtual void startLogicalIp(unsigned) = 0;