mirror of
https://github.com/corda/corda.git
synced 2025-01-09 14:33:30 +00:00
various bugfixes
This commit is contained in:
parent
a7134a2cd7
commit
af2c2e019c
204
src/compiler.cpp
204
src/compiler.cpp
@ -20,6 +20,7 @@ class Value;
|
|||||||
class Stack;
|
class Stack;
|
||||||
class Site;
|
class Site;
|
||||||
class Event;
|
class Event;
|
||||||
|
class Read;
|
||||||
|
|
||||||
void NO_RETURN abort(Context*);
|
void NO_RETURN abort(Context*);
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ class Site {
|
|||||||
|
|
||||||
virtual ~Site() { }
|
virtual ~Site() { }
|
||||||
|
|
||||||
virtual Site* resolve(Context*, unsigned) { return this; }
|
virtual Site* readTarget(Context*, Read*) { return this; }
|
||||||
|
|
||||||
virtual unsigned copyCost(Context*, Site*) = 0;
|
virtual unsigned copyCost(Context*, Site*) = 0;
|
||||||
|
|
||||||
@ -127,28 +128,16 @@ class Read {
|
|||||||
Read* eventNext;
|
Read* eventNext;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Write {
|
|
||||||
public:
|
|
||||||
Write(unsigned size, Value* value, Write* eventNext):
|
|
||||||
size(size), value(value), eventNext(eventNext)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
unsigned size;
|
|
||||||
Value* value;
|
|
||||||
Write* eventNext;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Value: public Compiler::Operand {
|
class Value: public Compiler::Operand {
|
||||||
public:
|
public:
|
||||||
Value(Site* site):
|
Value(Site* site):
|
||||||
reads(0), lastRead(0), sites(site), source(0), target(0)
|
reads(0), lastRead(0), sites(site), source(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Read* reads;
|
Read* reads;
|
||||||
Read* lastRead;
|
Read* lastRead;
|
||||||
Site* sites;
|
Site* sites;
|
||||||
Site* source;
|
Site* source;
|
||||||
Site* target;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
@ -205,6 +194,28 @@ addSite(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
|
|||||||
v->sites = s;
|
v->sites = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
findSite(Context*, Value* v, Site* site)
|
||||||
|
{
|
||||||
|
for (Site* s = v->sites; s; s = s->next) {
|
||||||
|
if (s == site) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
removeSite(Context*, Value* v, Site* s)
|
||||||
|
{
|
||||||
|
for (Site** p = &(v->sites); *p;) {
|
||||||
|
if (s == *p) {
|
||||||
|
*p = (*p)->next;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
p = &((*p)->next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ConstantSite: public Site {
|
class ConstantSite: public Site {
|
||||||
public:
|
public:
|
||||||
ConstantSite(Promise* value): value(value) { }
|
ConstantSite(Promise* value): value(value) { }
|
||||||
@ -381,8 +392,12 @@ class ValueSite: public AbstractSite {
|
|||||||
public:
|
public:
|
||||||
ValueSite(Value* value): value(value) { }
|
ValueSite(Value* value): value(value) { }
|
||||||
|
|
||||||
virtual Site* resolve(Context*, unsigned) {
|
virtual Site* readTarget(Context* c, Read*) {
|
||||||
return value->sites;
|
if (value->reads and value->reads->target) {
|
||||||
|
return value->reads->target->readTarget(c, value->reads);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -396,8 +411,13 @@ valueSite(Context* c, Value* v)
|
|||||||
|
|
||||||
class AnyRegisterSite: public AbstractSite {
|
class AnyRegisterSite: public AbstractSite {
|
||||||
public:
|
public:
|
||||||
virtual Site* resolve(Context* c, unsigned size) {
|
virtual Site* readTarget(Context* c, Read* r) {
|
||||||
return freeRegister(c, size, true);
|
for (Site* s = r->value->sites; s; s = s->next) {
|
||||||
|
if (s->type(c) == RegisterOperand) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return freeRegister(c, r->size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -516,7 +536,7 @@ acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
Site* newSite)
|
Site* newSite)
|
||||||
{
|
{
|
||||||
Value* oldValue = c->registers[r].value;
|
Value* oldValue = c->registers[r].value;
|
||||||
if (oldValue) {
|
if (oldValue and findSite(c, oldValue, c->registers[r].site)) {
|
||||||
if (oldValue->sites->next == 0 and oldValue->reads) {
|
if (oldValue->sites->next == 0 and oldValue->reads) {
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
Stack* start = 0;
|
Stack* start = 0;
|
||||||
@ -534,14 +554,7 @@ acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
stackSync(c, start, count);
|
stackSync(c, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Site** p = &(oldValue->sites); *p;) {
|
removeSite(c, oldValue, c->registers[r].site);
|
||||||
if (c->registers[r].site == *p) {
|
|
||||||
*p = (*p)->next;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
p = &((*p)->next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->registers[r].size = newSize;
|
c->registers[r].size = newSize;
|
||||||
@ -641,7 +654,7 @@ class IpPromise: public Promise {
|
|||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
Event(Context* c):
|
Event(Context* c):
|
||||||
next(0), stack(c->state->stack), promises(0), reads(0), writes(0),
|
next(0), stack(c->state->stack), promises(0), reads(0),
|
||||||
logicalIp(c->logicalIp)
|
logicalIp(c->logicalIp)
|
||||||
{
|
{
|
||||||
assert(c, c->logicalIp >= 0);
|
assert(c, c->logicalIp >= 0);
|
||||||
@ -658,7 +671,7 @@ class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Event(Context*, Event* next):
|
Event(Context*, Event* next):
|
||||||
next(next), stack(next->stack), promises(0), reads(0), writes(0),
|
next(next), stack(next->stack), promises(0), reads(0),
|
||||||
sequence(next->sequence), logicalIp(next->logicalIp)
|
sequence(next->sequence), logicalIp(next->logicalIp)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -670,7 +683,6 @@ class Event {
|
|||||||
Stack* stack;
|
Stack* stack;
|
||||||
CodePromise* promises;
|
CodePromise* promises;
|
||||||
Read* reads;
|
Read* reads;
|
||||||
Write* writes;
|
|
||||||
unsigned sequence;
|
unsigned sequence;
|
||||||
unsigned logicalIp;
|
unsigned logicalIp;
|
||||||
};
|
};
|
||||||
@ -711,20 +723,13 @@ addRead(Context* c, Value* v, unsigned size, Site* target)
|
|||||||
insertRead(c, c->lastEvent, 0, v, size, target);
|
insertRead(c, c->lastEvent, 0, v, size, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
addWrite(Context* c, Value* v, unsigned size)
|
|
||||||
{
|
|
||||||
c->lastEvent->writes = new (c->zone->allocate(sizeof(Write)))
|
|
||||||
Write(size, v, c->lastEvent->writes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
push(Context* c, unsigned size, Value* v);
|
push(Context* c, unsigned size, Value* v);
|
||||||
|
|
||||||
class CallEvent: public Event {
|
class CallEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CallEvent(Context* c, Value* address, void* indirection, unsigned flags,
|
CallEvent(Context* c, Value* address, void* indirection, unsigned flags,
|
||||||
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
TraceHandler* traceHandler, Value* result, unsigned,
|
||||||
Value** arguments, unsigned* argumentSizes,
|
Value** arguments, unsigned* argumentSizes,
|
||||||
unsigned argumentCount):
|
unsigned argumentCount):
|
||||||
Event(c),
|
Event(c),
|
||||||
@ -758,10 +763,6 @@ class CallEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->state->stack = stack;
|
c->state->stack = stack;
|
||||||
|
|
||||||
if (result) {
|
|
||||||
addWrite(c, result, resultSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
@ -775,6 +776,9 @@ class CallEvent: public Event {
|
|||||||
apply(c, type, BytesPerWord, address->source);
|
apply(c, type, BytesPerWord, address->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addSite(c, 0, 0, result, registerSite
|
||||||
|
(c, c->assembler->returnLow(), c->assembler->returnHigh()));
|
||||||
|
|
||||||
if (traceHandler) {
|
if (traceHandler) {
|
||||||
traceHandler->handleTrace
|
traceHandler->handleTrace
|
||||||
(new (c->zone->allocate(sizeof(CodePromise)))
|
(new (c->zone->allocate(sizeof(CodePromise)))
|
||||||
@ -841,6 +845,19 @@ appendReturn(Context* c, unsigned size, Value* value)
|
|||||||
new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, size, value);
|
new (c->zone->allocate(sizeof(ReturnEvent))) ReturnEvent(c, size, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Site*
|
||||||
|
writeTarget(Context* c, unsigned size, Value* v)
|
||||||
|
{
|
||||||
|
if (v->sites) {
|
||||||
|
assert(c, v->sites->next == 0);
|
||||||
|
return v->sites;
|
||||||
|
} else if (v->reads and v->reads->target) {
|
||||||
|
Site* s = v->reads->target->readTarget(c, v->reads);
|
||||||
|
if (s) return s;
|
||||||
|
}
|
||||||
|
return freeRegister(c, size, true);
|
||||||
|
}
|
||||||
|
|
||||||
class MoveEvent: public Event {
|
class MoveEvent: public Event {
|
||||||
public:
|
public:
|
||||||
MoveEvent(Context* c, BinaryOperation type, unsigned size, Value* src,
|
MoveEvent(Context* c, BinaryOperation type, unsigned size, Value* src,
|
||||||
@ -848,13 +865,14 @@ class MoveEvent: public Event {
|
|||||||
Event(c), type(type), size(size), src(src), dst(dst)
|
Event(c), type(type), size(size), src(src), dst(dst)
|
||||||
{
|
{
|
||||||
addRead(c, src, size, 0);
|
addRead(c, src, size, 0);
|
||||||
addWrite(c, dst, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "MoveEvent.compile\n");
|
fprintf(stderr, "MoveEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, size, src->source, dst->target);
|
Site* target = writeTarget(c, size, dst);
|
||||||
|
apply(c, type, size, src->source, target);
|
||||||
|
addSite(c, stack, size, dst, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryOperation type;
|
BinaryOperation type;
|
||||||
@ -940,13 +958,14 @@ class CombineEvent: public Event {
|
|||||||
r2.low == NoRegister ?
|
r2.low == NoRegister ?
|
||||||
valueSite(c, result) :
|
valueSite(c, result) :
|
||||||
static_cast<Site*>(registerSite(c, r2.low, r2.high)));
|
static_cast<Site*>(registerSite(c, r2.low, r2.high)));
|
||||||
addWrite(c, result, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "CombineEvent.compile\n");
|
fprintf(stderr, "CombineEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, size, first->source, second->source);
|
apply(c, type, size, first->source, second->source);
|
||||||
|
removeSite(c, second, second->source);
|
||||||
|
addSite(c, 0, 0, result, second->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryOperation type;
|
BinaryOperation type;
|
||||||
@ -971,13 +990,14 @@ class TranslateEvent: public Event {
|
|||||||
Event(c), type(type), size(size), value(value), result(result)
|
Event(c), type(type), size(size), value(value), result(result)
|
||||||
{
|
{
|
||||||
addRead(c, value, size, valueSite(c, result));
|
addRead(c, value, size, valueSite(c, result));
|
||||||
addWrite(c, result, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "TranslateEvent.compile\n");
|
fprintf(stderr, "TranslateEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, size, value->source);
|
apply(c, type, size, value->source);
|
||||||
|
removeSite(c, value, value->source);
|
||||||
|
addSite(c, 0, 0, result, value->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnaryOperation type;
|
UnaryOperation type;
|
||||||
@ -1008,18 +1028,15 @@ class MemoryEvent: public Event {
|
|||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "MemoryEvent.compile\n");
|
fprintf(stderr, "MemoryEvent.compile\n");
|
||||||
|
|
||||||
int baseRegister;
|
|
||||||
int indexRegister;
|
int indexRegister;
|
||||||
Read* read = reads;
|
|
||||||
if (index) {
|
if (index) {
|
||||||
assert(c, read->target->type(c) == RegisterOperand);
|
assert(c, index->source->type(c) == RegisterOperand);
|
||||||
indexRegister = static_cast<RegisterSite*>(read->target)->register_.low;
|
indexRegister = static_cast<RegisterSite*>(index->source)->register_.low;
|
||||||
read = read->eventNext;
|
|
||||||
} else {
|
} else {
|
||||||
indexRegister = NoRegister;
|
indexRegister = NoRegister;
|
||||||
}
|
}
|
||||||
assert(c, read->target->type(c) == RegisterOperand);
|
assert(c, base->source->type(c) == RegisterOperand);
|
||||||
baseRegister = static_cast<RegisterSite*>(read->target)->register_.low;
|
int baseRegister = static_cast<RegisterSite*>(base->source)->register_.low;
|
||||||
|
|
||||||
addSite(c, 0, 0, result, memorySite
|
addSite(c, 0, 0, result, memorySite
|
||||||
(c, baseRegister, displacement, indexRegister, scale));
|
(c, baseRegister, displacement, indexRegister, scale));
|
||||||
@ -1103,15 +1120,43 @@ appendStackSync(Context* c, bool forCall = false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
target(Context* c, unsigned size, Value* value)
|
readSource(Context* c, Stack* stack, Read* r)
|
||||||
{
|
{
|
||||||
if (value->reads
|
Site* target = (r->target ? r->target->readTarget(c, r) : 0);
|
||||||
and value->reads->target
|
|
||||||
and not value->reads->target->type(c) == StackOperand)
|
unsigned copyCost;
|
||||||
{
|
Site* site = pick(c, r->value->sites, target, ©Cost);
|
||||||
return value->reads->target;
|
|
||||||
|
if (site->type(c) == StackOperand) {
|
||||||
|
bool success = false;;
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
if (s->pushed) {
|
||||||
|
target = writeTarget(c, s->size * BytesPerWord, s->value);
|
||||||
|
|
||||||
|
addSite(c, stack, s->size * BytesPerWord, s->value, target);
|
||||||
|
|
||||||
|
s->pushed = false;
|
||||||
|
if (s == static_cast<StackSite*>(site)->stack) {
|
||||||
|
site = pick(c, r->value->sites, target, ©Cost);
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(c, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
if (copyCost) {
|
||||||
|
addSite(c, stack, r->size, r->value, target);
|
||||||
|
|
||||||
|
target->accept(c, r->size, site);
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
} else {
|
} else {
|
||||||
return freeRegister(c, size, true);
|
return site;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1137,48 +1182,11 @@ compile(Context* c)
|
|||||||
li->machineOffset = a->length();
|
li->machineOffset = a->length();
|
||||||
|
|
||||||
for (Read* r = e->reads; r; r = r->eventNext) {
|
for (Read* r = e->reads; r; r = r->eventNext) {
|
||||||
Site* target = (r->target ? r->target->resolve(c, r->size) : 0);
|
r->value->source = readSource(c, e->stack, r);
|
||||||
|
|
||||||
unsigned copyCost;
|
|
||||||
Site* site = pick(c, r->value->sites, target, ©Cost);
|
|
||||||
|
|
||||||
if (site->type(c) == StackOperand) {
|
|
||||||
for (Stack* s = e->stack; s; s = s->next) {
|
|
||||||
if (s->pushed) {
|
|
||||||
target = ::target(c, s->size * BytesPerWord, s->value);
|
|
||||||
|
|
||||||
addSite(c, e->stack, s->size * BytesPerWord, s->value, target);
|
|
||||||
|
|
||||||
s->pushed = false;
|
|
||||||
if (s == static_cast<StackSite*>(site)->stack) {
|
|
||||||
site = pick(c, r->value->sites, target, ©Cost);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
if (copyCost) {
|
|
||||||
addSite(c, e->stack, r->size, r->value, target);
|
|
||||||
|
|
||||||
target->accept(c, r->size, site);
|
|
||||||
}
|
|
||||||
|
|
||||||
r->value->source = target;
|
|
||||||
} else {
|
|
||||||
r->value->source = site;
|
|
||||||
}
|
|
||||||
|
|
||||||
r->value->reads = r->value->reads->next;
|
r->value->reads = r->value->reads->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Write* w = e->writes; w; w = w->eventNext) {
|
|
||||||
w->value->target = target(c, w->size, w->value);
|
|
||||||
|
|
||||||
addSite(c, e->stack, w->size, w->value, w->value->target);
|
|
||||||
}
|
|
||||||
|
|
||||||
e->compile(c);
|
e->compile(c);
|
||||||
|
|
||||||
for (CodePromise* p = e->promises; p; p = p->next) {
|
for (CodePromise* p = e->promises; p; p = p->next) {
|
||||||
|
Loading…
Reference in New Issue
Block a user