From c22b4b4e79b63346fcb1acdc97504c7bebd6d92d Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 8 Jul 2009 08:18:40 -0600 Subject: [PATCH] various subroutine handling bugfixes --- src/compile.cpp | 41 ++++++++++++++++++++++++++++------------- src/compiler.cpp | 29 +++++++++++++++++------------ 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 9abb064273..88f6773175 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -528,6 +528,7 @@ class SubroutineCall { next(subroutine->calls) { subroutine->calls = this; + ++ subroutine->callCount; } Subroutine* subroutine; @@ -537,13 +538,16 @@ class SubroutineCall { class SubroutinePath { public: - SubroutinePath(SubroutineCall* call, SubroutinePath* next): + SubroutinePath(SubroutineCall* call, SubroutinePath* next, + uintptr_t* rootTable): call(call), - next(next) + next(next), + rootTable(rootTable) { } SubroutineCall* call; SubroutinePath* next; + uintptr_t* rootTable; }; class SubroutineTrace { @@ -1396,7 +1400,8 @@ class Frame { if (subroutine == 0) { context->subroutines = subroutine = new (context->zone.allocate(sizeof(Subroutine))) - Subroutine(ip, context->eventLog.length(), context->subroutines); + Subroutine(ip, context->eventLog.length() + 1 + BytesPerWord + 2, + context->subroutines); } subroutine->handle = c->startSubroutine(); @@ -1425,13 +1430,13 @@ class Frame { } void endSubroutine(unsigned nextIndexIndex) { - context->eventLog.set2(nextIndexIndex, context->eventLog.length()); - c->cleanLocals(); poppedInt(); context->eventLog.append(PopSubroutineEvent); + + context->eventLog.set2(nextIndexIndex, context->eventLog.length()); } Context* context; @@ -3608,7 +3613,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, c->jmp(frame->machineIp(newIp)); - compile(t, frame, newIp); + saveStateAndCompile(t, frame, newIp); if (UNLIKELY(t->exception)) return; frame->endSubroutine(start); @@ -4097,6 +4102,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip, case ret: { unsigned index = codeBody(t, code, ip); + c->saveLocals(); c->jmp(loadLocal(context, 1, index)); frame->returnFromSubroutine(index); } return; @@ -4376,7 +4382,8 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, Event e = static_cast(context->eventLog.get(eventIndex++)); switch (e) { case PushContextEvent: { - eventIndex = calculateFrameMaps(t, context, roots, eventIndex); + eventIndex = calculateFrameMaps + (t, context, roots, eventIndex, subroutinePath); } break; case PopContextEvent: @@ -4392,7 +4399,9 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, fprintf(stderr, "\n"); } - uintptr_t* tableRoots = context->rootTable + (ip * mapSize); + uintptr_t* tableRoots + = (subroutinePath ? subroutinePath->rootTable : context->rootTable) + + (ip * mapSize); if (context->visitTable[ip] > 1) { for (unsigned wi = 0; wi < mapSize; ++wi) { @@ -4463,13 +4472,16 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots, SubroutineCall* call; context->eventLog.get(eventIndex, &call, BytesPerWord); eventIndex += BytesPerWord; + unsigned nextIndex = context->eventLog.get2(eventIndex); + eventIndex = nextIndex; calculateFrameMaps (t, context, roots, call->subroutine->logIndex, new (context->zone.allocate(sizeof(SubroutinePath))) - SubroutinePath(call, subroutinePath)); + SubroutinePath(call, subroutinePath, + makeRootTable(t, &(context->zone), context->method))); } break; case PopSubroutineEvent: @@ -4542,7 +4554,8 @@ print(SubroutinePath* path) if (path) { fprintf(stderr, " ("); while (true) { - fprintf(stderr, "%"LLD"", path->call->returnAddress->value()); + fprintf(stderr, "%p", reinterpret_cast + (path->call->returnAddress->value())); path = path->next; if (path) { fprintf(stderr, ", "); @@ -4653,7 +4666,7 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start, FrameMapTablePath* previous = 0; Subroutine* subroutine = p->subroutineTrace->path->call->subroutine; for (Subroutine* s = subroutine; s; s = s->next) { - if (s->tableIndex != 0) { + if (s->tableIndex == 0) { unsigned pathObjectSize = sizeof(FrameMapTablePath) + (sizeof(int32_t) * s->callCount); @@ -4672,7 +4685,7 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start, for (SubroutineCall* c = subroutine->calls; c; c = c->next) { assert(t, i < s->callCount); - current->elements[i] + current->elements[i++] = static_cast(c->returnAddress->value()) - reinterpret_cast(start); } @@ -5475,7 +5488,9 @@ findFrameMapInGeneralTable(MyThread* t, void* stack, object method, FrameMapTableIndexElement* v = index + middle; if (offset == v->offset) { - *start = v->base + findFrameMap(t, stack, method, table, v->path); + *start = v->base + (findFrameMap(t, stack, method, table, v->path) + * frameMapSizeInWords(t, method)); + return; } else if (offset < v->offset) { top = middle; } else { diff --git a/src/compiler.cpp b/src/compiler.cpp index e987177b1f..59bf9368ee 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -2052,7 +2052,7 @@ class MultiRead: public Read { } lastRead = cell; - // fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); +// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); lastTarget->value = r; } @@ -2064,7 +2064,7 @@ class MultiRead: public Read { void allocateTarget(Context* c) { Cell* cell = cons(c, 0, 0); - // fprintf(stderr, "allocate target for %p: %p\n", this, cell); +// fprintf(stderr, "allocate target for %p: %p\n", this, cell); if (lastTarget) { lastTarget->next = cell; @@ -4952,15 +4952,9 @@ class MyCompiler: public Compiler { } virtual void endSubroutine(Subroutine* subroutine) { - saveLocals(); - static_cast(subroutine)->forkState = ::saveState(&c); } - virtual void restoreFromSubroutine(Subroutine* subroutine) { - ::restoreState(&c, static_cast(subroutine)->forkState); - } - virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, unsigned localFootprint, unsigned alignedFrameSize) { @@ -5059,10 +5053,23 @@ class MyCompiler: public Compiler { (c.zone->allocate(sizeof(LogicalInstruction))) LogicalInstruction(logicalIp, c.stack, c.locals); - if (c.subroutine) { + bool startSubroutine = c.subroutine != 0; + if (startSubroutine) { c.logicalCode[logicalIp]->subroutine = c.subroutine; c.subroutine = 0; - + } + + c.logicalIp = logicalIp; + + if (startSubroutine) { + // assume all local variables are initialized on entry to a + // subroutine, since other calls to the subroutine may + // initialize them: + unsigned sizeInBytes = sizeof(Local) * c.localFootprint; + Local* newLocals = static_cast(c.zone->allocate(sizeInBytes)); + memcpy(newLocals, c.locals, sizeInBytes); + c.locals = newLocals; + for (unsigned li = 0; li < c.localFootprint; ++li) { Local* local = c.locals + li; if (local->value == 0) { @@ -5070,8 +5077,6 @@ class MyCompiler: public Compiler { } } } - - c.logicalIp = logicalIp; } virtual Promise* machineIp(unsigned logicalIp) {