support out-of-order compilation in x86 assembler

This commit is contained in:
Joel Dice 2008-09-06 19:37:12 -06:00
parent ed806ca740
commit 9971eaa92a
2 changed files with 57 additions and 7 deletions

View File

@ -120,12 +120,16 @@ class State {
class LogicalInstruction { class LogicalInstruction {
public: public:
LogicalInstruction() {
memset(this, 0, sizeof(LogicalInstruction));
}
Event* firstEvent; Event* firstEvent;
Event* lastEvent; Event* lastEvent;
LogicalInstruction* immediatePredecessor; LogicalInstruction* immediatePredecessor;
Stack* stack; Stack* stack;
Value** locals; Value** locals;
Promise* machineOffset; Assembler::Offset* machineOffset;
int index; int index;
bool stackSaved; bool stackSaved;
}; };
@ -226,6 +230,7 @@ class Context {
lastConstant(0), lastConstant(0),
machineCode(0), machineCode(0),
firstEvent(0), firstEvent(0),
lastEvent(0),
logicalIp(-1), logicalIp(-1),
constantCount(0), constantCount(0),
nextSequence(0), nextSequence(0),
@ -255,6 +260,7 @@ class Context {
ConstantPoolNode* lastConstant; ConstantPoolNode* lastConstant;
uint8_t* machineCode; uint8_t* machineCode;
Event* firstEvent; Event* firstEvent;
Event* lastEvent;
int logicalIp; int logicalIp;
unsigned constantCount; unsigned constantCount;
unsigned nextSequence; unsigned nextSequence;
@ -369,9 +375,14 @@ class Event {
{ {
assert(c, c->logicalIp >= 0); assert(c, c->logicalIp >= 0);
if (logicalInstruction->lastEvent) { if (c->lastEvent) {
logicalInstruction->lastEvent->next = this; c->lastEvent->next = this;
} else { } else {
c->firstEvent = this;
}
c->lastEvent = this;
if (logicalInstruction->firstEvent == 0) {
logicalInstruction->firstEvent = this; logicalInstruction->firstEvent = this;
} }
logicalInstruction->lastEvent = this; logicalInstruction->lastEvent = this;
@ -2475,6 +2486,10 @@ compile(Context* c)
for (Event* e = c->firstEvent; e; e = e->next) { for (Event* e = c->firstEvent; e; e = e->next) {
e->block = block; e->block = block;
if (e->logicalInstruction->machineOffset == 0) {
e->logicalInstruction->machineOffset = a->offset();
}
Event* predecessor = static_cast<Event*>(e->predecessors->value); Event* predecessor = static_cast<Event*>(e->predecessors->value);
if (e->predecessors->next) { if (e->predecessors->next) {
setSites(c, e, predecessor->junctionSites); setSites(c, e, predecessor->junctionSites);

View File

@ -48,10 +48,19 @@ isInt32(intptr_t v)
class Task; class Task;
class Block {
public:
Block(unsigned offset): offset(offset), start(~0) { }
unsigned offset;
unsigned start;
};
class Context { class Context {
public: public:
Context(System* s, Allocator* a, Zone* zone): Context(System* s, Allocator* a, Zone* zone):
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0) s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
block(0)
{ } { }
System* s; System* s;
@ -60,6 +69,7 @@ class Context {
Vector code; Vector code;
Task* tasks; Task* tasks;
uint8_t* result; uint8_t* result;
Block* block;
}; };
typedef void (*OperationType)(Context*); typedef void (*OperationType)(Context*);
@ -924,6 +934,31 @@ class MyArchitecture: public Assembler::Architecture {
unsigned referenceCount; unsigned referenceCount;
}; };
class MyOffset: public Assembler::Offset {
public:
MyOffset(Context* c, Block* block, unsigned offset):
c(c), block(block), offset(offset)
{ }
virtual unsigned resolve(unsigned start) {
block->start = start;
return value();
}
virtual bool resolved() {
return block->start != static_cast<unsigned>(~0);
}
virtual unsigned value() {
assert(c, resolved());
return block->start + (offset - block->offset);
}
Context* c;
Block* block;
unsigned offset;
};
class MyAssembler: public Assembler { class MyAssembler: public Assembler {
public: public:
MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch): MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch):
@ -1043,12 +1078,12 @@ class MyAssembler: public Assembler {
} }
virtual Offset* offset() { virtual Offset* offset() {
// todo return new (c.zone->allocate(sizeof(MyOffset)))
return 0; MyOffset(&c, c.block, c.code.length());
} }
virtual void endBlock() { virtual void endBlock() {
// todo c.block = new (c.zone->allocate(sizeof(Block))) Block(c.code.length());
} }
virtual unsigned length() { virtual unsigned length() {