fix frame map calculations involving exception handlers

This commit is contained in:
Joel Dice 2008-01-20 16:03:28 -07:00
parent 422133d1ba
commit c9714c73f2

View File

@ -3499,13 +3499,23 @@ printSet(uintptr_t m)
} }
unsigned unsigned
calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots, calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned ei) unsigned eventIndex)
{ {
// for each instruction with more than one predecessor, and for each
// stack position, determine if there exists a path to that
// instruction such that there is not an object pointer left at that
// stack position (i.e. it is uninitialized or contains primitive
// data).
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); if (originalRoots) {
memcpy(roots, originalRoots, mapSize * BytesPerWord);
} else {
memset(roots, 0, mapSize * BytesPerWord);
}
int32_t ip = -1; int32_t ip = -1;
@ -3517,18 +3527,18 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
// that position, or the contents of that position are as yet // that position, or the contents of that position are as yet
// unknown. // unknown.
while (ei < context->eventLog.length()) { while (eventIndex < context->eventLog.length()) {
Event e = static_cast<Event>(context->eventLog.get(ei++)); Event e = static_cast<Event>(context->eventLog.get(eventIndex++));
switch (e) { switch (e) {
case PushEvent: { case PushEvent: {
ei = calculateJunctions(t, context, roots, ei); eventIndex = calculateFrameMaps(t, context, roots, eventIndex);
} break; } break;
case PopEvent: case PopEvent:
return ei; return eventIndex;
case IpEvent: { case IpEvent: {
ip = context->eventLog.get2(ei); ip = context->eventLog.get2(eventIndex);
if (DebugFrameMaps) { if (DebugFrameMaps) {
fprintf(stderr, " roots at ip %3d: ", ip); fprintf(stderr, " roots at ip %3d: ", ip);
@ -3536,9 +3546,9 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
if (context->visitTable[ip] > 1) { uintptr_t* tableRoots = context->rootTable + (ip * mapSize);
uintptr_t* tableRoots = context->rootTable + (ip * mapSize);
if (context->visitTable[ip] > 1) {
for (unsigned wi = 0; wi < mapSize; ++wi) { for (unsigned wi = 0; wi < mapSize; ++wi) {
tableRoots[wi] &= roots[wi]; tableRoots[wi] &= roots[wi];
roots[wi] &= tableRoots[wi]; roots[wi] &= tableRoots[wi];
@ -3549,59 +3559,65 @@ calculateJunctions(MyThread* t, Context* context, uintptr_t* originalRoots,
printSet(*tableRoots); printSet(*tableRoots);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} else {
memcpy(tableRoots, roots, mapSize * BytesPerWord);
} }
ei += 2; eventIndex += 2;
} break; } break;
case MarkEvent: { case MarkEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(eventIndex);
markBit(roots, i); markBit(roots, i);
ei += 2; eventIndex += 2;
} break; } break;
case ClearEvent: { case ClearEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(eventIndex);
clearBit(roots, i); clearBit(roots, i);
ei += 2; eventIndex += 2;
} break; } break;
case TraceEvent: { case TraceEvent: {
ei += BytesPerWord; eventIndex += BytesPerWord;
} break; } break;
default: abort(t); default: abort(t);
} }
} }
return ei; return eventIndex;
} }
unsigned unsigned
updateTraceElements(MyThread* t, Context* context, uintptr_t* originalRoots, updateTraceElements(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned ei) unsigned eventIndex)
{ {
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); if (originalRoots) {
memcpy(roots, originalRoots, mapSize * BytesPerWord);
} else {
memset(roots, 0, mapSize * BytesPerWord);
}
int32_t ip = -1; int32_t ip = -1;
while (ei < context->eventLog.length()) { while (eventIndex < context->eventLog.length()) {
Event e = static_cast<Event>(context->eventLog.get(ei++)); Event e = static_cast<Event>(context->eventLog.get(eventIndex++));
switch (e) { switch (e) {
case PushEvent: { case PushEvent: {
ei = updateTraceElements(t, context, roots, ei); eventIndex = updateTraceElements(t, context, roots, eventIndex);
} break; } break;
case PopEvent: case PopEvent:
return ei; return eventIndex;
case IpEvent: { case IpEvent: {
ip = context->eventLog.get2(ei); ip = context->eventLog.get2(eventIndex);
if (DebugFrameMaps) { if (DebugFrameMaps) {
fprintf(stderr, " map at ip %3d: ", ip); fprintf(stderr, " map at ip %3d: ", ip);
@ -3617,54 +3633,35 @@ updateTraceElements(MyThread* t, Context* context, uintptr_t* originalRoots,
} }
} }
ei += 2; eventIndex += 2;
} break; } break;
case MarkEvent: { case MarkEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(eventIndex);
markBit(roots, i); markBit(roots, i);
ei += 2; eventIndex += 2;
} break; } break;
case ClearEvent: { case ClearEvent: {
unsigned i = context->eventLog.get2(ei); unsigned i = context->eventLog.get2(eventIndex);
clearBit(roots, i); clearBit(roots, i);
ei += 2; eventIndex += 2;
} break; } break;
case TraceEvent: { case TraceEvent: {
TraceElement* te; context->eventLog.get(ei, &te, BytesPerWord); TraceElement* te; context->eventLog.get(eventIndex, &te, BytesPerWord);
memcpy(te->map, roots, mapSize * BytesPerWord); memcpy(te->map, roots, mapSize * BytesPerWord);
ei += BytesPerWord; eventIndex += BytesPerWord;
} break; } break;
default: abort(t); default: abort(t);
} }
} }
return ei; return eventIndex;
}
void
calculateFrameMaps(MyThread* t, Context* context)
{
unsigned mapSize = frameMapSizeInWords(t, context->method);
uintptr_t roots[mapSize];
memset(roots, 0, mapSize * BytesPerWord);
// first pass: for each instruction with more than one predecessor,
// and for each stack position, determine if there exists a path to
// that instruction such that there is not an object pointer left at
// that stack position (i.e. it is uninitialized or contains
// primitive data).
calculateJunctions(t, context, roots, 0);
// second pass: update trace elements.
updateTraceElements(t, context, roots, 0);
} }
Allocator* Allocator*
@ -3804,7 +3801,7 @@ compile(MyThread* t, Context* context)
compile(t, &frame, 0); compile(t, &frame, 0);
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
calculateFrameMaps(t, context); unsigned eventIndex = calculateFrameMaps(t, context, 0, 0);
object eht = codeExceptionHandlerTable(t, methodCode(t, context->method)); object eht = codeExceptionHandlerTable(t, methodCode(t, context->method));
if (eht) { if (eht) {
@ -3818,7 +3815,6 @@ compile(MyThread* t, Context* context)
uintptr_t stackMap[stackMapSizeInWords(t, context->method)]; uintptr_t stackMap[stackMapSizeInWords(t, context->method)];
Frame frame2(&frame, stackMap); Frame frame2(&frame, stackMap);
frame2.pushObject();
uintptr_t* roots = context->rootTable uintptr_t* roots = context->rootTable
+ (start * frameMapSizeInWords(t, context->method)); + (start * frameMapSizeInWords(t, context->method));
@ -3826,16 +3822,29 @@ compile(MyThread* t, Context* context)
for (unsigned i = 0; i < localSize(t, context->method); ++ i) { for (unsigned i = 0; i < localSize(t, context->method); ++ i) {
if (getBit(roots, i)) { if (getBit(roots, i)) {
frame2.mark(i); frame2.mark(i);
} else {
frame2.clear(i);
} }
} }
frame2.pushObject();
for (unsigned i = 1;
i < codeMaxStack(t, methodCode(t, context->method));
++i)
{
frame2.clear(localSize(t, context->method) + i);
}
compile(t, &frame2, exceptionHandlerIp(eh)); compile(t, &frame2, exceptionHandlerIp(eh));
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
calculateFrameMaps(t, context); eventIndex = calculateFrameMaps(t, context, 0, eventIndex);
} }
} }
updateTraceElements(t, context, 0, 0);
return finish(t, context, 0); return finish(t, context, 0);
} }