minimize state tracked by stack mapping algorithm

This commit is contained in:
Joel Dice 2008-01-08 08:24:57 -07:00
parent ef06be3904
commit c8472c4d30

View File

@ -401,13 +401,13 @@ makeVisitTable(MyThread* t, Zone* zone, object method)
} }
uintptr_t* uintptr_t*
makeFrameMapTable(MyThread* t, Zone* zone, object method) makeRootTable(MyThread* t, Zone* zone, object method)
{ {
unsigned size = frameMapSizeInWords(t, method) unsigned size = frameMapSizeInWords(t, method)
* codeLength(t, methodCode(t, method)) * codeLength(t, methodCode(t, method))
* BytesPerWord; * BytesPerWord;
uintptr_t* table = static_cast<uintptr_t*>(zone->allocate(size)); uintptr_t* table = static_cast<uintptr_t*>(zone->allocate(size));
memset(table, 0, size); memset(table, 0xFF, size);
return table; return table;
} }
@ -440,8 +440,7 @@ class Context {
objectPool(0), objectPool(0),
traceLog(0), traceLog(0),
visitTable(makeVisitTable(t, &zone, method)), visitTable(makeVisitTable(t, &zone, method)),
rootTable(makeFrameMapTable(t, &zone, method)), rootTable(makeRootTable(t, &zone, method)),
knownTable(makeFrameMapTable(t, &zone, method)),
eventLog(t->m->system, 1024), eventLog(t->m->system, 1024),
protector(this) protector(this)
{ } { }
@ -455,7 +454,6 @@ class Context {
traceLog(0), traceLog(0),
visitTable(0), visitTable(0),
rootTable(0), rootTable(0),
knownTable(0),
eventLog(t->m->system, 0), eventLog(t->m->system, 0),
protector(this) protector(this)
{ } { }
@ -472,7 +470,6 @@ class Context {
TraceElement* traceLog; TraceElement* traceLog;
uint16_t* visitTable; uint16_t* visitTable;
uintptr_t* rootTable; uintptr_t* rootTable;
uintptr_t* knownTable;
Vector eventLog; Vector eventLog;
MyProtector protector; MyProtector protector;
}; };
@ -3465,23 +3462,20 @@ printSet(uintptr_t m)
unsigned unsigned
calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots, calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
uintptr_t* originalKnown, unsigned ei) unsigned ei)
{ {
unsigned mapSize = frameMapSizeInWords(t, context->method); unsigned mapSize = frameMapSizeInWords(t, context->method);
uintptr_t roots[mapSize]; uintptr_t roots[mapSize];
memcpy(roots, originalRoots, mapSize * BytesPerWord); memcpy(roots, originalRoots, mapSize * BytesPerWord);
uintptr_t known[mapSize];
memcpy(known, originalKnown, mapSize * BytesPerWord);
int32_t ip = -1; int32_t ip = -1;
while (ei < context->eventLog.length()) { while (ei < context->eventLog.length()) {
Event e = static_cast<Event>(context->eventLog.get(ei++)); Event e = static_cast<Event>(context->eventLog.get(ei++));
switch (e) { switch (e) {
case PushEvent: { case PushEvent: {
ei = calculateJunctions(t, context, roots, known, ei); ei = calculateJunctions(t, context, roots, ei);
} break; } break;
case PopEvent: case PopEvent:
@ -3494,33 +3488,20 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
fprintf(stderr, " roots at ip %3d: ", ip); fprintf(stderr, " roots at ip %3d: ", ip);
printSet(*roots); printSet(*roots);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, " known at ip %3d: ", ip);
printSet(*known);
fprintf(stderr, "\n");
} }
if (context->visitTable[ip] > 1) { if (context->visitTable[ip] > 1) {
uintptr_t* tableRoots = context->rootTable + (ip * mapSize); uintptr_t* tableRoots = context->rootTable + (ip * mapSize);
uintptr_t* tableKnown = context->knownTable + (ip * mapSize);
for (unsigned wi = 0; wi < mapSize; ++wi) { for (unsigned wi = 0; wi < mapSize; ++wi) {
tableRoots[wi] &= ~(known[wi] & ~roots[wi]); tableRoots[wi] &= roots[wi];
tableRoots[wi] |= known[wi] & roots[wi] & ~tableKnown[wi]; roots[wi] &= tableRoots[wi];
tableKnown[wi] |= known[wi];
roots[wi] = 0;
known[wi] = tableKnown[wi] & ~tableRoots[wi];
} }
if (DebugFrameMaps) { if (DebugFrameMaps) {
fprintf(stderr, "table roots at ip %3d: ", ip); fprintf(stderr, "table roots at ip %3d: ", ip);
printSet(*tableRoots); printSet(*tableRoots);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "table known at ip %3d: ", ip);
printSet(*tableKnown);
fprintf(stderr, "\n");
} }
} }
@ -3530,7 +3511,6 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
case MarkEvent: { case MarkEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(ei);
markBit(roots, i); markBit(roots, i);
markBit(known, i);
ei += 2; ei += 2;
} break; } break;
@ -3538,7 +3518,6 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
case ClearEvent: { case ClearEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(ei);
clearBit(roots, i); clearBit(roots, i);
markBit(known, i);
ei += 2; ei += 2;
} break; } break;
@ -3586,10 +3565,9 @@ updateTraceElements(MyThread* t, Context* context, uintptr_t* originalRoots,
if (context->visitTable[ip] > 1) { if (context->visitTable[ip] > 1) {
uintptr_t* tableRoots = context->rootTable + (ip * mapSize); uintptr_t* tableRoots = context->rootTable + (ip * mapSize);
uintptr_t* tableKnown = context->knownTable + (ip * mapSize);
for (unsigned wi = 0; wi < mapSize; ++wi) { for (unsigned wi = 0; wi < mapSize; ++wi) {
roots[wi] &= ~(tableKnown[wi] & ~tableRoots[wi]); roots[wi] &= tableRoots[wi];
} }
} }
@ -3632,12 +3610,9 @@ calculateFrameMaps(MyThread* t, Context* context)
uintptr_t roots[mapSize]; uintptr_t roots[mapSize];
memset(roots, 0, mapSize * BytesPerWord); memset(roots, 0, mapSize * BytesPerWord);
uintptr_t known[mapSize];
memset(known, 0xFF, mapSize * BytesPerWord);
// first pass: calculate reachable roots at instructions with more // first pass: calculate reachable roots at instructions with more
// than one predecessor. // than one predecessor.
calculateJunctions(t, context, roots, known, 0); calculateJunctions(t, context, roots, 0);
// second pass: update trace elements. // second pass: update trace elements.
updateTraceElements(t, context, roots, 0); updateTraceElements(t, context, roots, 0);