fix stack mapping bugs which broke GC

This commit is contained in:
Joel Dice 2008-11-08 15:36:38 -07:00
parent 312539af64
commit 61539bae31
4 changed files with 87 additions and 40 deletions

View File

@ -187,6 +187,7 @@ class Assembler {
virtual void* frameIp(void* stack) = 0; virtual void* frameIp(void* stack) = 0;
virtual unsigned frameHeaderSize() = 0; virtual unsigned frameHeaderSize() = 0;
virtual unsigned frameReturnAddressSize() = 0;
virtual unsigned frameFooterSize() = 0; virtual unsigned frameFooterSize() = 0;
virtual void nextFrame(void** stack, void** base) = 0; virtual void nextFrame(void** stack, void** base) = 0;
virtual void* popReturnAddress(void* stack) = 0; virtual void* popReturnAddress(void* stack) = 0;

View File

@ -31,7 +31,7 @@ const bool Verbose = true;
const bool DebugNatives = false; const bool DebugNatives = false;
const bool DebugCallTable = false; const bool DebugCallTable = false;
const bool DebugMethodTree = false; const bool DebugMethodTree = false;
const bool DebugFrameMaps = true; const bool DebugFrameMaps = false;
const bool CheckArrayBounds = true; const bool CheckArrayBounds = true;
@ -376,7 +376,9 @@ inline object*
localObject(MyThread* t, void* stack, object method, unsigned index) localObject(MyThread* t, void* stack, object method, unsigned index)
{ {
return reinterpret_cast<object*> return reinterpret_cast<object*>
(static_cast<uint8_t*>(stack) + localOffset(t, index, method)); (static_cast<uint8_t*>(stack)
+ localOffset(t, index, method)
+ (t->arch->frameReturnAddressSize() * BytesPerWord));
} }
class PoolElement { class PoolElement {
@ -1192,7 +1194,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
lock = methodClass(t, method); lock = methodClass(t, method);
} else { } else {
lock = *localObject(t, base, method, savedTargetIndex(t, method)); lock = *localObject(t, stack, method, savedTargetIndex(t, method));
} }
release(t, lock); release(t, lock);
@ -3664,7 +3666,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned i = context->eventLog.get2(eventIndex); unsigned i = context->eventLog.get2(eventIndex);
eventIndex += 2; eventIndex += 2;
if (i > localSize) { if (i >= localSize) {
i += stackPadding; i += stackPadding;
} }
@ -3675,7 +3677,7 @@ calculateFrameMaps(MyThread* t, Context* context, uintptr_t* originalRoots,
unsigned i = context->eventLog.get2(eventIndex); unsigned i = context->eventLog.get2(eventIndex);
eventIndex += 2; eventIndex += 2;
if (i > localSize) { if (i >= localSize) {
i += stackPadding; i += stackPadding;
} }
@ -3862,11 +3864,11 @@ finish(MyThread* t, Context* context)
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)),
"Simple") == 0 and "GC") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),
"size") == 0) "main") == 0)
{ {
asm("int3"); asm("int3");
} }

View File

@ -2207,6 +2207,17 @@ 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
setPadding(Context* c, Stack* s, unsigned realIndex)
{
unsigned logicalIndex = frameIndex
(c, s->index + c->localFootprint, s->footprint);
assert(c, logicalIndex >= realIndex);
s->paddingInWords = logicalIndex - realIndex;
}
void void
append(Context* c, Event* e); append(Context* c, Event* e);
@ -2228,29 +2239,38 @@ class CallEvent: public Event {
Stack* s = argumentStack; Stack* s = argumentStack;
unsigned index = 0; unsigned index = 0;
unsigned frameIndex = 0; unsigned frameIndex = 0;
for (unsigned i = 0; i < argumentCount; ++i) {
Read* target; if (argumentCount) {
if (index < c->arch->argumentRegisterCount()) { unsigned ai = 0;
int r = c->arch->argumentRegister(index); while (true) {
Read* target;
if (index < c->arch->argumentRegisterCount()) {
int r = c->arch->argumentRegister(index);
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "reg %d arg read %p\n", r, s->value); fprintf(stderr, "reg %d arg read %p\n", r, s->value);
} }
target = fixedRegisterRead(c, footprintSizeInBytes(s->footprint), r); target = fixedRegisterRead(c, footprintSizeInBytes(s->footprint), r);
mask &= ~(1 << r); mask &= ~(1 << r);
} else { } else {
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "stack %d arg read %p\n", frameIndex, s->value); fprintf(stderr, "stack %d arg read %p\n", frameIndex, s->value);
} }
target = read(c, footprintSizeInBytes(s->footprint), target = read(c, footprintSizeInBytes(s->footprint),
1 << MemoryOperand, 0, frameIndex); 1 << MemoryOperand, 0, frameIndex);
frameIndex += s->footprint; frameIndex += s->footprint;
}
addRead(c, this, s->value, target);
index += s->footprint;
if ((++ ai) < argumentCount) {
s = s->next;
} else {
break;
}
} }
addRead(c, this, s->value, target);
index += s->footprint;
s = s->next;
} }
if (DebugReads) { if (DebugReads) {
@ -2262,40 +2282,60 @@ class CallEvent: public Event {
AnyFrameIndex)); AnyFrameIndex));
int footprint = stackArgumentFootprint; int footprint = stackArgumentFootprint;
if (footprint == 0 and s) {
setPadding(c, s, frameIndex);
}
for (Stack* s = stackBefore; s; s = s->next) { for (Stack* s = stackBefore; s; s = s->next) {
if (footprint > 0) { if (footprint > 0) {
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "stack arg read %p of footprint %d at %d of %d\n", s->value, s->footprint, frameIndex, c->alignedFrameSize + c->parameterFootprint); fprintf(stderr, "stack arg read %p of footprint %d at %d of %d\n",
s->value, s->footprint, frameIndex,
c->alignedFrameSize + c->parameterFootprint);
} }
addRead(c, this, s->value, read addRead(c, this, s->value, read
(c, footprintSizeInBytes(s->footprint), (c, footprintSizeInBytes(s->footprint),
1 << MemoryOperand, 0, frameIndex)); 1 << MemoryOperand, 0, frameIndex));
} else { } else {
unsigned index = ::frameIndex
(c, s->index + c->localFootprint, s->footprint);
if (footprint == 0) { if (footprint == 0) {
assert(c, index >= frameIndex); popIndex = frameIndex;
s->paddingInWords = index - frameIndex;
popIndex = index;
} }
unsigned index = ::frameIndex
(c, s->index + c->localFootprint, s->footprint);
if (DebugReads) { if (DebugReads) {
fprintf(stderr, "stack save read %p of footprint %d at %d of %d\n", s->value, s->footprint, index, c->alignedFrameSize + c->parameterFootprint); fprintf(stderr, "stack save read %p of footprint %d at %d of %d\n",
s->value, s->footprint, index,
c->alignedFrameSize + c->parameterFootprint);
} }
addRead(c, this, s->value, read addRead(c, this, s->value, read
(c, footprintSizeInBytes(s->footprint), 1 << MemoryOperand, 0, (c, footprintSizeInBytes(s->footprint), 1 << MemoryOperand,
index)); 0, index));
} }
frameIndex += s->footprint;
footprint -= s->footprint; footprint -= s->footprint;
if (footprint == 0) {
setPadding(c, s, frameIndex);
}
frameIndex += s->footprint;
} }
for (unsigned li = 0; li < c->localFootprint; ++li) { for (unsigned li = 0; li < c->localFootprint; ++li) {
Local* local = localsBefore + li; Local* local = localsBefore + li;
if (local->value) { if (local->value) {
fprintf(stderr, "local save read %p of footprint %d at %d of %d\n", local->value, local->footprint, ::frameIndex(c, li, local->footprint), c->alignedFrameSize + c->parameterFootprint); if (DebugReads) {
fprintf(stderr, "local save read %p of footprint %d at %d of %d\n",
local->value, local->footprint,
::frameIndex(c, li, local->footprint),
c->alignedFrameSize + c->parameterFootprint);
}
addRead(c, this, local->value, read addRead(c, this, local->value, read
(c, footprintSizeInBytes(local->footprint), 1 << MemoryOperand, (c, footprintSizeInBytes(local->footprint), 1 << MemoryOperand,
0, ::frameIndex(c, li, local->footprint))); 0, ::frameIndex(c, li, local->footprint)));
@ -3988,8 +4028,8 @@ class MyCompiler: public Compiler {
Event* p = c.predecessor; Event* p = c.predecessor;
if (p) { if (p) {
fprintf(stderr, "visit %d pred %d\n", logicalIp, // fprintf(stderr, "visit %d pred %d\n", logicalIp,
p->logicalInstruction->index); // p->logicalInstruction->index);
p->stackAfter = c.stack; p->stackAfter = c.stack;
p->localsAfter = c.locals; p->localsAfter = c.locals;

View File

@ -1958,6 +1958,10 @@ class MyArchitecture: public Assembler::Architecture {
return FrameHeaderSize; return FrameHeaderSize;
} }
virtual unsigned frameReturnAddressSize() {
return 1;
}
virtual unsigned frameFooterSize() { virtual unsigned frameFooterSize() {
return 0; return 0;
} }