fix handling of instructions which are targets of more than one conditional branch

This commit is contained in:
Joel Dice 2008-10-13 18:18:18 -06:00
parent 3c798f5bd7
commit aaaf388652
2 changed files with 276 additions and 175 deletions

View File

@ -3873,7 +3873,7 @@ 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)),

View File

@ -127,10 +127,10 @@ class MultiReadPair {
MultiRead* read; MultiRead* read;
}; };
class MyState: public Compiler::State { class ForkState: public Compiler::State {
public: public:
MyState(Stack* stack, Local* locals, Event* predecessor, ForkState(Stack* stack, Local* locals, Event* predecessor,
unsigned logicalIp): unsigned logicalIp):
stack(stack), stack(stack),
locals(locals), locals(locals),
predecessor(predecessor), predecessor(predecessor),
@ -276,7 +276,7 @@ class Context {
machineCode(0), machineCode(0),
firstEvent(0), firstEvent(0),
lastEvent(0), lastEvent(0),
state(0), forkState(0),
logicalIp(-1), logicalIp(-1),
constantCount(0), constantCount(0),
logicalCodeLength(0), logicalCodeLength(0),
@ -314,7 +314,7 @@ class Context {
uint8_t* machineCode; uint8_t* machineCode;
Event* firstEvent; Event* firstEvent;
Event* lastEvent; Event* lastEvent;
MyState* state; ForkState* forkState;
int logicalIp; int logicalIp;
unsigned constantCount; unsigned constantCount;
unsigned logicalCodeLength; unsigned logicalCodeLength;
@ -453,60 +453,83 @@ append(Context* c, Cell* first, Cell* second)
} }
} }
unsigned
count(Cell* c)
{
unsigned n = 0;
for (; c; c = c->next) ++ n;
return n;
}
class StubReadPair { class StubReadPair {
public: public:
Value* value; Value* value;
StubRead* read; StubRead* read;
}; };
class JunctionState {
public:
JunctionState(): readCount(0) { }
unsigned readCount;
StubReadPair reads[0];
};
class Link {
public:
Link(Event* predecessor, Link* nextPredecessor, Event* successor,
Link* nextSuccessor, ForkState* forkState):
predecessor(predecessor), nextPredecessor(nextPredecessor),
successor(successor), nextSuccessor(nextSuccessor), forkState(forkState),
junctionState(0)
{ }
Event* predecessor;
Link* nextPredecessor;
Event* successor;
Link* nextSuccessor;
ForkState* forkState;
JunctionState* junctionState;
};
Link*
link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor,
Link* nextSuccessor, ForkState* forkState)
{
return new (c->zone->allocate(sizeof(Link))) Link
(predecessor, nextPredecessor, successor, nextSuccessor, forkState);
}
unsigned
countPredecessors(Link* link)
{
unsigned c = 0;
for (; link; link = link->nextPredecessor) ++ c;
return c;
}
Link*
lastPredecessor(Link* link)
{
while (link->nextPredecessor) link = link->nextPredecessor;
return link;
}
unsigned
countSuccessors(Link* link)
{
unsigned c = 0;
for (; link; link = link->nextSuccessor) ++ c;
return c;
}
class Event { class Event {
public: public:
Event(Context* c): Event(Context* c):
next(0), stackBefore(c->stack), localsBefore(c->locals), next(0), stackBefore(c->stack), localsBefore(c->locals),
stackAfter(0), localsAfter(0), promises(0), reads(0), stackAfter(0), localsAfter(0), promises(0), reads(0),
junctionSites(0), savedSites(0), predecessors(0), successors(0), block(0), junctionSites(0), savedSites(0), predecessors(0), successors(0),
logicalInstruction(c->logicalCode[c->logicalIp]), state(c->state), cleanLink(0), block(0), logicalInstruction(c->logicalCode[c->logicalIp]),
junctionReads(0), readCount(0) readCount(0)
{ { }
assert(c, c->logicalIp >= 0);
if (c->lastEvent) {
c->lastEvent->next = this;
} else {
c->firstEvent = this;
}
c->lastEvent = this;
Event* p = c->predecessor;
if (p) {
predecessors = cons(c, p, 0);
p->successors = cons(c, this, p->successors);
}
c->predecessor = this;
if (logicalInstruction->firstEvent == 0) {
logicalInstruction->firstEvent = this;
}
logicalInstruction->lastEvent = this;
c->state = 0;
}
virtual ~Event() { } virtual ~Event() { }
virtual const char* name() = 0; virtual const char* name() = 0;
virtual void compile(Context* c) = 0;
virtual void compilePostsync(Context*) { } virtual void compile(Context* c) = 0;
virtual bool isBranch() { return false; } virtual bool isBranch() { return false; }
@ -519,12 +542,11 @@ class Event {
Read* reads; Read* reads;
Site** junctionSites; Site** junctionSites;
Site** savedSites; Site** savedSites;
Cell* predecessors; Link* predecessors;
Cell* successors; Link* successors;
Link* cleanLink;
Block* block; Block* block;
LogicalInstruction* logicalInstruction; LogicalInstruction* logicalInstruction;
MyState* state;
StubReadPair* junctionReads;
unsigned readCount; unsigned readCount;
}; };
@ -653,8 +675,8 @@ nextRead(Context* c, Event* e, Value* v)
{ {
assert(c, e == v->reads->event); assert(c, e == v->reads->event);
// fprintf(stderr, "pop read %p from %p; next: %p\n", fprintf(stderr, "pop read %p from %p next %p event %p (%s)\n",
// v->reads, v, v->reads->next(c)); v->reads, v, v->reads->next(c), e, (e ? e->name() : 0));
v->reads = v->reads->next(c); v->reads = v->reads->next(c);
if (not live(v)) { if (not live(v)) {
@ -1328,15 +1350,17 @@ class MultiRead: public Read {
void allocateTarget(Context* c) { void allocateTarget(Context* c) {
Cell* cell = cons(c, 0, 0); Cell* cell = cons(c, 0, 0);
if (lastTarget == 0) { fprintf(stderr, "allocate target %p in %p\n", cell, this);
firstTarget = cell; if (lastTarget) {
} else {
lastTarget->next = cell; lastTarget->next = cell;
} else {
firstTarget = cell;
} }
lastTarget = cell; lastTarget = cell;
} }
Read* nextTarget() { Read* nextTarget() {
fprintf(stderr, "next target %p in %p\n", firstTarget, this);
Read* r = static_cast<Read*>(firstTarget->value); Read* r = static_cast<Read*>(firstTarget->value);
firstTarget = firstTarget->next; firstTarget = firstTarget->next;
return r; return r;
@ -1358,7 +1382,7 @@ multiRead(Context* c, unsigned size)
class StubRead: public Read { class StubRead: public Read {
public: public:
StubRead(unsigned size): StubRead(unsigned size):
Read(size), read(0), visited(false) Read(size), next_(0), read(0), visited(false)
{ } { }
virtual Site* pickSite(Context* c, Value* value) { virtual Site* pickSite(Context* c, Value* value) {
@ -1399,14 +1423,16 @@ class StubRead: public Read {
return true; return true;
} }
virtual void append(Context*, Read* r) { virtual void append(Context* c, Read* r) {
read = r; assert(c, next_ == 0);
next_ = r;
} }
virtual Read* next(Context* c) { virtual Read* next(Context*) {
abort(c); return next_;
} }
Read* next_;
Read* read; Read* read;
bool visited; bool visited;
}; };
@ -1845,7 +1871,7 @@ apply(Context* c, TernaryOperation op,
void void
addRead(Context* c, Event* e, Value* v, Read* r) addRead(Context* c, Event* e, Value* v, Read* r)
{ {
// fprintf(stderr, "add read %p to %p\n", r, v); fprintf(stderr, "add read %p to %p last %p event %p (%s)\n", r, v, v->lastRead, e, (e ? e->name() : 0));
r->value = v; r->value = v;
if (e) { if (e) {
@ -1911,6 +1937,9 @@ codePromise(Context* c, Promise* offset)
return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset); return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset);
} }
void
append(Context* c, Event* e);
class CallEvent: public Event { class CallEvent: public Event {
public: public:
CallEvent(Context* c, Value* address, unsigned flags, CallEvent(Context* c, Value* address, unsigned flags,
@ -2014,10 +2043,10 @@ appendCall(Context* c, Value* address, unsigned flags,
Stack* argumentStack, unsigned argumentCount, Stack* argumentStack, unsigned argumentCount,
unsigned stackArgumentFootprint) unsigned stackArgumentFootprint)
{ {
new (c->zone->allocate(sizeof(CallEvent))) append(c, new (c->zone->allocate(sizeof(CallEvent)))
CallEvent(c, address, flags, traceHandler, result, CallEvent(c, address, flags, traceHandler, result,
resultSize, argumentStack, argumentCount, resultSize, argumentStack, argumentCount,
stackArgumentFootprint); stackArgumentFootprint));
} }
class ReturnEvent: public Event { class ReturnEvent: public Event {
@ -2052,7 +2081,8 @@ class ReturnEvent: public Event {
void void
appendReturn(Context* c, unsigned size, Value* value) appendReturn(Context* c, unsigned size, Value* value)
{ {
new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, size, value); append(c, new (c->zone->allocate(sizeof(ReturnEvent)))
ReturnEvent(c, size, value));
} }
class MoveEvent: public Event { class MoveEvent: public Event {
@ -2154,10 +2184,11 @@ appendMove(Context* c, BinaryOperation type, unsigned srcSize, Value* src,
assert(c, not thunk); // todo assert(c, not thunk); // todo
new (c->zone->allocate(sizeof(MoveEvent))) append(c, new (c->zone->allocate(sizeof(MoveEvent)))
MoveEvent(c, type, srcSize, src, dstSize, dst, MoveEvent
read(c, srcSize, srcTypeMask, srcRegisterMask, AnyFrameIndex), (c, type, srcSize, src, dstSize, dst,
read(c, dstSize, dstTypeMask, dstRegisterMask, AnyFrameIndex)); read(c, srcSize, srcTypeMask, srcRegisterMask, AnyFrameIndex),
read(c, dstSize, dstTypeMask, dstRegisterMask, AnyFrameIndex)));
} }
ConstantSite* ConstantSite*
@ -2230,11 +2261,11 @@ appendCompare(Context* c, unsigned size, Value* first, Value* second)
assert(c, not thunk); // todo assert(c, not thunk); // todo
new (c->zone->allocate(sizeof(CompareEvent))) append(c, new (c->zone->allocate(sizeof(CompareEvent)))
CompareEvent CompareEvent
(c, size, first, second, (c, size, first, second,
read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex), read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex),
read(c, size, secondTypeMask, secondRegisterMask, AnyFrameIndex)); read(c, size, secondTypeMask, secondRegisterMask, AnyFrameIndex)));
} }
void void
@ -2393,15 +2424,16 @@ appendCombine(Context* c, TernaryOperation type,
(c, secondSize, secondTypeMask, secondRegisterMask, AnyFrameIndex); (c, secondSize, secondTypeMask, secondRegisterMask, AnyFrameIndex);
} }
new (c->zone->allocate(sizeof(CombineEvent))) append
CombineEvent (c, new (c->zone->allocate(sizeof(CombineEvent)))
(c, type, CombineEvent
firstSize, first, (c, type,
secondSize, second, firstSize, first,
resultSize, result, secondSize, second,
read(c, firstSize, firstTypeMask, firstRegisterMask, AnyFrameIndex), resultSize, result,
secondRead, read(c, firstSize, firstTypeMask, firstRegisterMask, AnyFrameIndex),
resultRead); secondRead,
resultRead));
} }
} }
@ -2456,10 +2488,10 @@ appendTranslate(Context* c, BinaryOperation type, unsigned size, Value* value,
// todo: respect resultTypeMask and resultRegisterMask // todo: respect resultTypeMask and resultRegisterMask
new (c->zone->allocate(sizeof(TranslateEvent))) append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
TranslateEvent TranslateEvent
(c, type, size, value, result, (c, type, size, value, result,
read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex)); read(c, size, firstTypeMask, firstRegisterMask, AnyFrameIndex)));
} }
class MemoryEvent: public Event { class MemoryEvent: public Event {
@ -2524,8 +2556,8 @@ void
appendMemory(Context* c, Value* base, int displacement, Value* index, appendMemory(Context* c, Value* base, int displacement, Value* index,
unsigned scale, Value* result) unsigned scale, Value* result)
{ {
new (c->zone->allocate(sizeof(MemoryEvent))) append(c, new (c->zone->allocate(sizeof(MemoryEvent)))
MemoryEvent(c, base, displacement, index, scale, result); MemoryEvent(c, base, displacement, index, scale, result));
} }
class BranchEvent: public Event { class BranchEvent: public Event {
@ -2616,8 +2648,8 @@ class BranchEvent: public Event {
void void
appendBranch(Context* c, UnaryOperation type, Value* address) appendBranch(Context* c, UnaryOperation type, Value* address)
{ {
new (c->zone->allocate(sizeof(BranchEvent))) append(c, new (c->zone->allocate(sizeof(BranchEvent)))
BranchEvent(c, type, address); BranchEvent(c, type, address));
} }
class BoundsCheckEvent: public Event { class BoundsCheckEvent: public Event {
@ -2691,8 +2723,8 @@ void
appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset, appendBoundsCheck(Context* c, Value* object, unsigned lengthOffset,
Value* index, intptr_t handler) Value* index, intptr_t handler)
{ {
new (c->zone->allocate(sizeof(BoundsCheckEvent))) BoundsCheckEvent append(c, new (c->zone->allocate(sizeof(BoundsCheckEvent)))
(c, object, lengthOffset, index, handler); BoundsCheckEvent(c, object, lengthOffset, index, handler));
} }
class FrameSiteEvent: public Event { class FrameSiteEvent: public Event {
@ -2717,8 +2749,8 @@ class FrameSiteEvent: public Event {
void void
appendFrameSite(Context* c, Value* value, unsigned size, int index) appendFrameSite(Context* c, Value* value, unsigned size, int index)
{ {
new (c->zone->allocate(sizeof(FrameSiteEvent))) FrameSiteEvent append(c, new (c->zone->allocate(sizeof(FrameSiteEvent)))
(c, value, size, index); FrameSiteEvent(c, value, size, index));
} }
unsigned unsigned
@ -2727,6 +2759,46 @@ frameFootprint(Context* c, Stack* s)
return c->localFootprint + (s ? (s->index + s->size) : 0); return c->localFootprint + (s ? (s->index + s->size) : 0);
} }
void
skipRead(Context* c, Value* v, StubReadPair* p)
{
if (v and not v->visited) {
assert(c, v->reads == p->read);
v->visited = true;
nextRead(c, 0, v);
}
}
void
clean(Context* c, Link* link)
{
fprintf(stderr, "clean link from %d to %d\n",
link->predecessor->logicalInstruction->index,
link->successor->logicalInstruction->index);
ForkState* forkState = link->forkState;
if (forkState) {
for (unsigned i = 0; i < forkState->readCount; ++i) {
MultiReadPair* p = forkState->reads + i;
Value* v = p->value;
v->reads = p->read->nextTarget();
fprintf(stderr, "next read %p for %p\n", v->reads, v);
if (not live(v)) {
clearSites(c, v);
}
}
}
JunctionState* junctionState = link->junctionState;
if (junctionState) {
for (unsigned i = 0; i < junctionState->readCount; ++i) {
assert(c, junctionState->reads[i].value->reads
== junctionState->reads[i].read);
nextRead(c, 0, junctionState->reads[i].value);
}
}
}
class DummyEvent: public Event { class DummyEvent: public Event {
public: public:
DummyEvent(Context* c): DummyEvent(Context* c):
@ -2750,12 +2822,45 @@ appendDummy(Context* c)
c->stack = i->stack; c->stack = i->stack;
c->locals = i->locals; c->locals = i->locals;
new (c->zone->allocate(sizeof(DummyEvent))) DummyEvent(c); append(c, new (c->zone->allocate(sizeof(DummyEvent))) DummyEvent(c));
c->stack = stack; c->stack = stack;
c->locals = locals; c->locals = locals;
} }
void
append(Context* c, Event* e)
{
if (DebugAppend) {
fprintf(stderr, " -- append %s at %d\n",
e->name(), e->logicalInstruction->index);
}
assert(c, c->logicalIp >= 0);
if (c->lastEvent) {
c->lastEvent->next = e;
} else {
c->firstEvent = e;
}
c->lastEvent = e;
Event* p = c->predecessor;
if (p) {
Link* link = ::link(c, p, e->predecessors, e, p->successors, c->forkState);
e->predecessors = link;
p->successors = link;
}
c->forkState = 0;
c->predecessor = e;
if (e->logicalInstruction->firstEvent == 0) {
e->logicalInstruction->firstEvent = e;
}
e->logicalInstruction->lastEvent = e;
}
Site* Site*
readSource(Context* c, Stack* stack, Local* locals, Read* r) readSource(Context* c, Stack* stack, Local* locals, Read* r)
{ {
@ -2854,12 +2959,12 @@ resolveJunctionSite(Context* c, Event* e, Value* v, unsigned index,
void void
propagateJunctionSites(Context* c, Event* e, Site** sites) propagateJunctionSites(Context* c, Event* e, Site** sites)
{ {
for (Cell* pc = e->predecessors; pc; pc = pc->next) { for (Link* pl = e->predecessors; pl; pl = pl->nextPredecessor) {
Event* p = static_cast<Event*>(pc->value); Event* p = pl->predecessor;
if (p->junctionSites == 0) { if (p->junctionSites == 0) {
p->junctionSites = sites; p->junctionSites = sites;
for (Cell* sc = p->successors; sc; sc = sc->next) { for (Link* sl = p->successors; sl; sl = sl->nextSuccessor) {
Event* s = static_cast<Event*>(sc->value); Event* s = sl->successor;
propagateJunctionSites(c, s, sites); propagateJunctionSites(c, s, sites);
} }
} }
@ -2924,9 +3029,9 @@ populateSiteTables(Context* c, Event* e)
} }
} }
} else { } else {
for (Cell* sc = e->successors; sc; sc = sc->next) { for (Link* sl = e->successors; sl; sl = sl->nextSuccessor) {
Event* s = static_cast<Event*>(sc->value); Event* s = sl->successor;
if (s->predecessors->next) { if (s->predecessors->nextPredecessor) {
unsigned size = sizeof(Site*) * frameFootprint; unsigned size = sizeof(Site*) * frameFootprint;
Site** junctionSites = static_cast<Site**> Site** junctionSites = static_cast<Site**>
(c->zone->allocate(size)); (c->zone->allocate(size));
@ -2977,7 +3082,7 @@ populateSiteTables(Context* c, Event* e)
} }
} }
if (e->successors->next) { if (e->successors->nextSuccessor) {
unsigned size = sizeof(Site*) * frameFootprint; unsigned size = sizeof(Site*) * frameFootprint;
Site** savedSites = static_cast<Site**>(c->zone->allocate(size)); Site** savedSites = static_cast<Site**>(c->zone->allocate(size));
memset(savedSites, 0, size); memset(savedSites, 0, size);
@ -3111,66 +3216,56 @@ populateSources(Context* c, Event* e)
} }
void void
addStubRead(Context* c, Value* v, unsigned size, StubReadPair** reads) addStubRead(Context* c, Value* v, unsigned size, JunctionState* state,
unsigned* count)
{ {
if (v) { if (v and (not v->visited)) {
StubRead* r; v->visited = true;
if (v->visited) { StubRead* r = stubRead(c, size);
r = static_cast<StubRead*>(v->lastRead); fprintf(stderr, "add stub read %p to %p\n", r, v);
} else { addRead(c, 0, v, r);
v->visited = true;
r = stubRead(c, size); StubReadPair* p = state->reads + ((*count)++);
addRead(c, 0, v, r);
}
StubReadPair* p = (*reads)++;
p->value = v; p->value = v;
p->read = r; p->read = r;
} }
} }
void void
populateJunctionReads(Context* c, Event* e) populateJunctionReads(Context* c, Link* link)
{ {
StubReadPair* reads = static_cast<StubReadPair*> JunctionState* state = new
(c->zone->allocate(sizeof(StubReadPair) * frameFootprint(c, c->stack))); (c->zone->allocate
(sizeof(JunctionState)
+ (sizeof(StubReadPair) * frameFootprint(c, c->stack))))
JunctionState;
e->junctionReads = reads; link->junctionState = state;
unsigned count = 0;
for (unsigned i = 0; i < c->localFootprint; ++i) { for (unsigned i = 0; i < c->localFootprint; ++i) {
Local* local = c->locals + i; Local* local = c->locals + i;
addStubRead(c, local->value, local->size, &reads); addStubRead(c, local->value, local->size, state, &count);
} }
for (Stack* s = c->stack; s; s = s->next) { for (Stack* s = c->stack; s; s = s->next) {
addStubRead(c, s->value, s->size * BytesPerWord, &reads); addStubRead(c, s->value, s->size * BytesPerWord, state, &count);
} }
for (StubReadPair* r = e->junctionReads; r < reads; ++r) { for (unsigned i = 0; i < count; ++i) {
r->value->visited = false; state->reads[i].value->visited = false;
} }
state->readCount = count;
} }
void void
updateStubRead(Context*, StubReadPair* p, Read* r) updateJunctionReads(Context*, JunctionState* state)
{ {
if (p->read->read == 0) p->read->read = r; for (unsigned i = 0; i < state->readCount; ++i) {
} StubReadPair* p = state->reads + i;
if (p->read->read == 0) p->read->read = p->value->reads;
void
updateJunctionReads(Context* c, Event* e)
{
StubReadPair* reads = e->junctionReads;
for (unsigned i = 0; i < c->localFootprint; ++i) {
if (e->localsAfter[i].value) {
updateStubRead(c, reads++, e->localsAfter[i].value->reads);
}
}
for (Stack* s = e->stackAfter; s; s = s->next) {
updateStubRead(c, reads++, s->value->reads);
} }
} }
@ -3226,7 +3321,8 @@ compile(Context* c)
" -- compile %s at %d with %d preds %d succs %d stack before " " -- compile %s at %d with %d preds %d succs %d stack before "
"%d after\n", "%d after\n",
e->name(), e->logicalInstruction->index, e->name(), e->logicalInstruction->index,
count(e->predecessors), count(e->successors), countPredecessors(e->predecessors),
countSuccessors(e->successors),
e->stackBefore ? e->stackBefore ?
e->stackBefore->index + e->stackBefore->size : 0, e->stackBefore->index + e->stackBefore->size : 0,
e->stackAfter ? e->stackAfter ?
@ -3237,26 +3333,23 @@ compile(Context* c)
e->logicalInstruction->machineOffset = a->offset(); e->logicalInstruction->machineOffset = a->offset();
} }
MyState* state = e->state;
if (state) {
for (unsigned i = 0; i < state->readCount; ++i) {
MultiReadPair* p = state->reads + i;
p->value->reads = p->read->nextTarget();
}
}
if (e->predecessors) { if (e->predecessors) {
Event* predecessor = static_cast<Event*>(e->predecessors->value); clean(c, lastPredecessor(e->predecessors));
if (e->predecessors->next) {
Event* first = e->predecessors->predecessor;
if (e->predecessors->nextPredecessor) {
fprintf(stderr, "ima junction\n"); fprintf(stderr, "ima junction\n");
for (Cell* cell = e->predecessors; cell->next; cell = cell->next) { for (Link* pl = e->predecessors;
updateJunctionReads(c, static_cast<Event*>(cell->value)); pl->nextPredecessor;
pl = pl->nextPredecessor)
{
updateJunctionReads(c, pl->junctionState);
} }
setSites(c, e, predecessor->junctionSites); setSites(c, e, first->junctionSites);
} else if (predecessor->successors->next) { } else if (first->successors->nextSuccessor) {
fprintf(stderr, "ima fork from %d\n", fprintf(stderr, "ima fork from %d\n",
predecessor->logicalInstruction->index); first->logicalInstruction->index);
setSites(c, e, predecessor->savedSites); setSites(c, e, first->savedSites);
} }
} }
@ -3273,7 +3366,9 @@ compile(Context* c)
populateSiteTables(c, e); populateSiteTables(c, e);
} }
e->compilePostsync(c); if (e->cleanLink) {
clean(c, e->cleanLink);
}
for (CodePromise* p = e->promises; p; p = p->next) { for (CodePromise* p = e->promises; p; p = p->next) {
p->offset = a->offset(); p->offset = a->offset();
@ -3316,7 +3411,7 @@ count(Stack* s)
} }
void void
allocateTargets(Context* c, MyState* state) allocateTargets(Context* c, ForkState* state)
{ {
for (unsigned i = 0; i < state->readCount; ++i) { for (unsigned i = 0; i < state->readCount; ++i) {
MultiReadPair* p = state->reads + i; MultiReadPair* p = state->reads + i;
@ -3326,13 +3421,14 @@ allocateTargets(Context* c, MyState* state)
} }
void void
addMultiRead(Context* c, Value* v, unsigned size, MyState* state, addMultiRead(Context* c, Value* v, unsigned size, ForkState* state,
unsigned* count) unsigned* count)
{ {
if (v and not v->visited) { if (v and not v->visited) {
v->visited = true; v->visited = true;
MultiRead* r = multiRead(c, size); MultiRead* r = multiRead(c, size);
fprintf(stderr, "add multi read %p to %p\n", r, v);
addRead(c, 0, v, r); addRead(c, 0, v, r);
MultiReadPair* p = state->reads + ((*count)++); MultiReadPair* p = state->reads + ((*count)++);
@ -3341,16 +3437,17 @@ addMultiRead(Context* c, Value* v, unsigned size, MyState* state,
} }
} }
MyState* ForkState*
saveState(Context* c) saveState(Context* c)
{ {
MyState* state = new ForkState* state = new
(c->zone->allocate (c->zone->allocate
(sizeof(MyState) + (sizeof(MultiReadPair) * frameFootprint(c, c->stack)))) (sizeof(ForkState)
MyState(c->stack, c->locals, c->predecessor, c->logicalIp); + (sizeof(MultiReadPair) * frameFootprint(c, c->stack))))
ForkState(c->stack, c->locals, c->predecessor, c->logicalIp);
if (c->predecessor) { if (c->predecessor) {
c->state = state; c->forkState = state;
unsigned count = 0; unsigned count = 0;
@ -3378,7 +3475,7 @@ saveState(Context* c)
} }
void void
restoreState(Context* c, MyState* s) restoreState(Context* c, ForkState* s)
{ {
if (c->logicalIp >= 0 and c->logicalCode[c->logicalIp]->lastEvent == 0) { if (c->logicalIp >= 0 and c->logicalCode[c->logicalIp]->lastEvent == 0) {
appendDummy(c); appendDummy(c);
@ -3390,7 +3487,7 @@ restoreState(Context* c, MyState* s)
c->logicalIp = s->logicalIp; c->logicalIp = s->logicalIp;
if (c->predecessor) { if (c->predecessor) {
c->state = s; c->forkState = s;
allocateTargets(c, s); allocateTargets(c, s);
} }
} }
@ -3438,7 +3535,7 @@ class MyCompiler: public Compiler {
} }
virtual void restoreState(State* state) { virtual void restoreState(State* state) {
::restoreState(&c, static_cast<MyState*>(state)); ::restoreState(&c, static_cast<ForkState*>(state));
} }
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
@ -3477,20 +3574,24 @@ class MyCompiler: public Compiler {
p->stackAfter = c.stack; p->stackAfter = c.stack;
p->localsAfter = c.locals; p->localsAfter = c.locals;
p->successors = cons(&c, e, p->successors); Link* link = ::link
populateJunctionReads(&c, p); (&c, p, e->predecessors, e, p->successors, c.forkState);
e->predecessors = cons(&c, p, e->predecessors); e->predecessors = link;
p->successors = link;
c.lastEvent->cleanLink = link;
fprintf(stderr, "populate junction reads for %d to %d\n",
p->logicalInstruction->index, logicalIp);
populateJunctionReads(&c, e->predecessors);
} }
c.forkState = false;
} }
virtual void startLogicalIp(unsigned logicalIp) { virtual void startLogicalIp(unsigned logicalIp) {
assert(&c, logicalIp < c.logicalCodeLength); assert(&c, logicalIp < c.logicalCodeLength);
assert(&c, c.logicalCode[logicalIp] == 0); assert(&c, c.logicalCode[logicalIp] == 0);
if (DebugAppend) {
fprintf(stderr, " -- ip: %d\n", logicalIp);
}
if (c.logicalIp >= 0 and c.logicalCode[c.logicalIp]->lastEvent == 0) { if (c.logicalIp >= 0 and c.logicalCode[c.logicalIp]->lastEvent == 0) {
appendDummy(&c); appendDummy(&c);
} }