remove virtual stack code due to problems with jumps, to be revisited along with other optimizations when everything is working; various bugfixes

This commit is contained in:
Joel Dice 2007-12-12 11:59:45 -07:00
parent fab77e4d96
commit fe24005ff0
4 changed files with 114 additions and 148 deletions

View File

@ -77,7 +77,7 @@ vmInvoke:
// 20(%ebp): stackSize // 20(%ebp): stackSize
// 24(%ebp): returnType // 24(%ebp): returnType
mov 8(%ebp),%rbx mov 8(%ebp),%ebx
// reserve space for arguments // reserve space for arguments
subl 20(%ebp),%esp subl 20(%ebp),%esp

View File

@ -1403,7 +1403,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case areturn: case areturn:
c->epilogue();
c->return_(frame->popObject()); c->return_(frame->popObject());
return; return;
@ -2130,7 +2129,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case ireturn: case ireturn:
case freturn: case freturn:
c->epilogue();
c->return_(frame->popInt()); c->return_(frame->popInt());
return; return;
@ -2367,7 +2365,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lreturn: case lreturn:
case dreturn: case dreturn:
c->epilogue();
c->return_(frame->popLong()); c->return_(frame->popLong());
return; return;
@ -2866,7 +2863,7 @@ compile(MyThread* t, Compiler* c, object method)
unsigned footprint = methodParameterFootprint(t, method); unsigned footprint = methodParameterFootprint(t, method);
unsigned locals = codeMaxLocals(t, code); 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 objectPool(t->m->system, 256);
Vector traceLog(t->m->system, 1024); Vector traceLog(t->m->system, 1024);

View File

@ -178,10 +178,6 @@ class MyOperand: public Operand {
return BytesPerWord; return BytesPerWord;
} }
virtual StackOperand* logicalPush(Context* c) { abort(c); }
virtual void logicalFlush(Context*, StackOperand*) { /* ignore */ }
virtual Register asRegister(Context* c) { abort(c); } virtual Register asRegister(Context* c) { abort(c); }
virtual void release(Context*) { /* ignore */ } virtual void release(Context*) { /* ignore */ }
@ -204,16 +200,9 @@ class MyOperand: public Operand {
class RegisterOperand: public MyOperand { class RegisterOperand: public MyOperand {
public: public:
RegisterOperand(Register value): 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*) { virtual Register asRegister(Context*) {
return value; return value;
} }
@ -236,7 +225,6 @@ class RegisterOperand: public MyOperand {
Register value; Register value;
bool reserved; bool reserved;
StackOperand* stack;
}; };
class ImmediateOperand: public MyOperand { class ImmediateOperand: public MyOperand {
@ -245,8 +233,6 @@ class ImmediateOperand: public MyOperand {
value(value) value(value)
{ } { }
virtual StackOperand* logicalPush(Context* c);
virtual void apply(Context* c, Operation operation); virtual void apply(Context* c, Operation operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) { virtual void apply(Context* c, Operation operation, MyOperand* operand) {
@ -262,8 +248,6 @@ class AbsoluteOperand: public MyOperand {
value(value) value(value)
{ } { }
virtual StackOperand* logicalPush(Context* c);
virtual void apply(Context* c, Operation operation); virtual void apply(Context* c, Operation operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) { virtual void apply(Context* c, Operation operation, MyOperand* operand) {
@ -290,7 +274,7 @@ class MemoryOperand: public MyOperand {
assert(static_cast<System*>(0), scale == 1); // todo assert(static_cast<System*>(0), scale == 1); // todo
} }
virtual StackOperand* logicalPush(Context* c); virtual Register asRegister(Context*);
virtual void apply(Context* c, Operation operation); virtual void apply(Context* c, Operation operation);
@ -336,24 +320,22 @@ class SelectionOperand: public MyOperand {
class StackOperand: public MyOperand { class StackOperand: public MyOperand {
public: public:
StackOperand(MyOperand* base, StackOperand* next): StackOperand(MyOperand* base, int index, StackOperand* next):
base(base), next(next), flushed(false) base(base), index(index), next(next)
{ { }
if (next) {
index = next->index + (next->footprint() / BytesPerWord);
} else {
index = 0;
}
}
virtual StackOperand* logicalPush(Context* c) { virtual unsigned footprint() {
return base->logicalPush(c); return base->footprint();
} }
virtual Register asRegister(Context* c) { virtual Register asRegister(Context* c) {
return base->asRegister(c); return base->asRegister(c);
} }
virtual void apply(Context* c, Operation operation) {
base->apply(c, operation);
}
virtual void accept(Context* c, Operation operation, virtual void accept(Context* c, Operation operation,
RegisterOperand* operand) RegisterOperand* operand)
{ {
@ -361,9 +343,8 @@ class StackOperand: public MyOperand {
} }
MyOperand* base; MyOperand* base;
StackOperand* next;
int index; int index;
bool flushed; StackOperand* next;
}; };
class Context { class Context {
@ -376,7 +357,8 @@ class Context {
zone(s, 8 * 1024), zone(s, 8 * 1024),
indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)), indirectCaller(reinterpret_cast<intptr_t>(indirectCaller)),
stack(0), stack(0),
ipTable(0) ipTable(0),
reserved(0)
{ {
ipMappings.appendAddress ipMappings.appendAddress
(new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0)); (new (zone.allocate(sizeof(IpMapping))) IpMapping(-1, 0));
@ -407,6 +389,7 @@ class Context {
intptr_t indirectCaller; intptr_t indirectCaller;
StackOperand* stack; StackOperand* stack;
IpMapping** ipTable; IpMapping** ipTable;
unsigned reserved;
RegisterOperand* registers[RegisterCount]; RegisterOperand* registers[RegisterCount];
}; };
@ -465,72 +448,49 @@ currentMapping(Context* c)
return mapping; 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* RegisterOperand*
temporary(Context* c, bool reserve) temporary(Context* c)
{ {
RegisterOperand* r = 0;
// we don't yet support using r9-r15 // we don't yet support using r9-r15
for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) { for (unsigned i = 0; i < 8/*RegisterCount*/; ++i) {
if (not c->registers[i]->reserved) { if (not c->registers[i]->reserved) {
if (c->registers[i]->stack == 0) { c->registers[i]->reserved = true;
if (reserve) c->registers[i]->reserved = true; return c->registers[i];
return c->registers[i];
} else if (r == 0 or r->stack->index > c->registers[i]->stack->index) {
r = c->registers[i];
}
} }
} }
if (r) { abort(c);
flush(c, r->stack);
return r;
} else {
abort(c);
}
} }
StackOperand* 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 void
pop(Context* c, MyOperand* dst) pop(Context* c, MyOperand* dst)
{ {
if (c->stack->flushed) { dst->apply(c, MyOperand::pop);
dst->apply(c, MyOperand::pop);
} else {
c->stack->base->apply(c, MyOperand::mov, dst);
c->stack->base->logicalFlush(c, c->stack);
}
c->stack = c->stack->next; c->stack = c->stack->next;
} }
MyOperand* MyOperand*
pop(Context* c) pop(Context* c)
{ {
MyOperand* r; RegisterOperand* tmp = temporary(c);
if (c->stack->flushed) { tmp->apply(c, MyOperand::pop);
RegisterOperand* tmp = temporary(c, true); MyOperand* r = tmp;
tmp->apply(c, MyOperand::pop);
r = tmp;
} else {
r = c->stack->base;
c->stack->base->logicalFlush(c, c->stack);
}
c->stack = c->stack->next; c->stack = c->stack->next;
return r; 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 Register
gpRegister(Context* c, unsigned index) gpRegister(Context* c, unsigned index)
{ {
@ -588,8 +532,6 @@ gpRegister(Context* c, unsigned index)
unsigned unsigned
pushArguments(Context* c, unsigned count, va_list list) pushArguments(Context* c, unsigned count, va_list list)
{ {
flushStack(c);
MyOperand* arguments[count]; MyOperand* arguments[count];
unsigned footprint = 0; unsigned footprint = 0;
for (unsigned i = 0; i < count; ++i) { 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 void
RegisterOperand::apply(Context* c, Operation operation) RegisterOperand::apply(Context* c, Operation operation)
{ {
@ -734,6 +658,17 @@ RegisterOperand::accept(Context* c, Operation operation,
ImmediateOperand* operand) ImmediateOperand* operand)
{ {
switch (operation) { 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_: case and_:
if (operand->value) { if (operand->value) {
rex(c); rex(c);
@ -805,15 +740,21 @@ class AbsoluteMovTask: public IpTask {
MyPromise* promise; 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 void
RegisterOperand::accept(Context* c, Operation operation, RegisterOperand::accept(Context* c, Operation operation,
AbsoluteOperand* operand) AbsoluteOperand* operand)
{ {
switch (operation) { switch (operation) {
case mov: { case mov: {
IpMapping* mapping = currentMapping(c); addAbsoluteMovTask(c, operand->value);
mapping->task = new (c->zone.allocate(sizeof(AbsoluteMovTask)))
AbsoluteMovTask(c->code.length(), operand->value, mapping->task);
accept(c, mov, immediate(c, 0)); accept(c, mov, immediate(c, 0));
accept(c, mov, memory(c, this, 0, 0, 1)); accept(c, mov, memory(c, this, 0, 0, 1));
@ -846,11 +787,13 @@ class DirectCallTask: public IpTask {
uint8_t* address; uint8_t* address;
}; };
StackOperand* void
ImmediateOperand::logicalPush(Context* c) addDirectCallTask(Context* c, intptr_t v)
{ {
return c->stack = new (c->zone.allocate(sizeof(StackOperand))) IpMapping* mapping = currentMapping(c);
StackOperand(this, c->stack); mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
DirectCallTask
(c->code.length(), reinterpret_cast<uint8_t*>(v), mapping->task);
} }
void void
@ -865,43 +808,55 @@ ImmediateOperand::apply(Context* c, Operation operation)
} break; } break;
case call: { case call: {
IpMapping* mapping = currentMapping(c); addDirectCallTask(c, value);
mapping->task = new (c->zone.allocate(sizeof(DirectCallTask)))
DirectCallTask
(c->code.length(), reinterpret_cast<uint8_t*>(value), mapping->task);
c->code.append(0xE8); c->code.append(0xE8);
c->code.append4(0); c->code.append4(0);
} break; } 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); default: abort(c);
} }
} }
StackOperand*
AbsoluteOperand::logicalPush(Context* c)
{
return c->stack = new (c->zone.allocate(sizeof(StackOperand)))
StackOperand(this, c->stack);
}
void void
AbsoluteOperand::apply(Context* c, Operation operation) AbsoluteOperand::apply(Context* c, Operation operation)
{ {
switch (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); default: abort(c);
} }
} }
StackOperand* Register
MemoryOperand::logicalPush(Context* c) MemoryOperand::asRegister(Context* c)
{ {
RegisterOperand* tmp = temporary(c, false); RegisterOperand* tmp = temporary(c);
tmp->accept(c, mov, this); tmp->accept(c, mov, this);
c->stack = new (c->zone.allocate(sizeof(StackOperand))) tmp->release(c);
StackOperand(tmp, c->stack); return tmp->value;
tmp->stack = c->stack;
return c->stack;
} }
void void
@ -916,6 +871,10 @@ MemoryOperand::apply(Context* c, Operation operation)
encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement); encode(c, 0x8f, 0, 0x40, 0x80, rax, base->asRegister(c), displacement);
break; break;
case push:
encode(c, 0xff, 0x30, 0x70, 0xb0, rax, base->asRegister(c), displacement);
break;
default: abort(c); default: abort(c);
} }
} }
@ -931,6 +890,12 @@ MemoryOperand::accept(Context* c, Operation operation,
displacement); displacement);
break; break;
case add:
rex(c);
encode(c, 0x01, 0, 0x40, 0x80, operand->value, base->asRegister(c),
displacement);
break;
default: abort(c); default: abort(c);
} }
} }
@ -958,7 +923,7 @@ MemoryOperand::accept(Context* c, Operation operation,
{ {
switch (operation) { switch (operation) {
case mov: { case mov: {
RegisterOperand* tmp = temporary(c, true); RegisterOperand* tmp = temporary(c);
tmp->accept(c, mov, operand); tmp->accept(c, mov, operand);
accept(c, mov, tmp); accept(c, mov, tmp);
@ -1108,7 +1073,6 @@ class MyCompiler: public Compiler {
} }
virtual Operand* stack() { virtual Operand* stack() {
flushStack(&c);
return register_(&c, rsp); return register_(&c, rsp);
} }
@ -1125,7 +1089,7 @@ class MyCompiler: public Compiler {
} }
virtual Operand* temporary() { virtual Operand* temporary() {
return ::temporary(&c, true); return ::temporary(&c);
} }
virtual void release(Operand* v) { virtual void release(Operand* v) {
@ -1153,7 +1117,7 @@ class MyCompiler: public Compiler {
immediate(&c, c.indirectCaller)->apply(&c, MyOperand::call); 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); return register_(&c, rax);
} }
@ -1180,24 +1144,23 @@ class MyCompiler: public Compiler {
static_cast<MyOperand*>(address)->apply(&c, MyOperand::call); static_cast<MyOperand*>(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); return register_(&c, rax);
} }
virtual void return_(Operand* v) { virtual void return_(Operand* v) {
static_cast<MyOperand*>(v)->apply(&c, MyOperand::mov, register_(&c, rax)); static_cast<MyOperand*>(v)->apply(&c, MyOperand::mov, register_(&c, rax));
epilogue();
ret(); ret();
} }
virtual Operand* call(Operand* v) { virtual Operand* call(Operand* v) {
flushStack(&c);
static_cast<MyOperand*>(v)->apply(&c, MyOperand::call); static_cast<MyOperand*>(v)->apply(&c, MyOperand::call);
return register_(&c, rax); return register_(&c, rax);
} }
virtual Operand* alignedCall(Operand* v) { virtual Operand* alignedCall(Operand* v) {
flushStack(&c);
static_cast<MyOperand*>(v)->apply(&c, MyOperand::alignedCall); static_cast<MyOperand*>(v)->apply(&c, MyOperand::alignedCall);
return register_(&c, rax); return register_(&c, rax);
} }
@ -1340,6 +1303,11 @@ class MyCompiler: public Compiler {
register_(&c, rsp)->apply(&c, MyOperand::mov, register_(&c, rbp)); 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() { virtual void epilogue() {
register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp)); register_(&c, rbp)->apply(&c, MyOperand::mov, register_(&c, rsp));
register_(&c, rbp)->apply(&c, MyOperand::pop); register_(&c, rbp)->apply(&c, MyOperand::pop);

View File

@ -89,6 +89,7 @@ class Compiler {
virtual Operand* select8(Operand*) = 0; virtual Operand* select8(Operand*) = 0;
virtual void prologue() = 0; virtual void prologue() = 0;
virtual void reserve(unsigned size) = 0;
virtual void epilogue() = 0; virtual void epilogue() = 0;
virtual void startLogicalIp(unsigned) = 0; virtual void startLogicalIp(unsigned) = 0;