mirror of
https://github.com/corda/corda.git
synced 2025-01-22 12:28:11 +00:00
fix various stack bugs
This commit is contained in:
parent
565ece136b
commit
1c3504b62a
@ -898,8 +898,9 @@ class Frame {
|
|||||||
|
|
||||||
for (unsigned i = count; i;) {
|
for (unsigned i = count; i;) {
|
||||||
Compiler::StackElement* s = c->top();
|
Compiler::StackElement* s = c->top();
|
||||||
c->popped();
|
unsigned footprint = c->footprint(s);
|
||||||
i -= c->footprint(s);
|
c->popped(footprint);
|
||||||
|
i -= footprint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
src/compiler.cpp
125
src/compiler.cpp
@ -15,12 +15,12 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool DebugAppend = false;
|
const bool DebugAppend = true;
|
||||||
const bool DebugCompile = true;
|
const bool DebugCompile = true;
|
||||||
const bool DebugResources = true;
|
const bool DebugResources = true;
|
||||||
const bool DebugFrame = false;
|
const bool DebugFrame = true;
|
||||||
const bool DebugControl = true;
|
const bool DebugControl = true;
|
||||||
const bool DebugReads = false;
|
const bool DebugReads = true;
|
||||||
const bool DebugSites = false;
|
const bool DebugSites = false;
|
||||||
const bool DebugMoves = true;
|
const bool DebugMoves = true;
|
||||||
const bool DebugBuddies = false;
|
const bool DebugBuddies = false;
|
||||||
@ -683,6 +683,8 @@ class FrameIterator {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool hasMore() {
|
bool hasMore() {
|
||||||
|
while (stack and stack->value == 0) stack = stack->next;
|
||||||
|
|
||||||
while (localIndex >= 0 and locals[localIndex].value == 0) -- localIndex;
|
while (localIndex >= 0 and locals[localIndex].value == 0) -- localIndex;
|
||||||
|
|
||||||
return stack != 0 or localIndex >= 0;
|
return stack != 0 or localIndex >= 0;
|
||||||
@ -1507,7 +1509,7 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decrement(c, c->registerResources + base);
|
decrement(c, c->registerResources + base);
|
||||||
if (index) {
|
if (index != NoRegister) {
|
||||||
decrement(c, c->registerResources + index);
|
decrement(c, c->registerResources + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2148,26 +2150,29 @@ class CallEvent: public Event {
|
|||||||
|
|
||||||
int footprint = stackArgumentFootprint;
|
int footprint = stackArgumentFootprint;
|
||||||
for (Stack* s = stackBefore; s; s = s->next) {
|
for (Stack* s = stackBefore; s; s = s->next) {
|
||||||
if (footprint > 0) {
|
if (s->value) {
|
||||||
if (DebugReads) {
|
if (footprint > 0) {
|
||||||
fprintf(stderr, "stack arg read %p at %d of %d\n",
|
if (DebugReads) {
|
||||||
s->value, frameIndex,
|
fprintf(stderr, "stack arg read %p at %d of %d\n",
|
||||||
c->alignedFrameSize + c->parameterFootprint);
|
s->value, frameIndex,
|
||||||
|
c->alignedFrameSize + c->parameterFootprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
addRead(c, this, s->value, read
|
||||||
|
(c, SiteMask(1 << MemoryOperand, 0, frameIndex)));
|
||||||
|
} else {
|
||||||
|
unsigned logicalIndex = ::frameIndex
|
||||||
|
(c, s->index + c->localFootprint);
|
||||||
|
|
||||||
|
if (DebugReads) {
|
||||||
|
fprintf(stderr, "stack save read %p at %d of %d\n",
|
||||||
|
s->value, logicalIndex,
|
||||||
|
c->alignedFrameSize + c->parameterFootprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
addRead(c, this, s->value, read
|
||||||
|
(c, SiteMask(1 << MemoryOperand, 0, logicalIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
addRead(c, this, s->value, read
|
|
||||||
(c, SiteMask(1 << MemoryOperand, 0, frameIndex)));
|
|
||||||
} else {
|
|
||||||
unsigned logicalIndex = ::frameIndex(c, s->index + c->localFootprint);
|
|
||||||
|
|
||||||
if (DebugReads) {
|
|
||||||
fprintf(stderr, "stack save read %p at %d of %d\n",
|
|
||||||
s->value, logicalIndex,
|
|
||||||
c->alignedFrameSize + c->parameterFootprint);
|
|
||||||
}
|
|
||||||
|
|
||||||
addRead(c, this, s->value, read
|
|
||||||
(c, SiteMask(1 << MemoryOperand, 0, logicalIndex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- footprint;
|
-- footprint;
|
||||||
@ -2184,8 +2189,12 @@ class CallEvent: public Event {
|
|||||||
++ frameIndex;
|
++ frameIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%d %d\n",
|
||||||
|
stackBefore ? stackBefore->index + 1 - stackArgumentFootprint : 0,
|
||||||
|
c->localFootprint);
|
||||||
|
|
||||||
popIndex = ::frameIndex
|
popIndex = ::frameIndex
|
||||||
(c, (stackBefore ? stackBefore->index + 1 - stackArgumentFootprint : 0)
|
(c, (stackBefore ? stackBefore->index - stackArgumentFootprint : 0)
|
||||||
+ c->localFootprint);
|
+ c->localFootprint);
|
||||||
|
|
||||||
saveLocals(c, this);
|
saveLocals(c, this);
|
||||||
@ -2776,17 +2785,11 @@ makeSnapshots(Context* c, Value* value, Snapshot* next)
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack*
|
|
||||||
stack(Context* c, Value* value, unsigned index, Stack* next)
|
|
||||||
{
|
|
||||||
return new (c->zone->allocate(sizeof(Stack)))
|
|
||||||
Stack(index, value, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack*
|
Stack*
|
||||||
stack(Context* c, Value* value, Stack* next)
|
stack(Context* c, Value* value, Stack* next)
|
||||||
{
|
{
|
||||||
return stack(c, value, (next ? next->index + 1 : 0), next);
|
return new (c->zone->allocate(sizeof(Stack)))
|
||||||
|
Stack(next ? next->index + 1 : 0, value, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
@ -2797,19 +2800,25 @@ push(Context* c, unsigned footprint, Value* v)
|
|||||||
{
|
{
|
||||||
assert(c, footprint);
|
assert(c, footprint);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
|
assert(c, (BytesPerWord == 8) xor (v->high != 0));
|
||||||
push(c, 1, v->high);
|
push(c, 1, v->high);
|
||||||
}
|
}
|
||||||
|
|
||||||
v = maybeBuddy(c, v);
|
if (v) {
|
||||||
|
v = maybeBuddy(c, v);
|
||||||
if (DebugFrame) {
|
|
||||||
fprintf(stderr, "push %p of footprint %d\n", v, footprint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack* s = stack(c, v, footprint, c->stack);
|
Stack* s = stack(c, v, c->stack);
|
||||||
v->home = frameIndex(c, s->index + c->localFootprint);
|
|
||||||
|
if (DebugFrame) {
|
||||||
|
fprintf(stderr, "push %p\n", v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
v->home = frameIndex(c, s->index + c->localFootprint);
|
||||||
|
}
|
||||||
c->stack = s;
|
c->stack = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2819,17 +2828,19 @@ pop(Context* c, unsigned footprint)
|
|||||||
assert(c, footprint);
|
assert(c, footprint);
|
||||||
|
|
||||||
Stack* s = c->stack;
|
Stack* s = c->stack;
|
||||||
assert(c, s->value->home >= 0);
|
assert(c, s->value == 0 or s->value->home >= 0);
|
||||||
|
|
||||||
if (DebugFrame) {
|
if (DebugFrame) {
|
||||||
fprintf(stderr, "pop %p of footprint %d\n", s->value, footprint);
|
fprintf(stderr, "pop %p\n", s->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->stack = s->next;
|
c->stack = s->next;
|
||||||
|
|
||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
assert(c, s->value->high);
|
assert(c, s->value->high == s->next->value
|
||||||
|
and ((BytesPerWord == 8) xor (s->value->high != 0)));
|
||||||
|
|
||||||
pop(c, 1);
|
pop(c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3168,6 +3179,7 @@ class BoundsCheckEvent: public Event {
|
|||||||
assert(c, object->source->type(c) == RegisterOperand);
|
assert(c, object->source->type(c) == RegisterOperand);
|
||||||
MemorySite length(static_cast<RegisterSite*>(object->source)->number,
|
MemorySite length(static_cast<RegisterSite*>(object->source)->number,
|
||||||
lengthOffset, NoRegister, 1);
|
lengthOffset, NoRegister, 1);
|
||||||
|
length.acquired = true;
|
||||||
|
|
||||||
apply(c, Compare, 4, index->source, 0, 4, &length, 0);
|
apply(c, Compare, 4, index->source, 0, 4, &length, 0);
|
||||||
|
|
||||||
@ -4414,7 +4426,7 @@ class MyCompiler: public Compiler {
|
|||||||
assert(&c, footprint);
|
assert(&c, footprint);
|
||||||
|
|
||||||
Value* v = value(&c);
|
Value* v = value(&c);
|
||||||
Stack* s = ::stack(&c, v, footprint, c.stack);
|
Stack* s = ::stack(&c, v, c.stack);
|
||||||
v->home = frameIndex(&c, s->index + c.localFootprint);
|
v->home = frameIndex(&c, s->index + c.localFootprint);
|
||||||
c.stack = s;
|
c.stack = s;
|
||||||
}
|
}
|
||||||
@ -4427,6 +4439,8 @@ class MyCompiler: public Compiler {
|
|||||||
c.saved = cons(&c, static_cast<Value*>(value), c.saved);
|
c.saved = cons(&c, static_cast<Value*>(value), c.saved);
|
||||||
if (BytesPerWord == 4 and footprint > 1) {
|
if (BytesPerWord == 4 and footprint > 1) {
|
||||||
assert(&c, footprint == 2);
|
assert(&c, footprint == 2);
|
||||||
|
assert(&c, static_cast<Value*>(value)->high);
|
||||||
|
|
||||||
save(1, static_cast<Value*>(value)->high);
|
save(1, static_cast<Value*>(value)->high);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4441,13 +4455,26 @@ class MyCompiler: public Compiler {
|
|||||||
(&c, v, frameIndex
|
(&c, v, frameIndex
|
||||||
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
|
(&c, (c.stack ? c.stack->index : 0) + c.localFootprint));
|
||||||
|
|
||||||
Stack* s = ::stack(&c, v, 1, c.stack);
|
Stack* s = ::stack(&c, v, c.stack);
|
||||||
v->home = frameIndex(&c, s->index + c.localFootprint);
|
v->home = frameIndex(&c, s->index + c.localFootprint);
|
||||||
c.stack = s;
|
c.stack = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void popped() {
|
virtual void popped(unsigned footprint) {
|
||||||
assert(&c, c.stack->value->home >= 0);
|
assert(&c, c.stack->value->home >= 0);
|
||||||
|
|
||||||
|
if (footprint > 1) {
|
||||||
|
assert(&c, footprint == 2);
|
||||||
|
assert(&c, c.stack->value->high == c.stack->next->value
|
||||||
|
and ((BytesPerWord == 8) xor (c.stack->value->high != 0)));
|
||||||
|
|
||||||
|
popped(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DebugFrame) {
|
||||||
|
fprintf(stderr, "popped %p\n", c.stack->value);
|
||||||
|
}
|
||||||
|
|
||||||
c.stack = c.stack->next;
|
c.stack = c.stack->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4456,7 +4483,9 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned footprint(StackElement* e) {
|
virtual unsigned footprint(StackElement* e) {
|
||||||
return static_cast<Stack*>(e)->value->high ? 2 : 1;
|
return (static_cast<Stack*>(e)->next
|
||||||
|
and (static_cast<Stack*>(e)->next->value
|
||||||
|
== static_cast<Stack*>(e)->value->high)) ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned index(StackElement* e) {
|
virtual unsigned index(StackElement* e) {
|
||||||
@ -4506,7 +4535,7 @@ class MyCompiler: public Compiler {
|
|||||||
Stack* bottomArgument = 0;
|
Stack* bottomArgument = 0;
|
||||||
|
|
||||||
for (int i = index - 1; i >= 0; --i) {
|
for (int i = index - 1; i >= 0; --i) {
|
||||||
argumentStack = ::stack(&c, arguments[i], 1, argumentStack);
|
argumentStack = ::stack(&c, arguments[i], argumentStack);
|
||||||
|
|
||||||
if (i == index - 1) {
|
if (i == index - 1) {
|
||||||
bottomArgument = argumentStack;
|
bottomArgument = argumentStack;
|
||||||
@ -4581,6 +4610,8 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
if (BytesPerWord == 4 and footprint > 1) {
|
if (BytesPerWord == 4 and footprint > 1) {
|
||||||
assert(&c, footprint == 2);
|
assert(&c, footprint == 2);
|
||||||
|
assert(&c, static_cast<Value*>(src)->high);
|
||||||
|
|
||||||
storeLocal(1, static_cast<Value*>(src)->high, index + 1);
|
storeLocal(1, static_cast<Value*>(src)->high, index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ class Compiler {
|
|||||||
virtual void save(unsigned footprint, Operand* value) = 0;
|
virtual void save(unsigned footprint, Operand* value) = 0;
|
||||||
virtual Operand* pop(unsigned footprint) = 0;
|
virtual Operand* pop(unsigned footprint) = 0;
|
||||||
virtual void pushed() = 0;
|
virtual void pushed() = 0;
|
||||||
virtual void popped() = 0;
|
virtual void popped(unsigned footprint) = 0;
|
||||||
virtual StackElement* top() = 0;
|
virtual StackElement* top() = 0;
|
||||||
virtual unsigned footprint(StackElement*) = 0;
|
virtual unsigned footprint(StackElement*) = 0;
|
||||||
virtual unsigned index(StackElement*) = 0;
|
virtual unsigned index(StackElement*) = 0;
|
||||||
|
@ -2300,11 +2300,10 @@ class MyAssembler: public Assembler {
|
|||||||
unsigned aSize, OperandType aType, Operand* aOperand,
|
unsigned aSize, OperandType aType, Operand* aOperand,
|
||||||
unsigned bSize, OperandType bType, Operand* bOperand,
|
unsigned bSize, OperandType bType, Operand* bOperand,
|
||||||
unsigned cSize UNUSED, OperandType cType UNUSED,
|
unsigned cSize UNUSED, OperandType cType UNUSED,
|
||||||
Operand* cOperand UNUSED)
|
Operand*)
|
||||||
{
|
{
|
||||||
assert(&c, bSize == cSize);
|
assert(&c, bSize == cSize);
|
||||||
assert(&c, bType == cType);
|
assert(&c, bType == cType);
|
||||||
assert(&c, bOperand == cOperand);
|
|
||||||
|
|
||||||
arch_->c.binaryOperations[index(op, aType, bType)]
|
arch_->c.binaryOperations[index(op, aType, bType)]
|
||||||
(&c, aSize, aOperand, bSize, bOperand);
|
(&c, aSize, aOperand, bSize, bOperand);
|
||||||
|
Loading…
Reference in New Issue
Block a user