This commit is contained in:
Joel Dice 2008-08-16 11:45:36 -06:00
parent 4299063be9
commit 9efe6f1f05
3 changed files with 370 additions and 247 deletions

View File

@ -17,14 +17,14 @@
namespace vm { namespace vm {
enum Operation { enum Operation {
PopFrame,
Return Return
}; };
const unsigned OperationCount = Return + 1; const unsigned OperationCount = Return + 1;
enum UnaryOperation { enum UnaryOperation {
Push, PushFrame,
Pop,
Call, Call,
LongCall, LongCall,
AlignedCall, AlignedCall,
@ -42,13 +42,16 @@ enum UnaryOperation {
const unsigned UnaryOperationCount = Negate + 1; const unsigned UnaryOperationCount = Negate + 1;
enum BinaryOperation { enum BinaryOperation {
LoadAddress,
Move, Move,
MoveZ, MoveZ,
Move4To8,
Swap, Swap,
Compare
};
const unsigned BinaryOperationCount = Compare + 1;
enum TernaryOperation {
LongCompare, LongCompare,
Compare,
Add, Add,
Subtract, Subtract,
Multiply, Multiply,
@ -62,7 +65,7 @@ enum BinaryOperation {
Xor Xor
}; };
const unsigned BinaryOperationCount = Xor + 1; const unsigned TernaryOperationCount = Xor + 1;
enum OperandType { enum OperandType {
ConstantOperand, ConstantOperand,
@ -156,14 +159,20 @@ class Assembler {
virtual void restore(int r) = 0; virtual void restore(int r) = 0;
}; };
class Offset {
public:
virtual ~Offset() { }
virtual unsigned calculate(unsigned start) = 0;
};
virtual ~Assembler() { } virtual ~Assembler() { }
virtual void setClient(Client* client) = 0; virtual void setClient(Client* client) = 0;
virtual unsigned registerCount() = 0; virtual unsigned registerCount() = 0;
virtual int base() = 0; virtual int frame() = 0;
virtual int stack() = 0;
virtual int thread() = 0; virtual int thread() = 0;
virtual int returnLow() = 0; virtual int returnLow() = 0;
virtual int returnHigh() = 0; virtual int returnHigh() = 0;
@ -171,22 +180,37 @@ class Assembler {
virtual unsigned argumentRegisterCount() = 0; virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0; virtual int argumentRegister(unsigned index) = 0;
virtual unsigned stackAlignment() = 0; virtual void plan
(UnaryOperation op,
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
bool* thunk) = 0;
virtual void plan(UnaryOperation op, unsigned size, uint8_t* typeMask, virtual void plan
uint64_t* registerMask, bool* thunk) = 0; (BinaryOperation op,
unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
bool* thunk) = 0;
virtual void plan(BinaryOperation op, unsigned size, uint8_t* aTypeMask, virtual void plan
uint64_t* aRegisterMask, uint8_t* bTypeMask, (TernaryOperation op,
uint64_t* bRegisterMask, bool* thunk) = 0; unsigned aSize, uint8_t* aTypeMask, uint64_t* aRegisterMask,
unsigned bSize, uint8_t* bTypeMask, uint64_t* bRegisterMask,
unsigned cSize, uint8_t* cTypeMask, uint64_t* cRegisterMask,
bool* thunk) = 0;
virtual void apply(Operation op) = 0; virtual void apply(Operation op) = 0;
virtual void apply(UnaryOperation op, unsigned size, OperandType type, virtual void apply(UnaryOperation op,
Operand* operand) = 0; unsigned aSize, OperandType aType, Operand* aOperand) = 0;
virtual void apply(BinaryOperation op, unsigned size, OperandType aType, virtual void apply(BinaryOperation op,
Operand* a, OperandType bType, Operand* b) = 0; unsigned aSize, OperandType aType, Operand* aOperand,
unsigned bSize, OperandType bType, Operand* bOperand) = 0;
virtual void apply(TernaryOperation op,
unsigned aSize, OperandType aType, Operand* aOperand,
unsigned bSize, OperandType bType, Operand* bOperand,
unsigned cSize, OperandType cType, Operand* cOperand) = 0;
virtual void writeTo(uint8_t* dst) = 0; virtual void writeTo(uint8_t* dst) = 0;
@ -195,6 +219,8 @@ class Assembler {
virtual void updateCall(void* returnAddress, void* newTarget) = 0; virtual void updateCall(void* returnAddress, void* newTarget) = 0;
virtual void dispose() = 0; virtual void dispose() = 0;
static unsigned alignFrameSize(unsigned sizeInWords);
}; };
Assembler* Assembler*

View File

@ -41,26 +41,22 @@ class MyThread: public Thread {
public: public:
CallTrace(MyThread* t): CallTrace(MyThread* t):
t(t), t(t),
base(t->base), frame(t->frame),
stack(t->stack),
nativeMethod(0), nativeMethod(0),
next(t->trace) next(t->trace)
{ {
t->trace = this; t->trace = this;
t->base = 0; t->frame = 0;
t->stack = 0;
} }
~CallTrace() { ~CallTrace() {
t->stack = stack; t->frame = frame;
t->base = base;
t->trace = next; t->trace = next;
} }
MyThread* t; MyThread* t;
void* ip; void* ip;
void* base; void* frame;
void* stack;
object nativeMethod; object nativeMethod;
CallTrace* next; CallTrace* next;
}; };
@ -68,15 +64,13 @@ class MyThread: public Thread {
MyThread(Machine* m, object javaThread, Thread* parent): MyThread(Machine* m, object javaThread, Thread* parent):
Thread(m, javaThread, parent), Thread(m, javaThread, parent),
ip(0), ip(0),
base(0), frame(0),
stack(0),
trace(0), trace(0),
reference(0) reference(0)
{ } { }
void* ip; void* ip;
void* base; void* frame;
void* stack;
CallTrace* trace; CallTrace* trace;
Reference* reference; Reference* reference;
}; };
@ -4311,42 +4305,34 @@ visitStack(MyThread* t, Heap::Visitor* v)
} }
void void
saveStackAndBase(MyThread* t, Assembler* a) saveFrame(MyThread* t, Assembler* a)
{ {
Assembler::Register base(a->base()); Assembler::Register frame(a->frame());
Assembler::Memory baseDst(a->thread(), difference(&(t->base), t)); Assembler::Memory frameDst(a->thread(), difference(&(t->frame), t));
a->apply(Move, BytesPerWord, RegisterOperand, &base, a->apply(Move, BytesPerWord, RegisterOperand, &frame,
MemoryOperand, &baseDst); BytesPerWord, MemoryOperand, &frameDst);
Assembler::Register stack(a->stack());
Assembler::Memory stackDst(a->thread(), difference(&(t->stack), t));
a->apply(Move, BytesPerWord, RegisterOperand, &stack,
MemoryOperand, &stackDst);
} }
void void
pushThread(MyThread*, Assembler* a) pushFrame(MyThread* t, Assembler* a, unsigned size)
{
Assembler::Constant offset(resolved(c, Assembler::alignFrameSize(size)));
a->apply(PushFrame, BytesPerWord, ConstantOperand, &offset);
}
void
setThreadArgument(MyThread*, Assembler* a)
{ {
Assembler::Register thread(a->thread()); Assembler::Register thread(a->thread());
if (a->argumentRegisterCount()) { if (a->argumentRegisterCount()) {
Assembler::Register arg(a->argumentRegister(0)); Assembler::Register arg(a->argumentRegister(0));
a->apply(Move, BytesPerWord, RegisterOperand, &thread, a->apply(Move, BytesPerWord, RegisterOperand, &thread,
RegisterOperand, &arg); BytesPerWord, RegisterOperand, &arg);
} else { } else {
a->apply(Push, BytesPerWord, RegisterOperand, &thread); Assembler::Memory arg(a->frame(), a->argumentPosition(0));
} a->apply(Move, BytesPerWord, RegisterOperand, &thread,
} BytesPerWord, MemoryOperand, &arg);
void
popThread(MyThread*, Assembler* a)
{
if (a->argumentRegisterCount() == 0) {
ResolvedPromise bpwPromise(BytesPerWord);
Assembler::Constant bpw(&bpwPromise);
Assembler::Register stack(a->stack());
a->apply(Add, BytesPerWord, ConstantOperand, &bpw,
RegisterOperand, &stack);
} }
} }
@ -4984,8 +4970,9 @@ compileThunks(MyThread* t, MyProcessor* p)
{ Assembler* a = defaultContext.context.assembler; { Assembler* a = defaultContext.context.assembler;
saveStackAndBase(t, a); saveFrame(t, a);
pushThread(t, a); pushFrame(t, a, 1);
setThreadArgument(t, a);
defaultContext.promise.resolved_ = true; defaultContext.promise.resolved_ = true;
defaultContext.promise.value_ = reinterpret_cast<intptr_t>(compileMethod); defaultContext.promise.value_ = reinterpret_cast<intptr_t>(compileMethod);
@ -4993,7 +4980,7 @@ compileThunks(MyThread* t, MyProcessor* p)
Assembler::Constant proc(&(defaultContext.promise)); Assembler::Constant proc(&(defaultContext.promise));
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
popThread(t, a); a->apply(PopFrame);
Assembler::Register result(a->returnLow()); Assembler::Register result(a->returnLow());
a->apply(Jump, BytesPerWord, RegisterOperand, &result); a->apply(Jump, BytesPerWord, RegisterOperand, &result);
@ -5003,8 +4990,9 @@ compileThunks(MyThread* t, MyProcessor* p)
{ Assembler* a = nativeContext.context.assembler; { Assembler* a = nativeContext.context.assembler;
saveStackAndBase(t, a); saveFrame(t, a);
pushThread(t, a); pushFrame(t, a, 1);
setThreadArgument(t, a);
nativeContext.promise.resolved_ = true; nativeContext.promise.resolved_ = true;
nativeContext.promise.value_ = reinterpret_cast<intptr_t>(invokeNative); nativeContext.promise.value_ = reinterpret_cast<intptr_t>(invokeNative);
@ -5012,7 +5000,7 @@ compileThunks(MyThread* t, MyProcessor* p)
Assembler::Constant proc(&(nativeContext.promise)); Assembler::Constant proc(&(nativeContext.promise));
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc); a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
popThread(t, a); a->apply(PopFrame);
a->apply(Return); a->apply(Return);
} }
@ -5021,8 +5009,9 @@ compileThunks(MyThread* t, MyProcessor* p)
{ Assembler* a = aioobContext.context.assembler; { Assembler* a = aioobContext.context.assembler;
saveStackAndBase(t, a); saveFrame(t, a);
pushThread(t, a); pushFrame(t, a, 1);
setThreadArgument(t, a);
aioobContext.promise.resolved_ = true; aioobContext.promise.resolved_ = true;
aioobContext.promise.value_ = reinterpret_cast<intptr_t> aioobContext.promise.value_ = reinterpret_cast<intptr_t>
@ -5036,7 +5025,7 @@ compileThunks(MyThread* t, MyProcessor* p)
{ Assembler* a = tableContext.context.assembler; { Assembler* a = tableContext.context.assembler;
saveStackAndBase(t, a); saveFrame(t, a);
Assembler::Constant proc(&(tableContext.promise)); Assembler::Constant proc(&(tableContext.promise));
a->apply(LongJump, BytesPerWord, ConstantOperand, &proc); a->apply(LongJump, BytesPerWord, ConstantOperand, &proc);

View File

@ -32,10 +32,19 @@ class Read;
void NO_RETURN abort(Context*); void NO_RETURN abort(Context*);
void void
apply(Context* c, UnaryOperation op, unsigned size, Site* a); apply(Context* c, UnaryOperation op,
unsigned s1Size, Site* s1);
void void
apply(Context* c, BinaryOperation op, unsigned size, Site* a, Site* b); apply(Context* c, BinaryOperation op,
unsigned s1Size, Site* s1,
unsigned s2Size, Site* s2);
void
apply(Context* c, TernaryOperation op,
unsigned s1Size, Site* s1,
unsigned s2Size, Site* s2,
unsigned s3Size, Site* s3);
enum ConstantCompare { enum ConstantCompare {
CompareNone, CompareNone,
@ -221,7 +230,7 @@ class Context {
Compiler::Client* client; Compiler::Client* client;
int logicalIp; int logicalIp;
State* state; State* state;
LogicalInstruction* logicalCode; LogicalInstruction** logicalCode;
unsigned logicalCodeLength; unsigned logicalCodeLength;
unsigned parameterFootprint; unsigned parameterFootprint;
unsigned localFootprint; unsigned localFootprint;
@ -292,7 +301,7 @@ class IpPromise: public Promise {
virtual int64_t value() { virtual int64_t value() {
if (resolved()) { if (resolved()) {
return reinterpret_cast<intptr_t> return reinterpret_cast<intptr_t>
(c->machineCode + c->logicalCode[logicalIp].machineOffset); (c->machineCode + c->logicalCode[logicalIp]->machineOffset->value());
} }
abort(c); abort(c);
@ -334,7 +343,7 @@ class Event {
{ {
assert(c, c->logicalIp >= 0); assert(c, c->logicalIp >= 0);
LogicalInstruction* i = c->logicalCode + c->logicalIp; LogicalInstruction* i = c->logicalCode[c->logicalIp];
if (i->lastEvent) { if (i->lastEvent) {
i->lastEvent->next = this; i->lastEvent->next = this;
} else { } else {
@ -1021,7 +1030,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
} }
if (saveSite) { if (saveSite) {
apply(c, Move, r->size, r->site, saveSite); apply(c, Move, r->size, r->site, r->size, saveSite);
addSite(c, 0, 0, r->size, v, saveSite); addSite(c, 0, 0, r->size, v, saveSite);
} else { } else {
if (DebugRegisters) { if (DebugRegisters) {
@ -1106,7 +1115,8 @@ swap(Context* c, Register* a, Register* b)
Assembler::Register ar(a->number); Assembler::Register ar(a->number);
Assembler::Register br(b->number); Assembler::Register br(b->number);
c->assembler->apply c->assembler->apply
(Swap, BytesPerWord, RegisterOperand, &ar, RegisterOperand, &br); (Swap, BytesPerWord, RegisterOperand, &ar,
BytesPerWord, RegisterOperand, &br);
c->registers[a->number] = b; c->registers[a->number] = b;
c->registers[b->number] = a; c->registers[b->number] = a;
@ -1209,31 +1219,56 @@ validate(Context* c, uint32_t mask, Stack* stack, Value** locals,
Assembler::Register rr(r->number); Assembler::Register rr(r->number);
Assembler::Register cr(current->number); Assembler::Register cr(current->number);
c->assembler->apply c->assembler->apply
(Move, BytesPerWord, RegisterOperand, &cr, RegisterOperand, &rr); (Move, BytesPerWord, RegisterOperand, &cr,
BytesPerWord, RegisterOperand, &rr);
} }
return r; return r;
} }
void void
apply(Context* c, UnaryOperation op, unsigned size, Site* a) apply(Context* c, UnaryOperation op,
unsigned s1Size, Site* s1)
{ {
OperandType type = a->type(c); OperandType s1Type = s1->type(c);
Assembler::Operand* operand = a->asAssemblerOperand(c); Assembler::Operand* s1Operand = s1->asAssemblerOperand(c);
c->assembler->apply(op, size, type, operand); c->assembler->apply(op, s1Size, s1Type, s1Operand);
} }
void void
apply(Context* c, BinaryOperation op, unsigned size, Site* a, Site* b) apply(Context* c, BinaryOperation op,
unsigned s1Size, Site* s1,
unsigned s2Size, Site* s2)
{ {
OperandType aType = a->type(c); OperandType s1Type = s1->type(c);
Assembler::Operand* aOperand = a->asAssemblerOperand(c); Assembler::Operand* s1Operand = s1->asAssemblerOperand(c);
OperandType bType = b->type(c); OperandType s2Type = s2->type(c);
Assembler::Operand* bOperand = b->asAssemblerOperand(c); Assembler::Operand* s2Operand = s2->asAssemblerOperand(c);
c->assembler->apply(op, size, aType, aOperand, bType, bOperand); c->assembler->apply(op, s1Size, s1Type, s1Operand,
s2Size, s2Type, s2Operand);
}
void
apply(Context* c, TernaryOperation op,
unsigned s1Size, Site* s1,
unsigned s2Size, Site* s2,
unsigned s3Size, Site* s3)
{
OperandType s1Type = s1->type(c);
Assembler::Operand* s1Operand = s1->asAssemblerOperand(c);
OperandType s2Type = s2->type(c);
Assembler::Operand* s2Operand = s2->asAssemblerOperand(c);
OperandType s3Type = s3->type(c);
Assembler::Operand* s3Operand = s3->asAssemblerOperand(c);
c->assembler->apply(op, s1Size, s1Type, s1Operand,
s2Size, s2Type, s2Operand,
s3Size, s3Type, s3Operand);
} }
void void
@ -1269,7 +1304,7 @@ insertRead(Context* c, Event* event, int sequence, Value* v, Read* r)
void void
addRead(Context* c, Value* v, Read* r) addRead(Context* c, Value* v, Read* r)
{ {
insertRead(c, c->logicalCode[c->logicalIp].lastEvent, -1, v, r); insertRead(c, c->logicalCode[c->logicalIp]->lastEvent, -1, v, r);
} }
Site* Site*
@ -1355,17 +1390,6 @@ appendPushed(Context* c, Stack* s)
void void
push(Context* c, unsigned size, Value* v); push(Context* c, unsigned size, Value* v);
void
ignore(Context* c, unsigned count)
{
if (count) {
Assembler::Register stack(c->assembler->stack());
Assembler::Constant offset(resolved(c, count * BytesPerWord));
c->assembler->apply
(Add, BytesPerWord, ConstantOperand, &offset, RegisterOperand, &stack);
}
}
void void
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads) cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
{ {
@ -1531,12 +1555,11 @@ class ReturnEvent: public Event {
nextRead(c, value); nextRead(c, value);
} }
Assembler::Register base(c->assembler->base()); Assembler::Register frame(c->assembler->frame());
Assembler::Register stack(c->assembler->stack()); Assembler::Memory oldFrame(c->assembler->frame(), 0);
c->assembler->apply(Move, BytesPerWord, RegisterOperand, &base, c->assembler->apply(Move, BytesPerWord, MemoryOperand, &oldFrame,
RegisterOperand, &stack); BytesPerWord, RegisterOperand, &frame);
c->assembler->apply(Pop, BytesPerWord, RegisterOperand, &base);
c->assembler->apply(Return); c->assembler->apply(Return);
} }
@ -1555,9 +1578,11 @@ appendReturn(Context* c, unsigned size, Value* value)
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 srcSize, Value* src,
Value* dst, Site* srcTarget, VirtualSite* dstTarget): unsigned dstSize, Value* dst, Site* srcTarget,
Event(c), type(type), size(size), src(src), dst(dst), dstTarget(dstTarget) VirtualSite* dstTarget):
Event(c), type(type), srcSize(srcSize), src(src), dstSize(dstSize),
dst(dst), dstTarget(dstTarget)
{ {
addRead(c, src, size, srcTarget); addRead(c, src, size, srcTarget);
} }
@ -1583,25 +1608,25 @@ class MoveEvent: public Event {
} }
if (not isStore) { if (not isStore) {
addSite(c, stack, locals, size, dst, target); addSite(c, stack, locals, dstSize, dst, target);
} }
if (cost or type != Move) { if (cost or type != Move) {
if (match(c, target, dstTarget->typeMask, dstTarget->registerMask)) { if (match(c, target, dstTarget->typeMask, dstTarget->registerMask)) {
apply(c, type, size, src->source, target); apply(c, type, srcSize, src->source, dstSize, target);
} else { } else {
assert(c, dstTarget->typeMask & (1 << RegisterOperand)); assert(c, dstTarget->typeMask & (1 << RegisterOperand));
Site* tmpTarget = freeRegisterSite(c, dstTarget->registerMask); Site* tmpTarget = freeRegisterSite(c, dstTarget->registerMask);
addSite(c, stack, locals, size, dst, tmpTarget); addSite(c, stack, locals, dstSize, dst, tmpTarget);
apply(c, type, size, src->source, tmpTarget); apply(c, type, srcSize, src->source, dstSize, tmpTarget);
if (isStore) { if (isStore) {
removeSite(c, dst, tmpTarget); removeSite(c, dst, tmpTarget);
apply(c, Move, size, tmpTarget, target); apply(c, Move, dstSize, tmpTarget, dstSize, target);
} else { } else {
removeSite(c, dst, target); removeSite(c, dst, target);
} }
@ -1616,8 +1641,9 @@ class MoveEvent: public Event {
} }
BinaryOperation type; BinaryOperation type;
unsigned size; unsigned srcSize;
Value* src; Value* src;
unsigned dstSize;
Value* dst; Value* dst;
VirtualSite* dstTarget; VirtualSite* dstTarget;
}; };
@ -1688,7 +1714,7 @@ class CompareEvent: public Event {
} else { } else {
c->constantCompare = CompareNone; c->constantCompare = CompareNone;
apply(c, Compare, size, first->source, second->source); apply(c, Compare, size, first->source, size, second->source);
} }
nextRead(c, first); nextRead(c, first);
@ -1730,7 +1756,7 @@ preserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s,
Site* r = targetOrNull(c, read); Site* r = targetOrNull(c, read);
if (r == 0 or r == s) r = freeRegisterSite(c); if (r == 0 or r == s) r = freeRegisterSite(c);
addSite(c, stack, locals, size, v, r); addSite(c, stack, locals, size, v, r);
apply(c, Move, size, s, r); apply(c, Move, size, s, size, r);
} }
void void
@ -1743,30 +1769,17 @@ maybePreserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
class CombineEvent: public Event { class CombineEvent: public Event {
public: public:
CombineEvent(Context* c, BinaryOperation type, unsigned size, Value* first, CombineEvent(Context* c, TernaryOperation type,
Value* second, Value* result, Site* firstTarget, unsigned firstSize, Value* first,
Site* secondTarget): unsigned secondSize, Value* second,
Event(c), type(type), size(size), first(first), second(second), unsigned resultSize, Value* result,
Site* firstTarget, Site* secondTarget):
Event(c), type(type), firstSize(firstSize), first(first),
secondSize(secondSize), second(second), resultSize(resultSize),
result(result) result(result)
{ {
// todo: we should really specify the sizes of each operand
// seperately for binary operations. The following is a hack
// until then.
unsigned firstSize;
switch (type) {
case ShiftLeft:
case ShiftRight:
case UnsignedShiftRight:
firstSize = 4;
break;
default:
firstSize = size;
break;
}
addRead(c, first, firstSize, firstTarget); addRead(c, first, firstSize, firstTarget);
addRead(c, second, size, secondTarget); addRead(c, second, secondSize, secondTarget);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1774,23 +1787,26 @@ class CombineEvent: public Event {
fprintf(stderr, "CombineEvent.compile\n"); fprintf(stderr, "CombineEvent.compile\n");
} }
maybePreserve(c, stack, size, second, second->source); maybePreserve(c, stack, secondSize, second, second->source);
apply(c, type, size, first->source, second->source); Site* target = targetOrRegister(c, result);
apply(c, type, firstSize, first->source, secondSize, second->source,
resultSize, target);
nextRead(c, first); nextRead(c, first);
nextRead(c, second); nextRead(c, second);
removeSite(c, second, second->source); if (live(target)) {
if (live(result)) { addSite(c, 0, 0, resultSize, result, target);
addSite(c, 0, 0, size, result, second->source);
} }
} }
BinaryOperation type; BinaryOperation type;
unsigned size; unsigned firstSize;
Value* first; Value* first;
unsigned secondSize;
Value* second; Value* second;
unsigned resultSize;
Value* result; Value* result;
}; };
@ -2340,52 +2356,17 @@ propagateJunctionSites(Context* c, Event* e, Site** sites)
} }
void void
compile(Context* c) frameCount(Context* c, Stack* s)
{ {
Assembler* a = c->assembler; return c->localCount + s->index + footprint(s);
c->pass = CompilePass;
Assembler::Register base(a->base());
Assembler::Register stack(a->stack());
a->apply(Push, BytesPerWord, RegisterOperand, &base);
a->apply(Move, BytesPerWord, RegisterOperand, &stack,
RegisterOperand, &base);
if (stackOffset(c)) {
Assembler::Constant offset(resolved(c, stackOffset(c) * BytesPerWord));
a->apply(Subtract, BytesPerWord, ConstantOperand, &offset,
RegisterOperand, &stack);
} }
for (Event* e = c->firstEvent; e; e = e->next) { void
if (e->predecessors->next) { populateSiteTables(Context* c, Event* e)
setSites(e, static_cast<Event*>(e->predecessors->value)->junctionSites); {
} else if (e->predecessors->successors->next) { Event* successor = static_cast<Event*>(e->successors->value);
setSites(e, static_cast<Event*>(e->predecessors->value)->savedSites);
}
{ Site* frozenSites[e->readCount]; unsigned frameCount = ::frameCount(c, successor->stack);
unsigned frozenSiteIndex = 0;
for (Read* r = e->reads; r; r = r->eventNext) {
r->value->source = readSource(c, e->stack, e->locals, r);
if (r->value->source) {
assert(c, frozenSiteIndex < e->readCount);
frozenSites[frozenSiteIndex++] = r->value->source;
r->value->source->freeze(c);
}
}
while (frozenSiteIndex) {
frozenSites[--frozenSiteIndex]->thaw(c);
}
}
e->compilePresync(c);
unsigned frameCount
= c->localCount + s->stack->index + footprint(s->stack);
{ Site* frozenSites[frameCount]; { Site* frozenSites[frameCount];
unsigned frozenSiteIndex = 0; unsigned frozenSiteIndex = 0;
@ -2439,24 +2420,147 @@ compile(Context* c)
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->localCount; ++i) {
savedSites = s->locals[i]->sites; savedSites = successor->locals[i]->sites;
} }
unsigned i = s->stack->index + c->localCount; unsigned i = successor->stack->index + c->localCount;
for (Stack* stack = s->stack; stack; stack = stack->next) { for (Stack* stack = successor->stack; stack; stack = stack->next) {
savedSites = stack->value->sites; savedSites = stack->value->sites;
i -= footprint(stack); i -= footprint(stack);
} }
} }
}
void
setSites(Context* c, Event* e, Site** sites)
{
for (unsigned i = 0; i < c->localCount; ++i) {
Value* v = e->locals[i];
clearSites(c, v);
addSites(c, v, sites);
}
unsigned i = e->stack->index + c->localCount;
for (Stack* stack = e->stack; stack; stack = stack->next) {
Value* v = stack->value;
clearSites(c, v);
addSites(c, v, sites);
}
}
void
populateSources(Context* c, Event* e)
{
Site* frozenSites[e->readCount];
unsigned frozenSiteIndex = 0;
for (Read* r = e->reads; r; r = r->eventNext) {
r->value->source = readSource(c, e->stack, e->locals, r);
if (r->value->source) {
assert(c, frozenSiteIndex < e->readCount);
frozenSites[frozenSiteIndex++] = r->value->source;
r->value->source->freeze(c);
}
}
while (frozenSiteIndex) {
frozenSites[--frozenSiteIndex]->thaw(c);
}
}
LogicalInstruction*
next(Context* c, LogicalInstruction* i)
{
for (unsigned n = i->index + 1; n < c->logicalCodeLength; ++n) {
i = c->logicalCode[n];
if (i) return i;
}
return 0;
}
class Block {
public:
Block(Event* head):
head(head), nextInstruction(0), offset(0), start(0)
{ }
Event* head;
LogicalInstruction* nextInstruction;
Assembler::Offset* offset;
unsigned start;
};
Block*
block(Context* c, Event* head)
{
return new (c->zone->allocate(sizeof(Block))) Block(head);
}
unsigned
compile(Context* c)
{
Assembler* a = c->assembler;
c->pass = CompilePass;
Block* firstBlock = block(c, c->firstEvent);
Block* block = firstBlock;
Assembler::Constant offset(resolved(c, alignedFrameSize(c)));
a->apply(PushFrame, BytesPerWord, ConstantOperand, &offset);
for (Event* e = c->firstEvent; e; e = e->next) {
e->block = block;
if (e->predecessors->next) {
setSites
(c, e, static_cast<Event*>(e->predecessors->value)->junctionSites);
} else if (e->predecessors->successors->next) {
setSites
(c, e, static_cast<Event*>(e->predecessors->value)->savedSites);
}
populateSources(c, e);
e->compile(c);
if (e->successors) {
populateSiteTables(c, e);
}
e->compilePostsync(c); e->compilePostsync(c);
for (CodePromise* p = e->promises; p; p = p->next) { for (CodePromise* p = e->promises; p; p = p->next) {
p->offset = a->offset(); p->offset = a->offset();
} }
if (e->next and e->logicalInstruction->lastEvent == e) {
LogicalInstruction* nextInstruction = next(c, e->logicalInstruction);
if (nextInstruction != e->next->logicalInstruction) {
a->endBlock();
block->nextInstruction = nextInstruction;
block->offset = a->offset();
Block* block = block(c, e->next);
} }
} }
}
a->endBlock();
block->nextInstruction = 0;
block->offset = a->offset();
block = firstBlock;
while (block->nextInstruction) {
Block* next = block->nextInstruction->firstEvent->block;
next->start = block->offset->calculate(block->start);
block = next;
}
return block->offset->calculate(block->start);
}
unsigned unsigned
count(Stack* s) count(Stack* s)
@ -2486,10 +2590,11 @@ pushState(Context* c)
void void
saveStack(Context* c) saveStack(Context* c)
{ {
if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp].stackSaved) { if (c->logicalIp >= 0 and not c->logicalCode[c->logicalIp]->stackSaved) {
c->logicalCode[c->logicalIp].stackSaved = true; LogicalInstruction* i = c->logicalCode[c->logicalIp];
c->logicalCode[c->logicalIp].stack = c->state->stack; i->stackSaved = true;
c->logicalCode[c->logicalIp].locals = c->locals; i->stack = c->state->stack;
i->locals = c->locals;
if (DebugAppend) { if (DebugAppend) {
unsigned count = 0; unsigned count = 0;
@ -2547,7 +2652,7 @@ void
updateJunctions(Context* c) updateJunctions(Context* c)
{ {
for (Junction* j = c->junctions; j; j = j->next) { for (Junction* j = c->junctions; j; j = j->next) {
LogicalInstruction* i = c->logicalCode + j->logicalIp; LogicalInstruction* i = c->logicalCode[j->logicalIp];
LogicalInstruction* p = i->immediatePredecessor; LogicalInstruction* p = i->immediatePredecessor;
p->lastEvent = p->lastEvent->next p->lastEvent = p->lastEvent->next
@ -2561,10 +2666,14 @@ visit(Context* c, unsigned logicalIp)
{ {
assert(c, logicalIp < c->logicalCodeLength); assert(c, logicalIp < c->logicalCodeLength);
LogicalInstruction* i = new (c->zone->allocate(sizeof(LogicalInstruction)))
LogicalInstruction;
c->logicalCode[logicalIp] = i;
if (c->logicalIp >= 0 and (not c->stackReset)) { if (c->logicalIp >= 0 and (not c->stackReset)) {
assert(c, c->logicalCode[logicalIp].immediatePredecessor == 0); assert(c, i->immediatePredecessor == 0);
c->logicalCode[logicalIp].immediatePredecessor i->immediatePredecessor = c->logicalCode[c->logicalIp];
= c->logicalCode + c->logicalIp;
} }
} }
@ -2635,9 +2744,9 @@ class MyCompiler: public Compiler {
c.parameterFootprint = parameterFootprint; c.parameterFootprint = parameterFootprint;
c.localFootprint = localFootprint; c.localFootprint = localFootprint;
c.logicalCode = static_cast<LogicalInstruction*> c.logicalCode = static_cast<LogicalInstruction**>
(c.zone->allocate(sizeof(LogicalInstruction) * logicalCodeLength)); (c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
memset(c.logicalCode, 0, sizeof(LogicalInstruction) * logicalCodeLength); memset(c.logicalCode, 0, sizeof(LogicalInstruction*) * logicalCodeLength);
c.localTable = static_cast<Local**> c.localTable = static_cast<Local**>
(c.zone->allocate(sizeof(Local*) * localFootprint)); (c.zone->allocate(sizeof(Local*) * localFootprint));
@ -2649,7 +2758,7 @@ class MyCompiler: public Compiler {
c.stackReset = false; c.stackReset = false;
if (c.logicalCode[logicalIp].immediatePredecessor) { if (c.logicalCode[logicalIp]->immediatePredecessor) {
c.junctions = new (c.zone->allocate(sizeof(Junction))) c.junctions = new (c.zone->allocate(sizeof(Junction)))
Junction(logicalIp, c.junctions); Junction(logicalIp, c.junctions);
} }
@ -2739,7 +2848,7 @@ class MyCompiler: public Compiler {
} }
Promise* machineIp() { Promise* machineIp() {
return codePromise(&c, c.logicalCode[c.logicalIp].lastEvent); return codePromise(&c, c.logicalCode[c.logicalIp]->lastEvent);
} }
virtual void mark(Operand* label) { virtual void mark(Operand* label) {
@ -3075,8 +3184,7 @@ class MyCompiler: public Compiler {
virtual unsigned compile() { virtual unsigned compile() {
updateJunctions(&c); updateJunctions(&c);
::compile(&c); return ::compile(&c);
return c.assembler->length();
} }
virtual unsigned poolSize() { virtual unsigned poolSize() {
@ -3085,7 +3193,7 @@ class MyCompiler: public Compiler {
virtual void writeTo(uint8_t* dst) { virtual void writeTo(uint8_t* dst) {
c.machineCode = dst; c.machineCode = dst;
c.assembler->writeTo(dst); c.assembler->writeTo(&c, dst);
int i = 0; int i = 0;
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) { for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {