mirror of
https://github.com/corda/corda.git
synced 2025-02-02 17:21:06 +00:00
snapshot
This commit is contained in:
parent
767c3ce2e4
commit
5f7d68b404
@ -161,7 +161,11 @@ class Assembler {
|
|||||||
public:
|
public:
|
||||||
virtual ~Offset() { }
|
virtual ~Offset() { }
|
||||||
|
|
||||||
virtual unsigned calculate(unsigned start) = 0;
|
virtual unsigned resolve(unsigned start) = 0;
|
||||||
|
|
||||||
|
virtual bool resolved() = 0;
|
||||||
|
|
||||||
|
virtual unsigned value() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Architecture {
|
class Architecture {
|
||||||
@ -220,6 +224,7 @@ class Assembler {
|
|||||||
|
|
||||||
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset);
|
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset);
|
||||||
virtual void pushFrame(unsigned argumentCount, ...);
|
virtual void pushFrame(unsigned argumentCount, ...);
|
||||||
|
virtual void allocateFrame(unsigned footprint);
|
||||||
virtual void popFrame();
|
virtual void popFrame();
|
||||||
|
|
||||||
virtual void apply(Operation op) = 0;
|
virtual void apply(Operation op) = 0;
|
||||||
@ -238,6 +243,10 @@ class Assembler {
|
|||||||
|
|
||||||
virtual void writeTo(uint8_t* dst) = 0;
|
virtual void writeTo(uint8_t* dst) = 0;
|
||||||
|
|
||||||
|
virtual Offset* offset() = 0;
|
||||||
|
|
||||||
|
virtual void endBlock() = 0;
|
||||||
|
|
||||||
virtual unsigned length() = 0;
|
virtual unsigned length() = 0;
|
||||||
|
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
|
313
src/compiler.cpp
313
src/compiler.cpp
@ -31,6 +31,7 @@ class RegisterSite;
|
|||||||
class Event;
|
class Event;
|
||||||
class PushEvent;
|
class PushEvent;
|
||||||
class Read;
|
class Read;
|
||||||
|
class Block;
|
||||||
|
|
||||||
void NO_RETURN abort(Context*);
|
void NO_RETURN abort(Context*);
|
||||||
|
|
||||||
@ -125,6 +126,7 @@ class LogicalInstruction {
|
|||||||
Stack* stack;
|
Stack* stack;
|
||||||
Value** locals;
|
Value** locals;
|
||||||
Promise* machineOffset;
|
Promise* machineOffset;
|
||||||
|
int index;
|
||||||
bool stackSaved;
|
bool stackSaved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,17 +155,6 @@ class ConstantPoolNode {
|
|||||||
ConstantPoolNode* next;
|
ConstantPoolNode* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Junction {
|
|
||||||
public:
|
|
||||||
Junction(unsigned logicalIp, Junction* next):
|
|
||||||
logicalIp(logicalIp),
|
|
||||||
next(next)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
unsigned logicalIp;
|
|
||||||
Junction* next;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Read {
|
class Read {
|
||||||
public:
|
public:
|
||||||
Read():
|
Read():
|
||||||
@ -178,6 +169,8 @@ class Read {
|
|||||||
int* frameIndex) = 0;
|
int* frameIndex) = 0;
|
||||||
|
|
||||||
virtual bool valid() = 0;
|
virtual bool valid() = 0;
|
||||||
|
|
||||||
|
virtual unsigned size(Context* c) = 0;
|
||||||
|
|
||||||
Read* next;
|
Read* next;
|
||||||
Value* value;
|
Value* value;
|
||||||
@ -222,25 +215,25 @@ class Context {
|
|||||||
arch(assembler->arch()),
|
arch(assembler->arch()),
|
||||||
zone(zone),
|
zone(zone),
|
||||||
client(client),
|
client(client),
|
||||||
logicalIp(-1),
|
|
||||||
state(new (zone->allocate(sizeof(State))) State(0, 0, 0)),
|
state(new (zone->allocate(sizeof(State))) State(0, 0, 0)),
|
||||||
logicalCode(0),
|
logicalCode(0),
|
||||||
logicalCodeLength(0),
|
|
||||||
parameterFootprint(0),
|
|
||||||
localFootprint(0),
|
|
||||||
registers
|
registers
|
||||||
(static_cast<Register**>
|
(static_cast<Register**>
|
||||||
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
||||||
firstConstant(0),
|
firstConstant(0),
|
||||||
lastConstant(0),
|
lastConstant(0),
|
||||||
|
machineCode(0),
|
||||||
|
firstEvent(0),
|
||||||
|
logicalIp(-1),
|
||||||
constantCount(0),
|
constantCount(0),
|
||||||
nextSequence(0),
|
nextSequence(0),
|
||||||
junctions(0),
|
logicalCodeLength(0),
|
||||||
machineCode(0),
|
parameterFootprint(0),
|
||||||
stackReset(false),
|
localFootprint(0),
|
||||||
|
maxStackFootprint(0),
|
||||||
|
stackPadding(0),
|
||||||
constantCompare(CompareNone),
|
constantCompare(CompareNone),
|
||||||
pass(ScanPass),
|
pass(ScanPass)
|
||||||
stackPadding(0)
|
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < arch->registerCount(); ++i) {
|
for (unsigned i = 0; i < arch->registerCount(); ++i) {
|
||||||
registers[i] = new (zone->allocate(sizeof(Register))) Register(i);
|
registers[i] = new (zone->allocate(sizeof(Register))) Register(i);
|
||||||
@ -253,24 +246,23 @@ class Context {
|
|||||||
Assembler::Architecture* arch;
|
Assembler::Architecture* arch;
|
||||||
Zone* zone;
|
Zone* zone;
|
||||||
Compiler::Client* client;
|
Compiler::Client* client;
|
||||||
int logicalIp;
|
|
||||||
State* state;
|
State* state;
|
||||||
LogicalInstruction** logicalCode;
|
LogicalInstruction** logicalCode;
|
||||||
|
Register** registers;
|
||||||
|
ConstantPoolNode* firstConstant;
|
||||||
|
ConstantPoolNode* lastConstant;
|
||||||
|
uint8_t* machineCode;
|
||||||
|
Event* firstEvent;
|
||||||
|
int logicalIp;
|
||||||
|
unsigned constantCount;
|
||||||
|
unsigned nextSequence;
|
||||||
unsigned logicalCodeLength;
|
unsigned logicalCodeLength;
|
||||||
unsigned parameterFootprint;
|
unsigned parameterFootprint;
|
||||||
unsigned localFootprint;
|
unsigned localFootprint;
|
||||||
unsigned maxStackFootprint;
|
unsigned maxStackFootprint;
|
||||||
Register** registers;
|
unsigned stackPadding;
|
||||||
ConstantPoolNode* firstConstant;
|
|
||||||
ConstantPoolNode* lastConstant;
|
|
||||||
unsigned constantCount;
|
|
||||||
unsigned nextSequence;
|
|
||||||
Junction* junctions;
|
|
||||||
uint8_t* machineCode;
|
|
||||||
bool stackReset;
|
|
||||||
ConstantCompare constantCompare;
|
ConstantCompare constantCompare;
|
||||||
Pass pass;
|
Pass pass;
|
||||||
unsigned stackPadding;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PoolPromise: public Promise {
|
class PoolPromise: public Promise {
|
||||||
@ -296,24 +288,28 @@ class PoolPromise: public Promise {
|
|||||||
|
|
||||||
class CodePromise: public Promise {
|
class CodePromise: public Promise {
|
||||||
public:
|
public:
|
||||||
CodePromise(Context* c, CodePromise* next): c(c), offset(-1), next(next) { }
|
CodePromise(Context* c, CodePromise* next):
|
||||||
|
c(c), offset(0), next(next)
|
||||||
|
{ }
|
||||||
|
|
||||||
CodePromise(Context* c, int offset): c(c), offset(offset), next(0) { }
|
CodePromise(Context* c, Assembler::Offset* offset):
|
||||||
|
c(c), offset(offset), next(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
virtual int64_t value() {
|
virtual int64_t value() {
|
||||||
if (resolved()) {
|
if (resolved()) {
|
||||||
return reinterpret_cast<intptr_t>(c->machineCode + offset);
|
return reinterpret_cast<intptr_t>(c->machineCode + offset->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool resolved() {
|
virtual bool resolved() {
|
||||||
return c->machineCode != 0 and offset >= 0;
|
return c->machineCode != 0 and offset and offset->resolved();
|
||||||
}
|
}
|
||||||
|
|
||||||
Context* c;
|
Context* c;
|
||||||
int offset;
|
Assembler::Offset* offset;
|
||||||
CodePromise* next;
|
CodePromise* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -365,42 +361,45 @@ class Event {
|
|||||||
public:
|
public:
|
||||||
Event(Context* c):
|
Event(Context* c):
|
||||||
next(0), stack(c->state->stack), locals(c->state->locals), promises(0),
|
next(0), stack(c->state->stack), locals(c->state->locals), promises(0),
|
||||||
reads(0), readCount(0), sequence(c->nextSequence++),
|
reads(0), junctionSites(0), savedSites(0), predecessors(0), successors(0),
|
||||||
stackReset(c->stackReset)
|
block(0), logicalInstruction(c->logicalCode[c->logicalIp]), readCount(0),
|
||||||
|
sequence(c->nextSequence++)
|
||||||
{
|
{
|
||||||
assert(c, c->logicalIp >= 0);
|
assert(c, c->logicalIp >= 0);
|
||||||
|
|
||||||
LogicalInstruction* i = c->logicalCode[c->logicalIp];
|
if (logicalInstruction->lastEvent) {
|
||||||
if (i->lastEvent) {
|
logicalInstruction->lastEvent->next = this;
|
||||||
i->lastEvent->next = this;
|
|
||||||
} else {
|
} else {
|
||||||
i->firstEvent = this;
|
logicalInstruction->firstEvent = this;
|
||||||
}
|
|
||||||
i->lastEvent = this;
|
|
||||||
|
|
||||||
if (c->stackReset) {
|
|
||||||
// fprintf(stderr, "stack reset\n");
|
|
||||||
c->stackReset = false;
|
|
||||||
}
|
}
|
||||||
|
logicalInstruction->lastEvent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(Context*, unsigned sequence, Stack* stack, Value** locals):
|
Event(Context*, unsigned sequence, Stack* stack, Value** locals):
|
||||||
next(0), stack(stack), locals(locals), promises(0), reads(0), readCount(0),
|
next(0), stack(stack), locals(locals), promises(0), reads(0),
|
||||||
sequence(sequence), stackReset(false)
|
junctionSites(0), savedSites(0), predecessors(0), successors(0), block(0),
|
||||||
|
logicalInstruction(0), readCount(0), sequence(sequence)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual ~Event() { }
|
virtual ~Event() { }
|
||||||
|
|
||||||
virtual void compile(Context* c) = 0;
|
virtual void compile(Context* c) = 0;
|
||||||
|
|
||||||
|
virtual void compilePostsync(Context*) { }
|
||||||
|
|
||||||
Event* next;
|
Event* next;
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
Value** locals;
|
Value** locals;
|
||||||
CodePromise* promises;
|
CodePromise* promises;
|
||||||
Read* reads;
|
Read* reads;
|
||||||
|
Site** junctionSites;
|
||||||
|
Site** savedSites;
|
||||||
|
Cell* predecessors;
|
||||||
|
Cell* successors;
|
||||||
|
Block* block;
|
||||||
|
LogicalInstruction* logicalInstruction;
|
||||||
unsigned readCount;
|
unsigned readCount;
|
||||||
unsigned sequence;
|
unsigned sequence;
|
||||||
bool stackReset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -913,7 +912,7 @@ class SingleRead: public Read {
|
|||||||
public:
|
public:
|
||||||
SingleRead(unsigned size, uint8_t typeMask, uint64_t registerMask,
|
SingleRead(unsigned size, uint8_t typeMask, uint64_t registerMask,
|
||||||
int frameIndex):
|
int frameIndex):
|
||||||
size(size), typeMask(typeMask), registerMask(registerMask),
|
size_(size), typeMask(typeMask), registerMask(registerMask),
|
||||||
frameIndex(frameIndex)
|
frameIndex(frameIndex)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -937,7 +936,11 @@ class SingleRead: public Read {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size;
|
virtual unsigned size(Context*) {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned size_;
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
uint64_t registerMask;
|
uint64_t registerMask;
|
||||||
int frameIndex;
|
int frameIndex;
|
||||||
@ -1023,6 +1026,10 @@ class MultiRead: public Read {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual unsigned size(Context* c) {
|
||||||
|
return static_cast<Read*>(reads->value)->size(c);
|
||||||
|
}
|
||||||
|
|
||||||
Cell* reads;
|
Cell* reads;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1417,7 +1424,7 @@ codePromise(Context* c, Event* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodePromise*
|
CodePromise*
|
||||||
codePromise(Context* c, int offset)
|
codePromise(Context* c, Assembler::Offset* offset)
|
||||||
{
|
{
|
||||||
return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset);
|
return new (c->zone->allocate(sizeof(CodePromise))) CodePromise(c, offset);
|
||||||
}
|
}
|
||||||
@ -1487,7 +1494,7 @@ class CallEvent: public Event {
|
|||||||
address->source);
|
address->source);
|
||||||
|
|
||||||
if (traceHandler) {
|
if (traceHandler) {
|
||||||
traceHandler->handleTrace(codePromise(c, c->assembler->length()));
|
traceHandler->handleTrace(codePromise(c, c->assembler->offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
clean(c, stack, locals, reads);
|
clean(c, stack, locals, reads);
|
||||||
@ -1808,9 +1815,6 @@ class CombineEvent: public Event {
|
|||||||
Value* result;
|
Value* result;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
appendStackSync(Context* c);
|
|
||||||
|
|
||||||
Value*
|
Value*
|
||||||
value(Context* c, Site* site = 0, Site* target = 0)
|
value(Context* c, Site* site = 0, Site* target = 0)
|
||||||
{
|
{
|
||||||
@ -2113,64 +2117,11 @@ class BranchEvent: public Event {
|
|||||||
void
|
void
|
||||||
appendBranch(Context* c, UnaryOperation type, Value* address)
|
appendBranch(Context* c, UnaryOperation type, Value* address)
|
||||||
{
|
{
|
||||||
appendStackSync(c);
|
|
||||||
|
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
fprintf(stderr, "appendBranch\n");
|
fprintf(stderr, "appendBranch\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(BranchEvent))) BranchEvent(c, type, address);
|
new (c->zone->allocate(sizeof(BranchEvent))) BranchEvent(c, type, address);
|
||||||
|
|
||||||
resetStack(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PushSite: public AbstractSite {
|
|
||||||
public:
|
|
||||||
PushSite(PushEvent* event): event(event) { }
|
|
||||||
|
|
||||||
virtual Site* readTarget(Context* c, Read* r) {
|
|
||||||
if (r->next and (not event->active)) {
|
|
||||||
return targetOrNull(c, r->next);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PushEvent* event;
|
|
||||||
};
|
|
||||||
|
|
||||||
Site*
|
|
||||||
pushSite(Context* c, PushEvent* e)
|
|
||||||
{
|
|
||||||
return new (c->zone->allocate(sizeof(PushSite))) PushSite(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
class PopEvent: public Event {
|
|
||||||
public:
|
|
||||||
PopEvent(Context* c, unsigned count, bool ignore):
|
|
||||||
Event(c), count(count), ignore(ignore)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
if (DebugCompile) {
|
|
||||||
fprintf(stderr, "PopEvent.compile\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
popNow(c, stack, count, ignore);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned count;
|
|
||||||
bool ignore;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendPop(Context* c, unsigned count, bool ignore)
|
|
||||||
{
|
|
||||||
if (DebugAppend) {
|
|
||||||
fprintf(stderr, "appendPop\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BoundsCheckEvent: public Event {
|
class BoundsCheckEvent: public Event {
|
||||||
@ -2192,15 +2143,16 @@ class BoundsCheckEvent: public Event {
|
|||||||
Assembler* a = c->assembler;
|
Assembler* a = c->assembler;
|
||||||
|
|
||||||
ConstantSite* constant = findConstantSite(c, index);
|
ConstantSite* constant = findConstantSite(c, index);
|
||||||
CodePromise* nextPromise = codePromise(c, -1);
|
CodePromise* nextPromise = codePromise
|
||||||
|
(c, static_cast<Assembler::Offset*>(0));
|
||||||
CodePromise* outOfBoundsPromise = 0;
|
CodePromise* outOfBoundsPromise = 0;
|
||||||
|
|
||||||
if (constant) {
|
if (constant) {
|
||||||
expect(c, constant->value.value->value() >= 0);
|
expect(c, constant->value.value->value() >= 0);
|
||||||
} else {
|
} else {
|
||||||
outOfBoundsPromise = codePromise(c, -1);
|
outOfBoundsPromise = codePromise(c, static_cast<Assembler::Offset*>(0));
|
||||||
|
|
||||||
apply(c, Compare, 4, constantSite(c, resolved(c, 0)), index->source);
|
apply(c, Compare, 4, constantSite(c, resolved(c, 0)), 4, index->source);
|
||||||
|
|
||||||
Assembler::Constant outOfBoundsConstant(outOfBoundsPromise);
|
Assembler::Constant outOfBoundsConstant(outOfBoundsPromise);
|
||||||
a->apply
|
a->apply
|
||||||
@ -2211,9 +2163,9 @@ class BoundsCheckEvent: public Event {
|
|||||||
int base = static_cast<RegisterSite*>(object->source)->register_.low;
|
int base = static_cast<RegisterSite*>(object->source)->register_.low;
|
||||||
|
|
||||||
Site* length = memorySite(c, base, lengthOffset);
|
Site* length = memorySite(c, base, lengthOffset);
|
||||||
length->acquire(c, 0, 0, 0);
|
length->acquire(c, 0, 0, 0, 0);
|
||||||
|
|
||||||
apply(c, Compare, 4, index->source, length);
|
apply(c, Compare, 4, index->source, 4, length);
|
||||||
|
|
||||||
length->release(c);
|
length->release(c);
|
||||||
|
|
||||||
@ -2221,13 +2173,13 @@ class BoundsCheckEvent: public Event {
|
|||||||
a->apply(JumpIfGreater, BytesPerWord, ConstantOperand, &nextConstant);
|
a->apply(JumpIfGreater, BytesPerWord, ConstantOperand, &nextConstant);
|
||||||
|
|
||||||
if (constant == 0) {
|
if (constant == 0) {
|
||||||
outOfBoundsPromise->offset = a->length();
|
outOfBoundsPromise->offset = a->offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assembler::Constant handlerConstant(resolved(c, handler));
|
Assembler::Constant handlerConstant(resolved(c, handler));
|
||||||
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
||||||
|
|
||||||
nextPromise->offset = a->length();
|
nextPromise->offset = a->offset();
|
||||||
|
|
||||||
nextRead(c, object);
|
nextRead(c, object);
|
||||||
nextRead(c, index);
|
nextRead(c, index);
|
||||||
@ -2258,22 +2210,24 @@ readSource(Context* c, Stack* stack, Value** locals, Read* r)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Site* target = (r->target ? r->target->readTarget(c, r) : 0);
|
Site* site = r->pickSite(c, r->value);
|
||||||
|
|
||||||
unsigned copyCost;
|
if (site) {
|
||||||
Site* site = pick(c, r->value->sites, target, ©Cost);
|
|
||||||
|
|
||||||
if (target and copyCost) {
|
|
||||||
addSite(c, stack, locals, r->size, r->value, target);
|
|
||||||
apply(c, Move, r->size, site, target);
|
|
||||||
return target;
|
|
||||||
} else {
|
|
||||||
return site;
|
return site;
|
||||||
|
} else {
|
||||||
|
Site* target = r->allocateSite(c);
|
||||||
|
unsigned copyCost;
|
||||||
|
site = pick(c, r->value->sites, target, ©Cost);
|
||||||
|
assert(c, copyCost);
|
||||||
|
|
||||||
|
addSite(c, stack, locals, r->size(c), r->value, target);
|
||||||
|
apply(c, Move, r->size(c), site, r->size(c), target);
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
pickJunctionSite(Context* c, Value* v)
|
pickJunctionSite(Context* c, Value* v, Read* r)
|
||||||
{
|
{
|
||||||
Site* s = r->pickSite(c, v);
|
Site* s = r->pickSite(c, v);
|
||||||
if (s) return s;
|
if (s) return s;
|
||||||
@ -2286,18 +2240,19 @@ resolveJunctionSite(Context* c, Event* e, Event* successor, Value* v,
|
|||||||
unsigned frozenSiteIndex)
|
unsigned frozenSiteIndex)
|
||||||
{
|
{
|
||||||
if (live(v)) {
|
if (live(v)) {
|
||||||
|
Read* r = v->reads;
|
||||||
Site* original = e->junctionSites[index];
|
Site* original = e->junctionSites[index];
|
||||||
|
|
||||||
if (original == 0) {
|
if (original == 0) {
|
||||||
e->junctionSites[i] = pickJunctionSite(c, v);
|
e->junctionSites[index] = pickJunctionSite(c, v, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Site* target = e->junctionSites[index];
|
Site* target = e->junctionSites[index];
|
||||||
unsigned copyCost;
|
unsigned copyCost;
|
||||||
Site* site = pick(c, v->sites, target, ©Cost);
|
Site* site = pick(c, v->sites, target, ©Cost);
|
||||||
if (copyCost) {
|
if (copyCost) {
|
||||||
addSite(c, successor->stack, successor->locals, v, target);
|
addSite(c, successor->stack, successor->locals, r->size(c), v, target);
|
||||||
apply(c, Move, site, target);
|
apply(c, Move, r->size(c), site, r->size(c), target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (original == 0) {
|
if (original == 0) {
|
||||||
@ -2318,16 +2273,16 @@ propagateJunctionSites(Context* c, Event* e, Site** sites)
|
|||||||
p->junctionSites = sites;
|
p->junctionSites = sites;
|
||||||
for (Cell* sc = p->successors; sc; sc = sc->next) {
|
for (Cell* sc = p->successors; sc; sc = sc->next) {
|
||||||
Event* s = static_cast<Event*>(sc->value);
|
Event* s = static_cast<Event*>(sc->value);
|
||||||
propagateJunctionSites(c, e, sites);
|
propagateJunctionSites(c, s, sites);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
unsigned
|
||||||
frameCount(Context* c, Stack* s)
|
frameFootprint(Context* c, Stack* s)
|
||||||
{
|
{
|
||||||
return c->localCount + s->index + footprint(s);
|
return c->localFootprint + s->index + s->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2335,13 +2290,13 @@ populateSiteTables(Context* c, Event* e)
|
|||||||
{
|
{
|
||||||
Event* successor = static_cast<Event*>(e->successors->value);
|
Event* successor = static_cast<Event*>(e->successors->value);
|
||||||
|
|
||||||
unsigned frameCount = ::frameCount(c, successor->stack);
|
unsigned frameFootprint = ::frameFootprint(c, successor->stack);
|
||||||
|
|
||||||
{ Site* frozenSites[frameCount];
|
{ Site* frozenSites[frameFootprint];
|
||||||
unsigned frozenSiteIndex = 0;
|
unsigned frozenSiteIndex = 0;
|
||||||
|
|
||||||
if (e->junctionSites) {
|
if (e->junctionSites) {
|
||||||
for (unsigned i = 0; i < frameCount; ++i) {
|
for (unsigned i = 0; i < frameFootprint; ++i) {
|
||||||
Site* site = e->junctionSites[i];
|
Site* site = e->junctionSites[i];
|
||||||
if (site) {
|
if (site) {
|
||||||
frozenSites[frozenSiteIndex++] = site;
|
frozenSites[frozenSiteIndex++] = site;
|
||||||
@ -2352,7 +2307,7 @@ populateSiteTables(Context* c, Event* e)
|
|||||||
for (Cell* sc = e->successors; sc; sc = sc->next) {
|
for (Cell* sc = e->successors; sc; sc = sc->next) {
|
||||||
Event* s = static_cast<Event*>(sc->value);
|
Event* s = static_cast<Event*>(sc->value);
|
||||||
if (s->predecessors->next) {
|
if (s->predecessors->next) {
|
||||||
unsigned size = sizeof(Site*) * frameCount;
|
unsigned size = sizeof(Site*) * frameFootprint;
|
||||||
Site** junctionSites = static_cast<Site**>
|
Site** junctionSites = static_cast<Site**>
|
||||||
(c->zone->allocate(size));
|
(c->zone->allocate(size));
|
||||||
memset(junctionSites, 0, size);
|
memset(junctionSites, 0, size);
|
||||||
@ -2365,17 +2320,17 @@ populateSiteTables(Context* c, Event* e)
|
|||||||
|
|
||||||
if (e->junctionSites) {
|
if (e->junctionSites) {
|
||||||
Event* s = e->next;
|
Event* s = e->next;
|
||||||
for (unsigned i = 0; i < c->localCount; ++i) {
|
for (unsigned i = 0; i < c->localFootprint; ++i) {
|
||||||
frozenSiteIndex = resolveJunctionSite
|
frozenSiteIndex = resolveJunctionSite
|
||||||
(c, e, s, s->locals[i], i, frozenSites, frozenSiteIndex);
|
(c, e, s, s->locals[i], i, frozenSites, frozenSiteIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i = s->stack->index + c->localCount;
|
unsigned i = s->stack->index + c->localFootprint;
|
||||||
for (Stack* stack = s->stack; stack; stack = stack->next) {
|
for (Stack* stack = s->stack; stack; stack = stack->next) {
|
||||||
frozenSiteIndex = resolveJunctionSite
|
frozenSiteIndex = resolveJunctionSite
|
||||||
(c, e, s, stack->value, i, frozenSites, frozenSiteIndex);
|
(c, e, s, stack->value, i, frozenSites, frozenSiteIndex);
|
||||||
|
|
||||||
i -= footprint(stack);
|
i -= stack->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2385,18 +2340,18 @@ populateSiteTables(Context* c, Event* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e->successors->next) {
|
if (e->successors->next) {
|
||||||
unsigned size = sizeof(Site*) * frameCount;
|
unsigned size = sizeof(Site*) * frameFootprint;
|
||||||
Site** savedSites = static_cast<Site**>(c->zone->allocate(size));
|
Site** savedSites = static_cast<Site**>(c->zone->allocate(size));
|
||||||
|
|
||||||
for (unsigned i = 0; i < c->localCount; ++i) {
|
for (unsigned i = 0; i < c->localFootprint; ++i) {
|
||||||
savedSites = successor->locals[i]->sites;
|
savedSites[i] = successor->locals[i]->sites;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i = successor->stack->index + c->localCount;
|
unsigned i = successor->stack->index + c->localFootprint;
|
||||||
for (Stack* stack = successor->stack; stack; stack = stack->next) {
|
for (Stack* stack = successor->stack; stack; stack = stack->next) {
|
||||||
savedSites = stack->value->sites;
|
savedSites[i] = stack->value->sites;
|
||||||
|
|
||||||
i -= footprint(stack);
|
i -= stack->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2404,17 +2359,18 @@ populateSiteTables(Context* c, Event* e)
|
|||||||
void
|
void
|
||||||
setSites(Context* c, Event* e, Site** sites)
|
setSites(Context* c, Event* e, Site** sites)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < c->localCount; ++i) {
|
for (unsigned i = 0; i < c->localFootprint; ++i) {
|
||||||
Value* v = e->locals[i];
|
Value* v = e->locals[i];
|
||||||
clearSites(c, v);
|
clearSites(c, v);
|
||||||
addSites(c, v, sites);
|
addSite(c, 0, 0, v->reads->size(c), v, sites[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned i = e->stack->index + c->localCount;
|
unsigned i = e->stack->index + c->localFootprint;
|
||||||
for (Stack* stack = e->stack; stack; stack = stack->next) {
|
for (Stack* stack = e->stack; stack; stack = stack->next) {
|
||||||
Value* v = stack->value;
|
Value* v = stack->value;
|
||||||
clearSites(c, v);
|
clearSites(c, v);
|
||||||
addSites(c, v, sites);
|
addSite(c, 0, 0, v->reads->size(c), v, sites[i]);
|
||||||
|
i -= stack->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2476,18 +2432,16 @@ compile(Context* c)
|
|||||||
Block* firstBlock = block(c, c->firstEvent);
|
Block* firstBlock = block(c, c->firstEvent);
|
||||||
Block* block = firstBlock;
|
Block* block = firstBlock;
|
||||||
|
|
||||||
Assembler::Constant offset(resolved(c, alignedFrameSize(c)));
|
a->allocateFrame(alignedFrameSize(c));
|
||||||
a->apply(PushFrame, BytesPerWord, ConstantOperand, &offset);
|
|
||||||
|
|
||||||
for (Event* e = c->firstEvent; e; e = e->next) {
|
for (Event* e = c->firstEvent; e; e = e->next) {
|
||||||
e->block = block;
|
e->block = block;
|
||||||
|
|
||||||
|
Event* predecessor = static_cast<Event*>(e->predecessors->value);
|
||||||
if (e->predecessors->next) {
|
if (e->predecessors->next) {
|
||||||
setSites
|
setSites(c, e, predecessor->junctionSites);
|
||||||
(c, e, static_cast<Event*>(e->predecessors->value)->junctionSites);
|
} else if (predecessor->successors->next) {
|
||||||
} else if (e->predecessors->successors->next) {
|
setSites(c, e, predecessor->savedSites);
|
||||||
setSites
|
|
||||||
(c, e, static_cast<Event*>(e->predecessors->value)->savedSites);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
populateSources(c, e);
|
populateSources(c, e);
|
||||||
@ -2511,7 +2465,7 @@ compile(Context* c)
|
|||||||
|
|
||||||
block->nextInstruction = nextInstruction;
|
block->nextInstruction = nextInstruction;
|
||||||
block->offset = a->offset();
|
block->offset = a->offset();
|
||||||
Block* block = block(c, e->next);
|
block = ::block(c, e->next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2524,11 +2478,11 @@ compile(Context* c)
|
|||||||
block = firstBlock;
|
block = firstBlock;
|
||||||
while (block->nextInstruction) {
|
while (block->nextInstruction) {
|
||||||
Block* next = block->nextInstruction->firstEvent->block;
|
Block* next = block->nextInstruction->firstEvent->block;
|
||||||
next->start = block->offset->calculate(block->start);
|
next->start = block->offset->resolve(block->start);
|
||||||
block = next;
|
block = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return block->offset->calculate(block->start);
|
return block->offset->resolve(block->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -2553,7 +2507,7 @@ pushState(Context* c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->state = new (c->zone->allocate(sizeof(State)))
|
c->state = new (c->zone->allocate(sizeof(State)))
|
||||||
State(c->state, c->state->stack);
|
State(c->state, c->state->stack, c->state->locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2563,7 +2517,7 @@ saveStack(Context* c)
|
|||||||
LogicalInstruction* i = c->logicalCode[c->logicalIp];
|
LogicalInstruction* i = c->logicalCode[c->logicalIp];
|
||||||
i->stackSaved = true;
|
i->stackSaved = true;
|
||||||
i->stack = c->state->stack;
|
i->stack = c->state->stack;
|
||||||
i->locals = c->locals;
|
i->locals = c->state->locals;
|
||||||
|
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
@ -2577,7 +2531,7 @@ void
|
|||||||
popState(Context* c)
|
popState(Context* c)
|
||||||
{
|
{
|
||||||
c->state = new (c->zone->allocate(sizeof(State)))
|
c->state = new (c->zone->allocate(sizeof(State)))
|
||||||
State(c->state->next->next, c->state->next->stack);
|
State(c->state->next->next, c->state->next->stack, c->state->next->locals);
|
||||||
|
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count;
|
unsigned count = 0; for (State* s = c->state; s; s = s->next) ++ count;
|
||||||
@ -2587,33 +2541,13 @@ popState(Context* c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
updateJunctions(Context* c)
|
|
||||||
{
|
|
||||||
for (Junction* j = c->junctions; j; j = j->next) {
|
|
||||||
LogicalInstruction* i = c->logicalCode[j->logicalIp];
|
|
||||||
LogicalInstruction* p = i->immediatePredecessor;
|
|
||||||
|
|
||||||
p->lastEvent = p->lastEvent->next
|
|
||||||
= new (c->zone->allocate(sizeof(StackSyncEvent)))
|
|
||||||
StackSyncEvent(c, p->lastEvent->sequence, p->stack, p->locals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
visit(Context* c, unsigned logicalIp)
|
visit(Context* c, unsigned logicalIp)
|
||||||
{
|
{
|
||||||
assert(c, logicalIp < c->logicalCodeLength);
|
assert(c, logicalIp < c->logicalCodeLength);
|
||||||
|
|
||||||
LogicalInstruction* i = new (c->zone->allocate(sizeof(LogicalInstruction)))
|
c->logicalCode[logicalIp] = new
|
||||||
LogicalInstruction;
|
(c->zone->allocate(sizeof(LogicalInstruction))) LogicalInstruction;
|
||||||
|
|
||||||
c->logicalCode[logicalIp] = i;
|
|
||||||
|
|
||||||
if (c->logicalIp >= 0 and (not c->stackReset)) {
|
|
||||||
assert(c, i->immediatePredecessor == 0);
|
|
||||||
i->immediatePredecessor = c->logicalCode[c->logicalIp];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Client: public Assembler::Client {
|
class Client: public Assembler::Client {
|
||||||
@ -2695,13 +2629,6 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) {
|
virtual void visitLogicalIp(unsigned logicalIp) {
|
||||||
visit(&c, logicalIp);
|
visit(&c, logicalIp);
|
||||||
|
|
||||||
c.stackReset = false;
|
|
||||||
|
|
||||||
if (c.logicalCode[logicalIp]->immediatePredecessor) {
|
|
||||||
c.junctions = new (c.zone->allocate(sizeof(Junction)))
|
|
||||||
Junction(logicalIp, c.junctions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void startLogicalIp(unsigned logicalIp) {
|
virtual void startLogicalIp(unsigned logicalIp) {
|
||||||
|
@ -601,6 +601,15 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Offset* offset() {
|
||||||
|
// todo
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void endBlock() {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
virtual unsigned length() {
|
virtual unsigned length() {
|
||||||
return c.code.length();
|
return c.code.length();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user