mirror of
https://github.com/corda/corda.git
synced 2025-01-05 20:54:13 +00:00
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:
parent
fab77e4d96
commit
fe24005ff0
@ -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
|
||||
|
@ -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);
|
||||
|
254
src/compiler.cpp
254
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<System*>(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<intptr_t>(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<uint8_t*>(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<uint8_t*>(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<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);
|
||||
}
|
||||
|
||||
virtual void return_(Operand* v) {
|
||||
static_cast<MyOperand*>(v)->apply(&c, MyOperand::mov, register_(&c, rax));
|
||||
epilogue();
|
||||
ret();
|
||||
}
|
||||
|
||||
virtual Operand* call(Operand* v) {
|
||||
flushStack(&c);
|
||||
static_cast<MyOperand*>(v)->apply(&c, MyOperand::call);
|
||||
return register_(&c, rax);
|
||||
}
|
||||
|
||||
virtual Operand* alignedCall(Operand* v) {
|
||||
flushStack(&c);
|
||||
static_cast<MyOperand*>(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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user