control flow bugfixes

This commit is contained in:
Joel Dice 2008-04-19 01:03:59 -06:00
parent ab7314e526
commit b19c52b501
2 changed files with 188 additions and 126 deletions

View File

@ -1709,6 +1709,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
handleEntrance(t, frame); handleEntrance(t, frame);
} else if (exceptionHandler) { } else if (exceptionHandler) {
exceptionHandler = false; exceptionHandler = false;
frame->pushObject();
c->call c->call
(c->constant(reinterpret_cast<intptr_t>(gcIfNecessary)), (c->constant(reinterpret_cast<intptr_t>(gcIfNecessary)),
@ -3850,15 +3852,15 @@ finish(MyThread* t, Context* context)
} }
// for debugging: // for debugging:
if (false and if (//false and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"Misc") == 0 and "java/lang/String") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),
"main") == 0) "getBytes") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3951,8 +3953,6 @@ compile(MyThread* t, Context* context)
} }
} }
frame2.pushObject();
for (unsigned i = 1; for (unsigned i = 1;
i < codeMaxStack(t, methodCode(t, context->method)); i < codeMaxStack(t, methodCode(t, context->method));
++i) ++i)

View File

@ -81,9 +81,9 @@ class State {
class LogicalInstruction { class LogicalInstruction {
public: public:
unsigned visits; unsigned visits;
Event* firstEvent;
Event* lastEvent; Event* lastEvent;
unsigned machineOffset; unsigned machineOffset;
int predecessor;
}; };
class Register { class Register {
@ -151,16 +151,18 @@ class Context {
zone(zone), zone(zone),
logicalIp(-1), logicalIp(-1),
state(new (zone->allocate(sizeof(State))) State(0)), state(new (zone->allocate(sizeof(State))) State(0)),
firstEvent(0),
lastEvent(0),
logicalCode(0), logicalCode(0),
logicalCodeLength(0), logicalCodeLength(0),
stackOffset(0), stackOffset(0),
registers(static_cast<Register*> registers(static_cast<Register*>
(zone->allocate(sizeof(Register) * assembler->registerCount()))), (zone->allocate(sizeof(Register) * assembler->registerCount()))),
freeRegisterCount(assembler->registerCount() - 3),
freeRegisters(static_cast<int*>
(zone->allocate(sizeof(int) * freeRegisterCount))),
firstConstant(0), firstConstant(0),
lastConstant(0), lastConstant(0),
constantCount(0), constantCount(0),
nextSequence(0),
junctions(0), junctions(0),
machineCode(0) machineCode(0)
{ {
@ -172,6 +174,13 @@ class Context {
registers[assembler->stack()].reserved = true; registers[assembler->stack()].reserved = true;
registers[assembler->thread()].refCount = 1; registers[assembler->thread()].refCount = 1;
registers[assembler->thread()].reserved = true; registers[assembler->thread()].reserved = true;
unsigned fri = 0;
for (int i = assembler->registerCount() - 1; i >= 0; --i) {
if (not registers[i].reserved) {
freeRegisters[fri++] = i;
}
}
} }
System* system; System* system;
@ -179,15 +188,16 @@ class Context {
Zone* zone; Zone* zone;
int logicalIp; int logicalIp;
State* state; State* state;
Event* firstEvent;
Event* lastEvent;
LogicalInstruction* logicalCode; LogicalInstruction* logicalCode;
unsigned logicalCodeLength; unsigned logicalCodeLength;
unsigned stackOffset; unsigned stackOffset;
Register* registers; Register* registers;
unsigned freeRegisterCount;
int* freeRegisters;
ConstantPoolNode* firstConstant; ConstantPoolNode* firstConstant;
ConstantPoolNode* lastConstant; ConstantPoolNode* lastConstant;
unsigned constantCount; unsigned constantCount;
unsigned nextSequence;
Junction* junctions; Junction* junctions;
uint8_t* machineCode; uint8_t* machineCode;
}; };
@ -284,24 +294,22 @@ class Event {
public: public:
Event(Context* c): Event(Context* c):
next(0), stack(c->state->stack), promises(0), reads(0), next(0), stack(c->state->stack), promises(0), reads(0),
logicalIp(c->logicalIp) sequence(c->nextSequence++)
{ {
assert(c, c->logicalIp >= 0); assert(c, c->logicalIp >= 0);
if (c->lastEvent) { LogicalInstruction* i = c->logicalCode + c->logicalIp;
c->lastEvent->next = this; if (i->lastEvent) {
sequence = c->lastEvent->sequence + 1; i->lastEvent->next = this;
} else { } else {
c->firstEvent = this; i->firstEvent = this;
sequence = 0;
} }
i->lastEvent = this;
c->lastEvent = this;
} }
Event(Context*, Event* next): Event(Context*, Event* next):
next(next), stack(next->stack), promises(0), reads(0), next(next), stack(next->stack), promises(0), reads(0),
sequence(next->sequence), logicalIp(next->logicalIp) sequence(next->sequence)
{ } { }
virtual ~Event() { } virtual ~Event() { }
@ -313,7 +321,6 @@ class Event {
CodePromise* promises; CodePromise* promises;
Read* reads; Read* reads;
unsigned sequence; unsigned sequence;
unsigned logicalIp;
}; };
bool bool
@ -337,11 +344,12 @@ addSite(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
} }
void void
removeSite(Context*, Value* v, Site* s) removeSite(Context* c, Value* v, Site* s)
{ {
for (Site** p = &(v->sites); *p;) { for (Site** p = &(v->sites); *p;) {
if (s == *p) { if (s == *p) {
fprintf(stderr, "remove site %p from %p\n", s, v); fprintf(stderr, "remove site %p from %p\n", s, v);
s->release(c);
*p = (*p)->next; *p = (*p)->next;
break; break;
} else { } else {
@ -350,15 +358,23 @@ removeSite(Context*, Value* v, Site* s)
} }
} }
void
clearSites(Context* c, Value* v)
{
for (Site* s = v->sites; s; s = s->next) {
s->release(c);
}
v->sites = 0;
}
void void
nextRead(Context* c, Value* v) nextRead(Context* c, Value* v)
{ {
fprintf(stderr, "pop read %p from %p; next: %p\n", v->reads, v, v->reads->next); fprintf(stderr, "pop read %p from %p\n", v->reads, v);
v->reads = v->reads->next; v->reads = v->reads->next;
if (v->reads == 0) { if (v->reads == 0) {
for (Site* s = v->sites; s; s = s->next) { clearSites(c, v);
s->release(c);
}
} }
} }
@ -493,6 +509,22 @@ registerSite(Context* c, int low, int high = NoRegister)
RegisterSite* RegisterSite*
freeRegister(Context* c, unsigned size, bool allowAcquired); freeRegister(Context* c, unsigned size, bool allowAcquired);
void
increment(Context* c, int r)
{
fprintf(stderr, "increment %d\n", r);
++ c->registers[r].refCount;
}
void
decrement(Context* c, int r)
{
assert(c, c->registers[r].refCount > 0);
assert(c, c->registers[r].refCount > 1 or (not c->registers[r].reserved));
fprintf(stderr, "decrement %d\n", r);
-- c->registers[r].refCount;
}
class MemorySite: public Site { class MemorySite: public Site {
public: public:
MemorySite(int base, int offset, int index, unsigned scale): MemorySite(int base, int offset, int index, unsigned scale):
@ -515,20 +547,16 @@ class MemorySite: public Site {
} }
virtual void acquire(Context* c, Stack*, unsigned, Value*, Site*) { virtual void acquire(Context* c, Stack*, unsigned, Value*, Site*) {
fprintf(stderr, "increment ref count for %d\n", value.base); increment(c, value.base);
++ c->registers[value.base].refCount;
if (value.index != NoRegister) { if (value.index != NoRegister) {
fprintf(stderr, "increment ref count for %d\n", value.index); increment(c, value.index);
++ c->registers[value.index].refCount;
} }
} }
virtual void release(Context* c) { virtual void release(Context* c) {
fprintf(stderr, "decrement ref count for %d\n", value.base); decrement(c, value.base);
-- c->registers[value.base].refCount;
if (value.index != NoRegister) { if (value.index != NoRegister) {
fprintf(stderr, "decrement ref count for %d\n", value.index); decrement(c, value.index);
-- c->registers[value.index].refCount;
} }
} }
@ -831,9 +859,10 @@ insertRead(Context* c, Event* thisEvent, Event* before, Value* v,
{ {
Read* r = new (c->zone->allocate(sizeof(Read))) Read* r = new (c->zone->allocate(sizeof(Read)))
Read(size, v, target, 0, thisEvent, thisEvent->reads); Read(size, v, target, 0, thisEvent, thisEvent->reads);
fprintf(stderr, "add read %p to %p\n", r, v);
thisEvent->reads = r; thisEvent->reads = r;
fprintf(stderr, "add read %p to %p\n", r, v);
if (before) { if (before) {
for (Read** p = &(v->reads); *p;) { for (Read** p = &(v->reads); *p;) {
if ((*p)->event->sequence >= before->sequence) { if ((*p)->event->sequence >= before->sequence) {
@ -859,7 +888,7 @@ insertRead(Context* c, Event* thisEvent, Event* before, Value* v,
void void
addRead(Context* c, Value* v, unsigned size, Site* target) addRead(Context* c, Value* v, unsigned size, Site* target)
{ {
insertRead(c, c->lastEvent, 0, v, size, target); insertRead(c, c->logicalCode[c->logicalIp].lastEvent, 0, v, size, target);
} }
Site* Site*
@ -867,23 +896,26 @@ pushSite(Context*, PushEvent*);
class PushEvent: public Event { class PushEvent: public Event {
public: public:
PushEvent(Context* c): PushEvent(Context* c, Stack* s):
Event(c), active(false) Event(c), s(s), active(false)
{ {
stack->pushEvent = this; assert(c, s->pushEvent == 0);
addRead(c, stack->value, stack->size * BytesPerWord, pushSite(c, this));
s->pushEvent = this;
addRead(c, s->value, s->size * BytesPerWord, pushSite(c, this));
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
fprintf(stderr, "PushEvent.compile\n"); fprintf(stderr, "PushEvent.compile\n");
if (active) { if (active) {
syncStack(c, stack); syncStack(c, s);
} }
nextRead(c, stack->value); nextRead(c, s->value);
} }
Stack* s;
bool active; bool active;
}; };
@ -919,10 +951,6 @@ class CallEvent: public Event {
s = s->next; s = s->next;
} }
for (Stack* s = stack; s; s = s->next) {
s->pushEvent->active = true;
}
addRead(c, address, BytesPerWord, addRead(c, address, BytesPerWord,
(indirection ? registerSite(c, c->assembler->returnLow()) : 0)); (indirection ? registerSite(c, c->assembler->returnLow()) : 0));
} }
@ -938,11 +966,15 @@ class CallEvent: public Event {
apply(c, type, BytesPerWord, address->source); apply(c, type, BytesPerWord, address->source);
} }
for (Stack* s = stack; s; s = s->next) {
clearSites(c, s->value);
}
for (Read* r = reads; r; r = r->eventNext) { for (Read* r = reads; r; r = r->eventNext) {
nextRead(c, r->value); nextRead(c, r->value);
} }
if (resultSize) { if (resultSize and result->reads) {
addSite(c, 0, 0, result, registerSite addSite(c, 0, 0, result, registerSite
(c, c->assembler->returnLow(), (c, c->assembler->returnLow(),
resultSize > BytesPerWord ? resultSize > BytesPerWord ?
@ -955,7 +987,7 @@ class CallEvent: public Event {
CodePromise(c, c->assembler->length())); CodePromise(c, c->assembler->length()));
} }
if (argumentFootprint) { if (argumentFootprint and ((flags & Compiler::NoReturn) == 0)) {
Assembler::Register stack(c->assembler->stack()); Assembler::Register stack(c->assembler->stack());
Assembler::Constant offset Assembler::Constant offset
(resolved(c, argumentFootprint * BytesPerWord)); (resolved(c, argumentFootprint * BytesPerWord));
@ -1059,7 +1091,7 @@ class MoveEvent: public Event {
nextRead(c, src); nextRead(c, src);
addSite(c, stack, size, dst, target); if (dst->reads) addSite(c, stack, size, dst, target);
} }
BinaryOperation type; BinaryOperation type;
@ -1168,7 +1200,7 @@ class CombineEvent: public Event {
nextRead(c, second); nextRead(c, second);
removeSite(c, second, second->source); removeSite(c, second, second->source);
addSite(c, 0, 0, result, second->source); if (result->reads) addSite(c, 0, 0, result, second->source);
} }
BinaryOperation type; BinaryOperation type;
@ -1205,7 +1237,7 @@ class TranslateEvent: public Event {
nextRead(c, value); nextRead(c, value);
removeSite(c, value, value->source); removeSite(c, value, value->source);
addSite(c, 0, 0, result, value->source); if (result->reads) addSite(c, 0, 0, result, value->source);
} }
UnaryOperation type; UnaryOperation type;
@ -1277,23 +1309,38 @@ appendMemory(Context* c, Value* base, int displacement, Value* index,
Site* Site*
stackSyncSite(Context* c, unsigned index, unsigned size) stackSyncSite(Context* c, unsigned index, unsigned size)
{ {
int high = NoRegister; assert(c, index + size <= c->freeRegisterCount);
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (not c->registers[i].reserved) { return registerSite
if (index == 0) { (c, c->freeRegisters[index],
if (size == 1) { size == 2 ? c->freeRegisters[index + 1] : NoRegister);
return registerSite(c, i, high); }
} else {
high = i; Stack*
-- size; stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
} {
} else { return new (c->zone->allocate(sizeof(Stack)))
-- index; Stack(value, size, index, next);
} }
void
resetStack(Context* c)
{
unsigned i = 0;
Stack* p = 0;
for (Stack* s = c->state->stack; s; s = s->next) {
Stack* n = stack
(c, value(c, stackSyncSite(c, i, s->size)), s->size, s->index, 0);
if (p) {
p->next = n;
} else {
c->state->stack = n;
} }
p = n;
i += s->size;
} }
abort(c);
} }
class StackSyncEvent: public Event { class StackSyncEvent: public Event {
@ -1307,6 +1354,8 @@ class StackSyncEvent: public Event {
stackSyncSite(c, i, s->size)); stackSyncSite(c, i, s->size));
i += s->size; i += s->size;
} }
resetStack(c);
} }
StackSyncEvent(Context* c, Event* next): StackSyncEvent(Context* c, Event* next):
@ -1325,8 +1374,6 @@ class StackSyncEvent: public Event {
for (Read* r = reads; r; r = r->eventNext) { for (Read* r = reads; r; r = r->eventNext) {
nextRead(c, r->value); nextRead(c, r->value);
r->value->sites = r->target;
r->target->next = 0;
} }
} }
}; };
@ -1361,11 +1408,28 @@ pushSite(Context* c, PushEvent* e)
} }
void void
appendPush(Context* c) appendPush(Context* c, Stack* s)
{ {
fprintf(stderr, "appendPush\n"); fprintf(stderr, "appendPush\n");
new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c); new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c, s);
}
void
appendPush(Context* c)
{
appendPush(c, c->state->stack);
}
void
ignore(Context* c, unsigned count)
{
if (count) {
Assembler::Register stack(c->assembler->stack());
Assembler::Constant offset(resolved(c, count * BytesPerWord));
c->assembler->apply
(Add, BytesPerWord, ConstantOperand, &offset, RegisterOperand, &stack);
}
} }
void void
@ -1376,7 +1440,7 @@ popNow(Context* c, Event* event, Stack* stack, unsigned count, bool ignore)
for (unsigned i = count; i;) { for (unsigned i = count; i;) {
if (s->pushed) { if (s->pushed) {
if (s->value->reads and (not ignore)) { if (s->value->reads and (not ignore)) {
assert(c, ignored == 0); ::ignore(c, ignored);
fprintf(stderr, "pop %p\n", s); fprintf(stderr, "pop %p\n", s);
@ -1402,12 +1466,7 @@ popNow(Context* c, Event* event, Stack* stack, unsigned count, bool ignore)
s = s->next; s = s->next;
} }
if (ignored) { ::ignore(c, ignored);
Assembler::Register stack(c->assembler->stack());
Assembler::Constant offset(resolved(c, ignored * BytesPerWord));
c->assembler->apply
(Add, BytesPerWord, ConstantOperand, &offset, RegisterOperand, &stack);
}
} }
void void
@ -1497,20 +1556,24 @@ compile(Context* c)
RegisterOperand, &stack); RegisterOperand, &stack);
} }
for (Event* e = c->firstEvent; e; e = e->next) { for (unsigned i = 0; i < c->logicalCodeLength; ++i) {
fprintf(stderr, "ip: %d\n", e->logicalIp); LogicalInstruction* li = c->logicalCode + i;
if (li->firstEvent) {
li->machineOffset = a->length();
LogicalInstruction* li = c->logicalCode + e->logicalIp; fprintf(stderr, "ip: %d\n", i);
li->machineOffset = a->length();
for (Read* r = e->reads; r; r = r->eventNext) { for (Event* e = li->firstEvent; e; e = e->next) {
r->value->source = readSource(c, e->stack, r, e); for (Read* r = e->reads; r; r = r->eventNext) {
} r->value->source = readSource(c, e->stack, r, e);
}
e->compile(c); e->compile(c);
for (CodePromise* p = e->promises; p; p = p->next) { for (CodePromise* p = e->promises; p; p = p->next) {
p->offset = a->length(); p->offset = a->length();
}
}
} }
} }
} }
@ -1538,13 +1601,8 @@ popState(Context* c)
{ {
c->state = new (c->zone->allocate(sizeof(State))) c->state = new (c->zone->allocate(sizeof(State)))
State(c->state->next); State(c->state->next);
}
Stack* resetStack(c);
stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
{
return new (c->zone->allocate(sizeof(Stack)))
Stack(value, size, index, next);
} }
Stack* Stack*
@ -1581,12 +1639,13 @@ updateJunctions(Context* c)
for (Junction* j = c->junctions; j; j = j->next) { for (Junction* j = c->junctions; j; j = j->next) {
LogicalInstruction* i = c->logicalCode + j->logicalIp; LogicalInstruction* i = c->logicalCode + j->logicalIp;
if (i->predecessor >= 0) { for (int ip = j->logicalIp - 1; ip >= 0; --ip) {
LogicalInstruction* p = c->logicalCode + i->predecessor; LogicalInstruction* p = c->logicalCode + ip;
if (p->lastEvent) {
p->lastEvent = p->lastEvent->next i->lastEvent = i->lastEvent->next
= new (c->zone->allocate(sizeof(StackSyncEvent))) = new (c->zone->allocate(sizeof(StackSyncEvent)))
StackSyncEvent(c, p->lastEvent->next); StackSyncEvent(c, 0);
}
} }
} }
} }
@ -1600,14 +1659,14 @@ used(Context* c, int r)
return v and findSite(c, v, c->registers[r].site); return v and findSite(c, v, c->registers[r].site);
} }
bool // bool
usedExclusively(Context* c, int r) // usedExclusively(Context* c, int r)
{ // {
Value* v = c->registers[r].value; // Value* v = c->registers[r].value;
return used(c, r) // return used(c, r)
and v->pushCount == 0 // and v->pushCount == 0
and v->sites->next == 0; // and v->sites->next == 0;
} // }
int int
freeRegisterExcept(Context* c, int except, bool allowAcquired) freeRegisterExcept(Context* c, int except, bool allowAcquired)
@ -1621,14 +1680,14 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
} }
} }
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) { // for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except // if (i != except
and c->registers[i].refCount == 0 // and c->registers[i].refCount == 0
and (not usedExclusively(c, i))) // and (not usedExclusively(c, i)))
{ // {
return i; // return i;
} // }
} // }
if (allowAcquired) { if (allowAcquired) {
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) { for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
@ -1673,13 +1732,12 @@ class Client: public Assembler::Client {
expect(c, c->registers[r].refCount == 0); expect(c, c->registers[r].refCount == 0);
expect(c, c->registers[r].value == 0); expect(c, c->registers[r].value == 0);
} }
++ c->registers[r].refCount; increment(c, r);
fprintf(stderr, "acquire temporary: %d\n", r);
return r; return r;
} }
virtual void releaseTemporary(int r) { virtual void releaseTemporary(int r) {
-- c->registers[r].refCount; decrement(c, r);
} }
Context* c; Context* c;
@ -1710,17 +1768,14 @@ class MyCompiler: public Compiler {
} }
virtual void visitLogicalIp(unsigned logicalIp) { virtual void visitLogicalIp(unsigned logicalIp) {
if ((++ c.logicalCode[logicalIp].visits) == 1) { if ((++ c.logicalCode[logicalIp].visits) == 2) {
c.junctions = new (c.zone->allocate(sizeof(Junction))) c.junctions = new (c.zone->allocate(sizeof(Junction)))
Junction(logicalIp, c.junctions); Junction(logicalIp, c.junctions);
} }
} }
virtual void startLogicalIp(unsigned logicalIp) { virtual void startLogicalIp(unsigned logicalIp) {
if (c.logicalIp >= 0) { fprintf(stderr, "ip: %d\n", logicalIp);
c.logicalCode[c.logicalIp].lastEvent = c.lastEvent;
}
c.logicalIp = logicalIp; c.logicalIp = logicalIp;
} }
@ -1809,8 +1864,9 @@ class MyCompiler: public Compiler {
} }
Promise* machineIp() { Promise* machineIp() {
return c.lastEvent->promises = new (c.zone->allocate(sizeof(CodePromise))) Event* e = c.logicalCode[c.logicalIp].lastEvent;
CodePromise(&c, c.lastEvent->promises); return e->promises = new (c.zone->allocate(sizeof(CodePromise)))
CodePromise(&c, e->promises);
} }
virtual void mark(Operand* label) { virtual void mark(Operand* label) {
@ -1890,9 +1946,15 @@ class MyCompiler: public Compiler {
va_end(a); va_end(a);
for (Stack* s = c.state->stack; s; s = s->next) {
if (s->pushEvent == 0) {
appendPush(&c, s);
}
s->pushEvent->active = true;
}
Stack* oldStack = c.state->stack; Stack* oldStack = c.state->stack;
fprintf(stderr, "argument count: %d\n", argumentCount);
for (int i = argumentCount - 1; i >= 0; --i) { for (int i = argumentCount - 1; i >= 0; --i) {
::push(&c, argumentSizes[i], arguments[i]); ::push(&c, argumentSizes[i], arguments[i]);
} }