mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
minimize state tracked by stack mapping algorithm
This commit is contained in:
parent
ef06be3904
commit
c8472c4d30
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user