improved tracking of data flow across control flow boundaries

This commit is contained in:
Joel Dice 2008-09-13 15:09:26 -06:00
parent 44ccd2b09e
commit bd9e8a77e2
3 changed files with 274 additions and 154 deletions

View File

@ -598,8 +598,6 @@ class Frame {
sp(f->sp), sp(f->sp),
level(f->level + 1) level(f->level + 1)
{ {
c->pushState();
memcpy(stackMap, f->stackMap, codeMaxStack memcpy(stackMap, f->stackMap, codeMaxStack
(t, methodCode(t, context->method))); (t, methodCode(t, context->method)));
@ -610,12 +608,6 @@ class Frame {
~Frame() { ~Frame() {
if (t->exception == 0) { if (t->exception == 0) {
if (level > 0) {
c->saveStack();
c->popState();
c->resetStack();
}
if (level > 1) { if (level > 1) {
context->eventLog.append(PopContextEvent); context->eventLog.append(PopContextEvent);
} }
@ -2518,9 +2510,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
} else { } else {
c->jne(target); c->jne(target);
} }
Compiler::State* state = c->saveState();
compile(t, frame, newIp); compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} break; } break;
case if_icmpeq: case if_icmpeq:
@ -2558,8 +2554,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
break; break;
} }
Compiler::State* state = c->saveState();
compile(t, frame, newIp); compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} break; } break;
case ifeq: case ifeq:
@ -2596,8 +2596,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
break; break;
} }
Compiler::State* state = c->saveState();
compile(t, frame, newIp); compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} break; } break;
case ifnull: case ifnull:
@ -2614,9 +2618,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
} else { } else {
c->jne(target); c->jne(target);
} }
Compiler::State* state = c->saveState();
compile(t, frame, newIp); compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} break; } break;
case iinc: { case iinc: {
@ -2857,7 +2865,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
assert(t, newIp < codeLength(t, code)); assert(t, newIp < codeLength(t, code));
c->saveStack(); // todo: flush stack to memory here
Compiler::State* state = c->saveState();
frame->pushAddress(frame->machineIp(ip)); frame->pushAddress(frame->machineIp(ip));
c->jmp(frame->machineIp(newIp)); c->jmp(frame->machineIp(newIp));
@ -2868,6 +2877,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
frame->pop(1); frame->pop(1);
c->restoreState(state);
} break; } break;
case l2d: { case l2d: {
@ -3036,9 +3047,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
0, 0, BytesPerWord, 0, 0, BytesPerWord,
4, key, start, c->constant(pairCount), default_)); 4, key, start, c->constant(pairCount), default_));
Compiler::State* state = c->saveState();
for (int32_t i = 0; i < pairCount; ++i) { for (int32_t i = 0; i < pairCount; ++i) {
compile(t, frame, ipTable[i]); compile(t, frame, ipTable[i]);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} }
ip = defaultIp; ip = defaultIp;
@ -3395,9 +3410,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
c->mark(defaultCase); c->mark(defaultCase);
c->jmp(frame->machineIp(defaultIp)); c->jmp(frame->machineIp(defaultIp));
Compiler::State* state = c->saveState();
for (int32_t i = 0; i < top - bottom + 1; ++i) { for (int32_t i = 0; i < top - bottom + 1; ++i) {
compile(t, frame, ipTable[i]); compile(t, frame, ipTable[i]);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
c->restoreState(state);
} }
ip = defaultIp; ip = defaultIp;
@ -3904,6 +3923,8 @@ compile(MyThread* t, Context* context)
} }
} }
Compiler::State* state = c->saveState();
compile(t, &frame, 0); compile(t, &frame, 0);
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
@ -3922,6 +3943,8 @@ compile(MyThread* t, Context* context)
bool progress = false; bool progress = false;
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) { for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
c->restoreState(state);
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i); ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
unsigned start = exceptionHandlerStart(eh); unsigned start = exceptionHandlerStart(eh);

View File

@ -31,6 +31,7 @@ class RegisterSite;
class Event; class Event;
class PushEvent; class PushEvent;
class Read; class Read;
class MultiRead;
class Block; class Block;
void NO_RETURN abort(Context*); void NO_RETURN abort(Context*);
@ -105,17 +106,19 @@ class Stack: public Compiler::StackElement {
Stack* next; Stack* next;
}; };
class State { class MyState: public Compiler::State {
public: public:
State(State* next, Stack* stack, Value** locals): MyState(Stack* stack, Value** locals, Cell* predecessors, MultiRead** reads):
stack(stack), stack(stack),
locals(locals), locals(locals),
next(next) predecessors(predecessors),
reads(reads)
{ } { }
Stack* stack; Stack* stack;
Value** locals; Value** locals;
State* next; Cell* predecessors;
MultiRead** reads;
}; };
class LogicalInstruction { class LogicalInstruction {
@ -163,7 +166,7 @@ class ConstantPoolNode {
class Read { class Read {
public: public:
Read(): Read():
next(0), value(0), event(0), eventNext(0) value(0), event(0), eventNext(0)
{ } { }
virtual ~Read() { } virtual ~Read() { }
@ -178,8 +181,11 @@ class Read {
virtual bool valid() = 0; virtual bool valid() = 0;
virtual unsigned size(Context* c) = 0; virtual unsigned size(Context* c) = 0;
virtual void append(Context* c, Read* r) = 0;
virtual Read* next() = 0;
Read* next;
Value* value; Value* value;
Event* event; Event* event;
Read* eventNext; Read* eventNext;
@ -200,6 +206,10 @@ class Value: public Compiler::Operand {
Value(Site* site, Site* target): Value(Site* site, Site* target):
reads(0), lastRead(0), sites(site), source(0), target(target) reads(0), lastRead(0), sites(site), source(0), target(target)
{ } { }
virtual ~Value() { }
virtual void addPredecessor(Context*, Event*) { }
Read* reads; Read* reads;
Read* lastRead; Read* lastRead;
@ -222,7 +232,9 @@ class Context {
arch(assembler->arch()), arch(assembler->arch()),
zone(zone), zone(zone),
client(client), client(client),
state(new (zone->allocate(sizeof(State))) State(0, 0, 0)), stack(0),
locals(0),
predecessors(0),
logicalCode(0), logicalCode(0),
registers registers
(static_cast<Register**> (static_cast<Register**>
@ -254,7 +266,9 @@ class Context {
Assembler::Architecture* arch; Assembler::Architecture* arch;
Zone* zone; Zone* zone;
Compiler::Client* client; Compiler::Client* client;
State* state; Stack* stack;
Value** locals;
Cell* predecessors;
LogicalInstruction** logicalCode; LogicalInstruction** logicalCode;
Register** registers; Register** registers;
ConstantPoolNode* firstConstant; ConstantPoolNode* firstConstant;
@ -383,10 +397,31 @@ cons(Context* c, void* value, Cell* next)
return new (c->zone->allocate(sizeof(Cell))) Cell(next, value); return new (c->zone->allocate(sizeof(Cell))) Cell(next, value);
} }
Cell*
append(Context* c, Cell* first, Cell* second)
{
if (first) {
if (second) {
Cell* start = cons(c, first->value, second);
Cell* end = start;
for (Cell* cell = first->next; cell; cell = cell->next) {
Cell* n = cons(c, cell->value, second);
end->next = n;
end = n;
}
return start;
} else {
return first;
}
} else {
return second;
}
}
class Event { class Event {
public: public:
Event(Context* c): Event(Context* c):
next(0), stack(c->state->stack), locals(c->state->locals), promises(0), next(0), stack(c->stack), locals(c->locals), promises(0),
reads(0), junctionSites(0), savedSites(0), predecessors(0), successors(0), reads(0), junctionSites(0), savedSites(0), predecessors(0), successors(0),
block(0), logicalInstruction(c->logicalCode[c->logicalIp]), readCount(0), block(0), logicalInstruction(c->logicalCode[c->logicalIp]), readCount(0),
sequence(c->nextSequence++) sequence(c->nextSequence++)
@ -395,8 +430,6 @@ class Event {
if (c->lastEvent) { if (c->lastEvent) {
c->lastEvent->next = this; c->lastEvent->next = this;
predecessors = cons(c, c->lastEvent, 0);
c->lastEvent->successors = cons(c, this, c->lastEvent->successors);
} else { } else {
c->firstEvent = this; c->firstEvent = this;
} }
@ -542,7 +575,7 @@ 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; next: %p\n", v->reads, v, v->reads->next);
v->reads = v->reads->next; v->reads = v->reads->next();
if (not live(v)) { if (not live(v)) {
clearSites(c, v); clearSites(c, v);
} }
@ -948,7 +981,7 @@ class SingleRead: public Read {
public: public:
SingleRead(unsigned size, uint8_t typeMask, uint64_t registerMask, SingleRead(unsigned size, uint8_t typeMask, uint64_t registerMask,
int frameIndex): int frameIndex):
size_(size), typeMask(typeMask), registerMask(registerMask), next_(0), size_(size), typeMask(typeMask), registerMask(registerMask),
frameIndex(frameIndex) frameIndex(frameIndex)
{ } { }
@ -976,6 +1009,16 @@ class SingleRead: public Read {
return size_; return size_;
} }
virtual void append(Context* c, Read* r) {
assert(c, next_ == 0);
next_ = r;
}
virtual Read* next() {
return next_;
}
Read* next_;
unsigned size_; unsigned size_;
uint8_t typeMask; uint8_t typeMask;
uint64_t registerMask; uint64_t registerMask;
@ -1022,7 +1065,7 @@ fixedRegisterRead(Context* c, unsigned size, int low, int high = NoRegister)
class MultiRead: public Read { class MultiRead: public Read {
public: public:
MultiRead(): MultiRead():
reads(0) reads(0), lastRead(0), current(0), visited(false)
{ } { }
virtual Site* pickSite(Context* c, Value* value) { virtual Site* pickSite(Context* c, Value* value) {
@ -1046,18 +1089,27 @@ class MultiRead: public Read {
virtual void intersect(uint8_t* typeMask, uint64_t* registerMask, virtual void intersect(uint8_t* typeMask, uint64_t* registerMask,
int* frameIndex) int* frameIndex)
{ {
for (Cell* cell = reads; cell; cell = cell->next) { if (not visited) {
Read* r = static_cast<Read*>(cell->value); visited = true;
r->intersect(typeMask, registerMask, frameIndex); for (Cell* cell = reads; cell; cell = cell->next) {
Read* r = static_cast<Read*>(cell->value);
r->intersect(typeMask, registerMask, frameIndex);
}
visited = false;
} }
} }
virtual bool valid() { virtual bool valid() {
for (Cell* cell = reads; cell; cell = cell->next) { if (not visited) {
Read* r = static_cast<Read*>(cell->value); visited = true;
if (r->valid()) { for (Cell* cell = reads; cell; cell = cell->next) {
return true; Read* r = static_cast<Read*>(cell->value);
if (r->valid()) {
visited = false;
return true;
}
} }
visited = false;
} }
return false; return false;
} }
@ -1066,7 +1118,30 @@ class MultiRead: public Read {
return static_cast<Read*>(reads->value)->size(c); return static_cast<Read*>(reads->value)->size(c);
} }
virtual void append(Context* c, Read* r) {
Cell* cell = cons(c, r, 0);
if (lastRead == 0) {
reads = cell;
current = cell;
} else {
lastRead->next = cell;
}
lastRead = cell;
}
virtual Read* next() {
return static_cast<Read*>(current->value);
}
Read* step() {
current = current->next;
return next();
}
Cell* reads; Cell* reads;
Cell* lastRead;
Cell* current;
bool visited;
}; };
MultiRead* MultiRead*
@ -1385,43 +1460,22 @@ apply(Context* c, TernaryOperation op,
s3Size, s3Type, s3Operand); s3Size, s3Type, s3Operand);
} }
void
insertRead(Context*, Event* event, int sequence, Value* v, Read* r)
{
r->value = v;
r->event = event;
r->eventNext = event->reads;
event->reads = r;
++ event->readCount;
// fprintf(stderr, "add read %p to %p\n", r, v);
if (sequence >= 0) {
for (Read** p = &(v->reads); *p;) {
if ((*p)->event->sequence > static_cast<unsigned>(sequence)) {
r->next = *p;
*p = r;
break;
} else {
p = &((*p)->next);
}
}
}
if (r->next == 0) {
if (v->lastRead) {
v->lastRead->next = r;
} else {
v->reads = r;
}
v->lastRead = r;
}
}
void void
addRead(Context* c, Value* v, Read* r) addRead(Context* c, Value* v, Read* r)
{ {
insertRead(c, c->logicalCode[c->logicalIp]->lastEvent, -1, v, r); Event* e = c->logicalCode[c->logicalIp]->lastEvent;
r->value = v;
r->event = e;
r->eventNext = e->reads;
e->reads = r;
++ e->readCount;
if (v->lastRead) {
v->lastRead->append(c, r);
} else {
v->reads = r;
}
v->lastRead = r;
} }
void void
@ -1621,7 +1675,7 @@ class MoveEvent: public Event {
fprintf(stderr, "MoveEvent.compile\n"); fprintf(stderr, "MoveEvent.compile\n");
} }
bool isLoad = not valid(src->reads->next); bool isLoad = not valid(src->reads->next());
bool isStore = not valid(dst->reads); bool isStore = not valid(dst->reads);
Site* target = targetOrRegister(c, dst); Site* target = targetOrRegister(c, dst);
@ -1804,8 +1858,8 @@ void
maybePreserve(Context* c, Stack* stack, Value** locals, unsigned size, maybePreserve(Context* c, Stack* stack, Value** locals, unsigned size,
Value* v, Site* s) Value* v, Site* s)
{ {
if (valid(v->reads->next) and v->sites->next == 0) { if (valid(v->reads->next()) and v->sites->next == 0) {
preserve(c, stack, locals, size, v, s, v->reads->next); preserve(c, stack, locals, size, v, s, v->reads->next());
} }
} }
@ -1863,6 +1917,24 @@ value(Context* c, Site* site = 0, Site* target = 0)
return new (c->zone->allocate(sizeof(Value))) Value(site, target); return new (c->zone->allocate(sizeof(Value))) Value(site, target);
} }
class LabelValue: public Value {
public:
LabelValue(Site* site): Value(site, 0), predecessors(0) { }
virtual void addPredecessor(Context* c, Event* e) {
predecessors = cons(c, e, predecessors);
}
Cell* predecessors;
};
LabelValue*
labelValue(Context* c)
{
return new (c->zone->allocate(sizeof(LabelValue))) LabelValue
(constantSite(c, static_cast<Promise*>(0)));
}
Stack* Stack*
stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next) stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
{ {
@ -1882,16 +1954,16 @@ push(Context* c, unsigned size, Value* v)
{ {
assert(c, ceiling(size, BytesPerWord)); assert(c, ceiling(size, BytesPerWord));
c->state->stack = stack(c, v, ceiling(size, BytesPerWord), c->state->stack); c->stack = stack(c, v, ceiling(size, BytesPerWord), c->stack);
} }
Value* Value*
pop(Context* c, unsigned size UNUSED) pop(Context* c, unsigned size UNUSED)
{ {
Stack* s = c->state->stack; Stack* s = c->stack;
assert(c, ceiling(size, BytesPerWord) == s->size); assert(c, ceiling(size, BytesPerWord) == s->size);
c->state->stack = s->next; c->stack = s->next;
return s->value; return s->value;
} }
@ -1915,13 +1987,13 @@ appendCombine(Context* c, TernaryOperation type,
&thunk); &thunk);
if (thunk) { if (thunk) {
Stack* oldStack = c->state->stack; Stack* oldStack = c->stack;
::push(c, secondSize, second); ::push(c, secondSize, second);
::push(c, firstSize, first); ::push(c, firstSize, first);
Stack* argumentStack = c->state->stack; Stack* argumentStack = c->stack;
c->state->stack = oldStack; c->stack = oldStack;
appendCall appendCall
(c, value(c, constantSite(c, c->client->getThunk(type, resultSize))), (c, value(c, constantSite(c, c->client->getThunk(type, resultSize))),
@ -2172,7 +2244,8 @@ appendBranch(Context* c, UnaryOperation type, Value* address)
fprintf(stderr, "appendBranch\n"); fprintf(stderr, "appendBranch\n");
} }
new (c->zone->allocate(sizeof(BranchEvent))) BranchEvent(c, type, address); new (c->zone->allocate(sizeof(BranchEvent)))
BranchEvent(c, type, address);
} }
class BoundsCheckEvent: public Event { class BoundsCheckEvent: public Event {
@ -2284,6 +2357,21 @@ appendParameter(Context* c, Value* value, unsigned size, int index)
(c, value, size, index); (c, value, size, index);
} }
class DummyEvent: public Event {
public:
DummyEvent(Context* c):
Event(c)
{ }
virtual void compile(Context*) { }
};
void
appendDummy(Context* c)
{
new (c->zone->allocate(sizeof(DummyEvent))) DummyEvent(c);
}
// class ClobberLocalEvent: public Event { // class ClobberLocalEvent: public Event {
// public: // public:
// ClobberLocalEvent(Context* c, unsigned size, int index): // ClobberLocalEvent(Context* c, unsigned size, int index):
@ -2516,7 +2604,7 @@ next(Context* c, LogicalInstruction* i)
{ {
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) { for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
i = c->logicalCode[n]; i = c->logicalCode[n];
if (i and i->firstEvent) return i; if (i) return i;
} }
return 0; return 0;
} }
@ -2615,48 +2703,51 @@ count(Stack* s)
return c; return c;
} }
void MyState*
pushState(Context* c) saveState(Context* c)
{ {
if (DebugAppend) { MultiRead** reads;
unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count;
fprintf(stderr, "push at level %d\n", count);
count = 0; for (Stack* s = c->state->stack; s; s = s->next) ++ count;
fprintf(stderr, "stack count: %d\n", count);
}
c->state = new (c->zone->allocate(sizeof(State))) if (c->predecessors) {
State(c->state, c->state->stack, c->state->locals); reads = static_cast<MultiRead**>
} (c->zone->allocate(sizeof(MultiRead*) * frameFootprint(c, c->stack)));
void unsigned index = 0;
saveStack(Context* c) for (unsigned i = 0; i < c->localFootprint; ++i) {
{ MultiRead* r = multiRead(c);
if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp]->stackSaved) { addRead(c, c->locals[i], r);
LogicalInstruction* i = c->logicalCode[c->logicalIp]; reads[index++] = r;
i->stackSaved = true;
i->stack = c->state->stack;
i->locals = c->state->locals;
if (DebugAppend) {
unsigned count = 0;
for (Stack* s = c->state->stack; s; s = s->next) ++ count;
fprintf(stderr, "stack count after ip %d: %d\n", c->logicalIp, count);
} }
for (Stack* s = c->stack; s; s = s->next) {
MultiRead* r = multiRead(c);
addRead(c, s->value, r);
reads[index++] = r;
}
} else {
reads = 0;
} }
return new (c->zone->allocate(sizeof(MyState)))
MyState(c->stack, c->locals, c->predecessors, reads);
} }
void void
popState(Context* c) restoreState(Context* c, MyState* s)
{ {
c->state = new (c->zone->allocate(sizeof(State))) c->stack = s->stack;
State(c->state->next->next, c->state->next->stack, c->state->next->locals); c->locals = s->locals;
c->predecessors = s->predecessors;
if (DebugAppend) {
unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count; if (c->predecessors) {
fprintf(stderr, "pop to level %d\n", count); unsigned index = 0;
count = 0; for (Stack* s = c->state->stack; s; s = s->next) ++ count; for (unsigned i = 0; i < c->localFootprint; ++i) {
fprintf(stderr, "stack count: %d\n", count); c->locals[i]->reads = s->reads[index++]->step();
}
for (Stack* stack = c->stack; stack; stack = stack->next) {
stack->value->reads = s->reads[index++]->step();
}
} }
} }
@ -2665,6 +2756,16 @@ visit(Context* c, unsigned logicalIp)
{ {
assert(c, logicalIp < c->logicalCodeLength); assert(c, logicalIp < c->logicalCodeLength);
if (c->predecessors) {
c->lastEvent->predecessors = c->predecessors;
c->predecessors = cons(c, c->lastEvent, 0);
for (Cell* cell = c->lastEvent->predecessors; cell; cell = cell->next) {
Event* p = static_cast<Event*>(cell->value);
p->successors = cons(c, c->lastEvent, p->successors);
}
}
if (c->logicalCode[logicalIp] == 0) { if (c->logicalCode[logicalIp] == 0) {
c->logicalCode[logicalIp] = new c->logicalCode[logicalIp] = new
(c->zone->allocate(sizeof(LogicalInstruction))) (c->zone->allocate(sizeof(LogicalInstruction)))
@ -2710,20 +2811,12 @@ class MyCompiler: public Compiler {
assembler->setClient(&client); assembler->setClient(&client);
} }
virtual void pushState() { virtual State* saveState() {
::pushState(&c); return ::saveState(&c);
} }
virtual void popState() { virtual void restoreState(State* state) {
::popState(&c); ::restoreState(&c, static_cast<MyState*>(state));
}
virtual void saveStack() {
::saveStack(&c);
}
virtual void resetStack() {
// todo: anything?
} }
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
@ -2738,10 +2831,10 @@ class MyCompiler: public Compiler {
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength)); (c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength); memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength);
c.state->locals = static_cast<Value**> c.locals = static_cast<Value**>
(c.zone->allocate(sizeof(Value*) * localFootprint)); (c.zone->allocate(sizeof(Value*) * localFootprint));
memset(c.state->locals, 0, sizeof(Value*) * localFootprint); memset(c.locals, 0, sizeof(Value*) * localFootprint);
} }
virtual void visitLogicalIp(unsigned logicalIp) { virtual void visitLogicalIp(unsigned logicalIp) {
@ -2753,9 +2846,11 @@ class MyCompiler: public Compiler {
fprintf(stderr, " -- ip: %d\n", logicalIp); fprintf(stderr, " -- ip: %d\n", logicalIp);
} }
visit(&c, logicalIp); if (c.logicalIp >= 0 and c.logicalCode[c.logicalIp]->lastEvent == 0) {
appendDummy(&c);
}
::saveStack(&c); visit(&c, logicalIp);
c.logicalIp = logicalIp; c.logicalIp = logicalIp;
} }
@ -2823,12 +2918,12 @@ class MyCompiler: public Compiler {
} }
virtual Operand* stackTop() { virtual Operand* stackTop() {
Site* s = frameSite(&c, c.state->stack->index); Site* s = frameSite(&c, c.stack->index);
return value(&c, s, s); return value(&c, s, s);
} }
virtual Operand* label() { virtual Operand* label() {
return value(&c, ::constantSite(&c, static_cast<Promise*>(0))); return labelValue(&c);
} }
Promise* machineIp() { Promise* machineIp() {
@ -2836,20 +2931,18 @@ class MyCompiler: public Compiler {
} }
virtual void mark(Operand* label) { virtual void mark(Operand* label) {
for (Site* s = static_cast<Value*>(label)->sites; s; s = s->next) { LabelValue* v = static_cast<LabelValue*>(label);
if (s->type(&c) == ConstantOperand) { assert(&c, v->sites);
static_cast<ConstantSite*>(s)->value.value = machineIp(); assert(&c, v->sites->next == 0);
return; assert(&c, v->sites->type(&c) == ConstantOperand);
} static_cast<ConstantSite*>(v->sites)->value.value = machineIp();
} c.predecessors = append(&c, v->predecessors, c.predecessors);
abort(&c);
} }
virtual void push(unsigned size) { virtual void push(unsigned size) {
assert(&c, ceiling(size, BytesPerWord)); assert(&c, ceiling(size, BytesPerWord));
c.state->stack = ::stack c.stack = ::stack(&c, value(&c), ceiling(size, BytesPerWord), c.stack);
(&c, value(&c), ceiling(size, BytesPerWord), c.state->stack);
} }
virtual void push(unsigned size, Operand* value) { virtual void push(unsigned size, Operand* value) {
@ -2862,15 +2955,15 @@ class MyCompiler: public Compiler {
virtual void pushed() { virtual void pushed() {
Value* v = value(&c); Value* v = value(&c);
c.state->stack = ::stack(&c, v, 1, c.state->stack); c.stack = ::stack(&c, v, 1, c.stack);
} }
virtual void popped() { virtual void popped() {
c.state->stack = c.state->stack->next; c.stack = c.stack->next;
} }
virtual StackElement* top() { virtual StackElement* top() {
return c.state->stack; return c.stack;
} }
virtual unsigned size(StackElement* e) { virtual unsigned size(StackElement* e) {
@ -2882,7 +2975,7 @@ class MyCompiler: public Compiler {
} }
virtual Operand* peek(unsigned size UNUSED, unsigned index) { virtual Operand* peek(unsigned size UNUSED, unsigned index) {
Stack* s = c.state->stack; Stack* s = c.stack;
for (unsigned i = index; i > 0;) { for (unsigned i = index; i > 0;) {
i -= s->size; i -= s->size;
s = s->next; s = s->next;
@ -2920,17 +3013,17 @@ class MyCompiler: public Compiler {
va_end(a); va_end(a);
Stack* oldStack = c.state->stack; Stack* oldStack = c.stack;
Stack* bottomArgument = 0; Stack* bottomArgument = 0;
for (int i = index - 1; i >= 0; --i) { for (int i = index - 1; i >= 0; --i) {
::push(&c, argumentSizes[i], arguments[i]); ::push(&c, argumentSizes[i], arguments[i]);
if (i == index - 1) { if (i == index - 1) {
bottomArgument = c.state->stack; bottomArgument = c.stack;
} }
} }
Stack* argumentStack = c.state->stack; Stack* argumentStack = c.stack;
c.state->stack = oldStack; c.stack = oldStack;
Value* result = value(&c); Value* result = value(&c);
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result, appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
@ -2947,7 +3040,7 @@ class MyCompiler: public Compiler {
{ {
Value* result = value(&c); Value* result = value(&c);
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result, appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
resultSize, c.state->stack, 0, argumentFootprint); resultSize, c.stack, 0, argumentFootprint);
return result; return result;
} }
@ -2961,27 +3054,32 @@ class MyCompiler: public Compiler {
Value* v = value(&c); Value* v = value(&c);
appendParameter(&c, v, size, index); appendParameter(&c, v, size, index);
c.state->locals[index] = v; c.locals[index] = v;
} }
virtual void storeLocal(unsigned, Operand* src, unsigned index) { virtual void storeLocal(unsigned, Operand* src, unsigned index) {
assert(&c, index < c.localFootprint); assert(&c, index < c.localFootprint);
// if (c.state->locals[index]) { // if (c.locals[index]) {
// appendClobberLocal(&c, size, index); // appendClobberLocal(&c, size, index);
// } // }
// Value* v = static_cast<Value*>(memory(base(), localOffset(&c, index))); // Value* v = static_cast<Value*>(memory(base(), localOffset(&c, index)));
// store(size, src, v); // store(size, src, v);
c.state->locals[index] = static_cast<Value*>(src); unsigned size = sizeof(Value*) * c.localFootprint;
Value** newLocals = static_cast<Value**>(c.zone->allocate(size));
memcpy(newLocals, c.locals, size);
c.locals = newLocals;
c.locals[index] = static_cast<Value*>(src);
} }
virtual Operand* loadLocal(unsigned, unsigned index) { virtual Operand* loadLocal(unsigned, unsigned index) {
assert(&c, index < c.localFootprint); assert(&c, index < c.localFootprint);
assert(&c, c.state->locals[index]); assert(&c, c.locals[index]);
return c.state->locals[index]; return c.locals[index];
} }
virtual void checkBounds(Operand* object, unsigned lengthOffset, virtual void checkBounds(Operand* object, unsigned lengthOffset,

View File

@ -32,13 +32,12 @@ class Compiler {
class Operand { }; class Operand { };
class StackElement { }; class StackElement { };
class State { };
virtual ~Compiler() { } virtual ~Compiler() { }
virtual void pushState() = 0; virtual State* saveState() = 0;
virtual void popState() = 0; virtual void restoreState(State* state) = 0;
virtual void saveStack() = 0;
virtual void resetStack() = 0;
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint, virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
unsigned localFootprint, unsigned maxStackFootprint) = 0; unsigned localFootprint, unsigned maxStackFootprint) = 0;