mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
fix stack mapping bugs which broke GC
This commit is contained in:
parent
312539af64
commit
61539bae31
@ -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;
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
106
src/compiler.cpp
106
src/compiler.cpp
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user