progress towards refactored JIT compiler to support PowerPC and data flow analysis across control flow boundaries

This commit is contained in:
Joel Dice 2008-08-23 12:04:36 -06:00
parent 9908bbcf50
commit a062d8c975
5 changed files with 179 additions and 280 deletions

View File

@ -173,7 +173,9 @@ class Assembler {
virtual int stack() = 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;
virtual bool reserved(int register_) = 0;
virtual unsigned argumentRegisterCount() = 0; virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0; virtual int argumentRegister(unsigned index) = 0;
@ -214,6 +216,8 @@ class Assembler {
virtual void setClient(Client* client) = 0; virtual void setClient(Client* client) = 0;
virtual Architecture* arch() = 0;
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 popFrame(); virtual void popFrame();

View File

@ -350,8 +350,6 @@ alignedFrameSizeWithParameters(MyThread* t, object method)
int int
localOffset(MyThread* t, int v, object method) localOffset(MyThread* t, int v, object method)
{ {
return alignedFrameSize(t, method) - t->arch->frameHeaderSize() - v;
int parameterFootprint = methodParameterFootprint(t, method) * BytesPerWord; int parameterFootprint = methodParameterFootprint(t, method) * BytesPerWord;
v *= BytesPerWord; v *= BytesPerWord;
@ -3858,7 +3856,8 @@ compile(MyThread* t, Context* context)
unsigned footprint = methodParameterFootprint(t, context->method); unsigned footprint = methodParameterFootprint(t, context->method);
unsigned locals = localSize(t, context->method); unsigned locals = localSize(t, context->method);
c->init(codeLength(t, methodCode(t, context->method)), footprint, locals); c->init(codeLength(t, methodCode(t, context->method)), footprint, locals,
codeMaxStack(t, methodCode(t, context->method)));
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))]; uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
Frame frame(context, stackMap); Frame frame(context, stackMap);

View File

@ -20,6 +20,9 @@ const bool DebugCompile = false;
const bool DebugStack = false; const bool DebugStack = false;
const bool DebugRegisters = false; const bool DebugRegisters = false;
const int AnyFrameIndex = -2;
const int NoFrameIndex = -1;
class Context; class Context;
class Value; class Value;
class Stack; class Stack;
@ -53,6 +56,14 @@ enum ConstantCompare {
CompareEqual CompareEqual
}; };
class Cell {
public:
Cell(Cell* next, void* value): next(next), value(value) { }
Cell* next;
void* value;
};
class Site { class Site {
public: public:
Site(): next(0) { } Site(): next(0) { }
@ -62,6 +73,8 @@ class Site {
virtual Site* readTarget(Context*, Read*) { return this; } virtual Site* readTarget(Context*, Read*) { return this; }
virtual unsigned copyCost(Context*, Site*) = 0; virtual unsigned copyCost(Context*, Site*) = 0;
virtual bool match(Context*, uint8_t, uint64_t, int) = 0;
virtual void acquire(Context*, Stack*, Value**, unsigned, Value*) { } virtual void acquire(Context*, Stack*, Value**, unsigned, Value*) { }
@ -78,7 +91,7 @@ class Site {
Site* next; Site* next;
}; };
class Stack: public StackElement { class Stack: public Compiler::StackElement {
public: public:
Stack(unsigned index, Value* value, Stack* next): Stack(unsigned index, Value* value, Stack* next):
index(index), value(value), next(next) index(index), value(value), next(next)
@ -109,7 +122,7 @@ class LogicalInstruction {
LogicalInstruction* immediatePredecessor; LogicalInstruction* immediatePredecessor;
Stack* stack; Stack* stack;
Value** locals; Value** locals;
unsigned machineOffset; Promise* machineOffset;
bool stackSaved; bool stackSaved;
}; };
@ -193,17 +206,18 @@ class Context {
Compiler::Client* client): Compiler::Client* client):
system(system), system(system),
assembler(assembler), assembler(assembler),
arch(assembler->arch()),
zone(zone), zone(zone),
client(client), client(client),
logicalIp(-1), logicalIp(-1),
state(new (zone->allocate(sizeof(State))) State(0, 0)), state(new (zone->allocate(sizeof(State))) State(0, 0, 0)),
logicalCode(0), logicalCode(0),
logicalCodeLength(0), logicalCodeLength(0),
parameterFootprint(0), parameterFootprint(0),
localFootprint(0), localFootprint(0),
registers registers
(static_cast<Register**> (static_cast<Register**>
(zone->allocate(sizeof(Register*) * assembler->registerCount()))), (zone->allocate(sizeof(Register*) * arch->registerCount()))),
firstConstant(0), firstConstant(0),
lastConstant(0), lastConstant(0),
constantCount(0), constantCount(0),
@ -215,17 +229,15 @@ class Context {
pass(ScanPass), pass(ScanPass),
stackPadding(0) stackPadding(0)
{ {
for (unsigned i = 0; i < assembler->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);
registers[i]->reserved = arch->reserved(i);
} }
registers[assembler->base()]->reserved = true;
registers[assembler->stack()]->reserved = true;
registers[assembler->thread()]->reserved = true;
} }
System* system; System* system;
Assembler* assembler; Assembler* assembler;
Assembler::Architecture* arch;
Zone* zone; Zone* zone;
Compiler::Client* client; Compiler::Client* client;
int logicalIp; int logicalIp;
@ -234,6 +246,7 @@ class Context {
unsigned logicalCodeLength; unsigned logicalCodeLength;
unsigned parameterFootprint; unsigned parameterFootprint;
unsigned localFootprint; unsigned localFootprint;
unsigned maxStackFootprint;
Register** registers; Register** registers;
ConstantPoolNode* firstConstant; ConstantPoolNode* firstConstant;
ConstantPoolNode* lastConstant; ConstantPoolNode* lastConstant;
@ -338,8 +351,9 @@ expect(Context* c, bool v)
class Event { class Event {
public: public:
Event(Context* c): Event(Context* c):
next(0), stack(c->state->stack), locals(c->locals), promises(0), reads(0), next(0), stack(c->state->stack), locals(c->state->locals), promises(0),
readCount(0), sequence(c->nextSequence++), stackReset(c->stackReset) reads(0), readCount(0), sequence(c->nextSequence++),
stackReset(c->stackReset)
{ {
assert(c, c->logicalIp >= 0); assert(c, c->logicalIp >= 0);
@ -357,7 +371,7 @@ class Event {
} }
} }
Event(Context*, unsigned sequence, Stack* stack, Local* 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), readCount(0),
sequence(sequence), stackReset(false) sequence(sequence), stackReset(false)
{ } { }
@ -376,16 +390,30 @@ class Event {
bool stackReset; bool stackReset;
}; };
unsigned
alignedFrameSize(Context* c)
{
return c->arch->alignFrameSize
(c->localFootprint
- c->parameterFootprint
+ c->maxStackFootprint);
}
int int
localOffset(Context* c, int v) localOffset(Context* c, int v)
{ {
int parameterFootprint = c->parameterFootprint * BytesPerWord; int parameterFootprint = c->parameterFootprint * BytesPerWord;
int frameSize = alignedFrameSize(c) * BytesPerWord;
v *= BytesPerWord; v *= BytesPerWord;
if (v < parameterFootprint) { if (v < parameterFootprint) {
return (parameterFootprint - v - BytesPerWord) + (BytesPerWord * 2); return frameSize
+ parameterFootprint
+ c->arch->frameFooterSize()
+ c->arch->frameHeaderSize()
- v;
} else { } else {
return -(v + BytesPerWord - parameterFootprint); return frameSize - c->arch->frameHeaderSize() - v;
} }
} }
@ -480,6 +508,10 @@ class ConstantSite: public Site {
return (s == this ? 0 : 1); return (s == this ? 0 : 1);
} }
virtual bool match(Context*, uint8_t typeMask, uint64_t, int) {
return typeMask & (1 << ConstantOperand);
}
virtual OperandType type(Context*) { virtual OperandType type(Context*) {
return ConstantOperand; return ConstantOperand;
} }
@ -518,6 +550,10 @@ class AddressSite: public Site {
return (s == this ? 0 : 3); return (s == this ? 0 : 3);
} }
virtual bool match(Context*, uint8_t typeMask, uint64_t, int) {
return typeMask & (1 << AddressOperand);
}
virtual OperandType type(Context*) { virtual OperandType type(Context*) {
return AddressOperand; return AddressOperand;
} }
@ -563,8 +599,8 @@ void
release(Context* c, Register* r); release(Context* c, Register* r);
Register* Register*
validate(Context* c, uint32_t mask, Stack* stack, unsigned size, validate(Context* c, uint32_t mask, Stack* stack, Value** locals,
Value* value, RegisterSite* site, Register* current); unsigned size, Value* value, RegisterSite* site, Register* current);
class RegisterSite: public Site { class RegisterSite: public Site {
public: public:
@ -597,6 +633,19 @@ class RegisterSite: public Site {
} }
} }
virtual bool match(Context* c, uint8_t typeMask, uint64_t registerMask, int)
{
if ((typeMask & (1 << RegisterOperand)) and low) {
sync(c);
return ((static_cast<uint64_t>(1) << register_.low) & registerMask)
and (register_.high == NoRegister
or ((static_cast<uint64_t>(1) << (register_.high + 32))
& registerMask));
} else {
return false;
}
}
virtual void acquire(Context* c, Stack* stack, Value** locals, unsigned size, virtual void acquire(Context* c, Stack* stack, Value** locals, unsigned size,
Value* v) Value* v)
{ {
@ -654,9 +703,9 @@ RegisterSite*
registerSite(Context* c, int low, int high = NoRegister) registerSite(Context* c, int low, int high = NoRegister)
{ {
assert(c, low != NoRegister); assert(c, low != NoRegister);
assert(c, low < static_cast<int>(c->assembler->registerCount())); assert(c, low < static_cast<int>(c->arch->registerCount()));
assert(c, high == NoRegister assert(c, high == NoRegister
or high < static_cast<int>(c->assembler->registerCount())); or high < static_cast<int>(c->arch->registerCount()));
Register* hr; Register* hr;
if (high == NoRegister) { if (high == NoRegister) {
@ -720,7 +769,7 @@ decrement(Context* c UNUSED, Register* r)
class MemorySite: public Site { class MemorySite: public Site {
public: public:
MemorySite(int base, int offset, int index, unsigned scale): MemorySite(int base, int offset, int index, unsigned scale):
base(0), index(0), offsetPromise(0), value(base, offset, index, scale) base(0), index(0), value(base, offset, index, scale)
{ } { }
void sync(Context* c UNUSED) { void sync(Context* c UNUSED) {
@ -747,6 +796,22 @@ class MemorySite: public Site {
} }
} }
virtual bool match(Context* c, uint8_t typeMask, uint64_t, int frameIndex) {
if (typeMask & (1 << MemoryOperand)) {
sync(c);
if (value.base == c->arch->stack()) {
assert(c, value.index == NoRegister);
return frameIndex == AnyFrameIndex
|| (frameIndex != NoFrameIndex
&& localOffset(c, frameIndex) == value.offset);
} else {
return false;
}
} else {
return false;
}
}
virtual void acquire(Context* c, Stack*, Value**, unsigned, Value*) { virtual void acquire(Context* c, Stack*, Value**, unsigned, Value*) {
base = increment(c, value.base); base = increment(c, value.base);
if (value.index != NoRegister) { if (value.index != NoRegister) {
@ -783,6 +848,13 @@ memorySite(Context* c, int base, int offset = 0, int index = NoRegister,
MemorySite(base, offset, index, scale); MemorySite(base, offset, index, scale);
} }
MemorySite*
frameSite(Context* c, int frameIndex)
{
assert(c, frameIndex >= 0);
return memorySite(c, c->arch->stack(), localOffset(c, frameIndex));
}
Site* Site*
targetOrNull(Context* c, Value* v, Read* r) targetOrNull(Context* c, Value* v, Read* r)
{ {
@ -801,6 +873,7 @@ targetOrNull(Context* c, Value* v)
if (v->target) { if (v->target) {
return v->target; return v->target;
} else if (live(v)) { } else if (live(v)) {
Read* r = v->reads;
Site* s = r->pickSite(c, v); Site* s = r->pickSite(c, v);
if (s) return s; if (s) return s;
return r->allocateSite(c); return r->allocateSite(c);
@ -839,70 +912,13 @@ allocateSite(Context* c, uint8_t typeMask, uint64_t registerMask,
} }
} }
class TargetRead: public Read {
public:
TargetRead(Value* target, uint8_t typeMask, uint64_t registerMask,
int frameIndex):
target(target), registerMask(registerMask), typeMask(typeMask),
frameIndex(frameIndex)
{ }
virtual Site* pickSite(Context* c, Value* value) {
return ::pickSite(c, value, typeMask, registerMask, frameIndex);
}
virtual Site* allocateSite(Context* c) {
if (target) {
Site* s = targetOrNull(c, target);
if (s and s->match(c, typeMask, registerMask, frameIndex)) {
return s;
}
}
return ::allocateSite(c, typeMask, registerMask, frameIndex);
}
virtual void intersect(uint8_t* typeMask, uint64_t* registerMask,
int* frameIndex)
{
*typeMask &= this->typeMask;
*registerMask &= this->registerMask;
if (*frameIndex == AnyFrameIndex) {
*frameIndex = this->frameIndex;
} else if (this->frameIndex != AnyFrameIndex
and *frameIndex != this->frameIndex)
{
*frameIndex = NoFrameIndex;
}
}
virtual bool valid() {
return true;
}
Value* target;
uint64_t registerMask;
uint8_t typeMask;
int frameIndex;
};
TargetRead*
targetRead(Context* c, Value* target = 0,
uint8_t typeMask = ~static_cast<uint8_t>(0),
uint64_t registerMask = ~static_cast<uint64_t>(0),
int frameIndex = NoFrameIndex)
{
return new (c->zone->allocate(sizeof(TargetRead)))
TargetRead(target, typeMask, registerMask);
}
class MultiRead: public Read { class MultiRead: public Read {
public: public:
MultiRead(): MultiRead():
reads(0) reads(0)
{ } { }
virtual Site* pickSite(Context* c) { virtual Site* pickSite(Context* c, Value* value) {
uint8_t typeMask = ~static_cast<uint8_t>(0); uint8_t typeMask = ~static_cast<uint8_t>(0);
uint64_t registerMask = ~static_cast<uint64_t>(0); uint64_t registerMask = ~static_cast<uint64_t>(0);
int frameIndex = AnyFrameIndex; int frameIndex = AnyFrameIndex;
@ -925,7 +941,7 @@ class MultiRead: public Read {
{ {
for (Cell* cell = reads; cell; cell = cell->next) { for (Cell* cell = reads; cell; cell = cell->next) {
Read* r = static_cast<Read*>(cell->value); Read* r = static_cast<Read*>(cell->value);
r->intersect(&typeMask, &registerMask, &frameIndex); r->intersect(typeMask, registerMask, frameIndex);
} }
} }
@ -948,19 +964,6 @@ multiRead(Context* c)
return new (c->zone->allocate(sizeof(MultiRead))) MultiRead; return new (c->zone->allocate(sizeof(MultiRead))) MultiRead;
} }
VirtualSite*
anyRegisterSite(Context* c)
{
return virtualSite(c, 0, 1 << RegisterOperand, ~static_cast<uint64_t>(0));
}
VirtualSite*
registerOrConstantSite(Context* c)
{
return virtualSite(c, 0, (1 << RegisterOperand) | (1 << ConstantOperand),
~static_cast<uint64_t>(0));
}
Site* Site*
targetOrRegister(Context* c, Value* v) targetOrRegister(Context* c, Value* v)
{ {
@ -1004,7 +1007,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
if (v->sites->next == 0) { if (v->sites->next == 0) {
Site* saveSite = 0; Site* saveSite = 0;
for (unsigned i = 0; i < localFootprint; ++i) { for (unsigned i = 0; i < c->localFootprint; ++i) {
if (locals[i] == v) { if (locals[i] == v) {
saveSite = frameSite(c, i); saveSite = frameSite(c, i);
break; break;
@ -1012,7 +1015,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
} }
if (saveSite == 0) { if (saveSite == 0) {
for (Stack* s = stack; s and (not s->pushed); s = s->next) { for (Stack* s = stack; s; s = s->next) {
if (s->value == v) { if (s->value == v) {
uint8_t typeMask; uint8_t typeMask;
uint64_t registerMask; uint64_t registerMask;
@ -1086,7 +1089,7 @@ pickRegister(Context* c, uint32_t mask)
{ {
Register* register_ = 0; Register* register_ = 0;
unsigned cost = 5; unsigned cost = 5;
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) { for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
if ((1 << i) & mask) { if ((1 << i) & mask) {
Register* r = c->registers[i]; Register* r = c->registers[i];
if ((static_cast<uint32_t>(1) << i) == mask) { if ((static_cast<uint32_t>(1) << i) == mask) {
@ -1307,105 +1310,28 @@ 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*
pushSite(Context*, PushEvent*);
class PushEvent: public Event {
public:
PushEvent(Context* c, Stack* s):
Event(c), s(s), active(false)
{
assert(c, s->pushEvent == 0);
s->pushEvent = this;
addRead(c, s->value, s->geometry->size * BytesPerWord, pushSite(c, this));
}
virtual void compile(Context* c) {
if (DebugCompile) {
fprintf(stderr, "PushEvent.compile active: %d\n", active);
}
if (active) {
pushNow(c, s);
}
nextRead(c, s->value);
}
virtual bool skipMove(unsigned size) {
return active and size >= BytesPerWord;
}
Stack* s;
bool active;
};
void void
appendPush(Context* c, Stack* s) clean(Context* c, Value* v)
{ {
if (DebugAppend) { for (Site** s = &(v->sites); *s;) {
fprintf(stderr, "appendPush\n"); if ((*s)->match(c, 1 << MemoryOperand, 0, AnyFrameIndex)) {
s = &((*s)->next);
} else {
(*s)->release(c);
*s = (*s)->next;
}
} }
new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c, s);
} }
void void
appendPush(Context* c) clean(Context* c, Stack* stack, Value** locals, Read* reads)
{ {
appendPush(c, c->state->stack); for (unsigned i = 0; i < c->localCount; ++i) {
} clean(c, locals[i]);
class PushedEvent: public Event {
public:
PushedEvent(Context* c, Stack* s):
Event(c), s(s)
{ }
virtual void compile(Context* c) {
if (DebugCompile) {
fprintf(stderr, "PushedEvent.compile\n");
}
assert(c, c->stackPadding == 0);
assert(c, s->geometry->padding == 0);
s->pushSite = s->value->sites = pushSite(&c, s);
}
Stack* s;
};
void
appendPushed(Context* c, Stack* s)
{
if (DebugAppend) {
fprintf(stderr, "appendPushed\n");
}
new (c->zone->allocate(sizeof(PushedEvent))) PushedEvent(c, s);
}
void
push(Context* c, unsigned size, Value* v);
void
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
{
for (Local* l = locals; l; l = l->next) {
l->reuse = false;
} }
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
clearSites(c, s->value); clean(c, s->value);
}
for (Stack* s = stack; s; s = s->next) {
if (s->pushSite) {
addSite(c, 0, 0, s->geometry->size * BytesPerWord, s->value,
s->pushSite);
}
} }
for (Read* r = reads; r; r = r->eventNext) { for (Read* r = reads; r; r = r->eventNext) {
@ -1413,15 +1339,6 @@ cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
} }
} }
void
resetLocals(Context* c)
{
for (Local* l = c->locals; l; l = l->next) {
c->localTable[l->index] = 0;
}
c->locals = 0;
}
CodePromise* CodePromise*
codePromise(Context* c, Event* e) codePromise(Context* c, Event* e)
{ {
@ -1439,64 +1356,71 @@ class CallEvent: public Event {
public: public:
CallEvent(Context* c, Value* address, unsigned flags, CallEvent(Context* c, Value* address, unsigned flags,
TraceHandler* traceHandler, Value* result, unsigned resultSize, TraceHandler* traceHandler, Value* result, unsigned resultSize,
Stack* argumentStack, unsigned argumentCount, unsigned padding): Stack* argumentStack, unsigned argumentCount,
unsigned stackArgumentFootprint):
Event(c), Event(c),
address(address), address(address),
traceHandler(traceHandler), traceHandler(traceHandler),
result(result), result(result),
flags(flags), flags(flags),
resultSize(resultSize), resultSize(resultSize)
argumentFootprint(0),
paddding(padding)
{ {
uint32_t mask = ~0; uint32_t mask = ~0;
Stack* s = argumentStack; Stack* s = argumentStack;
unsigned index = 0; unsigned index = 0;
unsigned frameIndex = alignedFrameSize(c) + c->parameterFootprint;
for (unsigned i = 0; i < argumentCount; ++i) { for (unsigned i = 0; i < argumentCount; ++i) {
Site* target; Read* target;
if (index < c->assembler->argumentRegisterCount()) { if (index < c->assembler->argumentRegisterCount()) {
int r = c->assembler->argumentRegister(index); int r = c->assembler->argumentRegister(index);
target = fixedRegisterSite(c, r); target = fixedRegisterRead(c, r);
mask &= ~(1 << r); mask &= ~(1 << r);
} else { } else {
target = 0; frameIndex -= s->geometry->size;
target = read(c, 1 << MemoryOperand, 0, frameIndex);
s->pushEvent->active = true; s->pushEvent->active = true;
argumentFootprint += s->geometry->size;
} }
addRead(c, s->value, s->geometry->size * BytesPerWord, target); addRead(c, s->value, s->geometry->size * BytesPerWord, target);
index += s->geometry->size; index += s->geometry->size;
s = s->next; s = s->next;
} }
addRead(c, address, BytesPerWord, virtualSite addRead(c, address, BytesPerWord, read
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask)); (c, ~0, (static_cast<uint64_t>(mask) << 32) | mask,
AnyFrameIndex));
int footprint = stackArgumentFootprint;
for (Stack* s = stack; s; s = s->next) { for (Stack* s = stack; s; s = s->next) {
s->pushEvent->active = true; if (footprint) {
addRead(c, s->value, s->geometry->size * BytesPerWord, virtualSite addRead(c, s->value, s->geometry->size * BytesPerWord, read
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask)); (c, 1 << MemoryOperand, 0, frameIndex));
} else {
unsigned index = s->geometry->index + c->localFootprint;
if (footprint == 0) {
assert(c, index <= frameIndex);
s->geometry->padding = frameIndex - index;
}
addRead(c, s->value, s->geometry->size * BytesPerWord, read
(c, 1 << MemoryOperand, 0, index));
}
frameIndex -= s->geometry->size;
footprint -= s->geometry->size;
} }
resetLocals(c);
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
if (DebugCompile) { if (DebugCompile) {
fprintf(stderr, "CallEvent.compile\n"); fprintf(stderr, "CallEvent.compile\n");
} }
pushNow(c, stack);
pad(c, padding);
UnaryOperation type = ((flags & Compiler::Aligned) ? AlignedCall : Call); apply(c, (flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord,
apply(c, type, BytesPerWord, address->source); address->source);
if (traceHandler) { if (traceHandler) {
traceHandler->handleTrace(codePromise(c, c->assembler->length())); traceHandler->handleTrace(codePromise(c, c->assembler->length()));
} }
cleanStack(c, stack, locals, reads); clean(c, stack, locals, reads);
if (resultSize and live(result)) { if (resultSize and live(result)) {
addSite(c, 0, 0, resultSize, result, registerSite addSite(c, 0, 0, resultSize, result, registerSite
@ -1504,10 +1428,6 @@ class CallEvent: public Event {
resultSize > BytesPerWord ? resultSize > BytesPerWord ?
c->assembler->returnHigh() : NoRegister)); c->assembler->returnHigh() : NoRegister));
} }
if (argumentFootprint and ((flags & Compiler::NoReturn) == 0)) {
ignore(c, argumentFootprint);
}
} }
Value* address; Value* address;
@ -1515,14 +1435,13 @@ class CallEvent: public Event {
Value* result; Value* result;
unsigned flags; unsigned flags;
unsigned resultSize; unsigned resultSize;
unsigned argumentFootprint;
unsigned padding;
}; };
void void
appendCall(Context* c, Value* address, unsigned flags, appendCall(Context* c, Value* address, unsigned flags,
TraceHandler* traceHandler, Value* result, unsigned resultSize, TraceHandler* traceHandler, Value* result, unsigned resultSize,
Stack* argumentStack, unsigned argumentCount, unsigned padding) Stack* argumentStack, unsigned argumentCount,
unsigned stackArgumentFootprint)
{ {
if (DebugAppend) { if (DebugAppend) {
fprintf(stderr, "appendCall\n"); fprintf(stderr, "appendCall\n");
@ -1530,7 +1449,8 @@ appendCall(Context* c, Value* address, unsigned flags,
new (c->zone->allocate(sizeof(CallEvent))) new (c->zone->allocate(sizeof(CallEvent)))
CallEvent(c, address, flags, traceHandler, result, CallEvent(c, address, flags, traceHandler, result,
resultSize, argumentStack, argumentCount, unsigned padding); resultSize, argumentStack, argumentCount,
stackArgumentFootprint);
} }
class ReturnEvent: public Event { class ReturnEvent: public Event {
@ -1996,31 +1916,6 @@ stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
StackGeometry(size, index), next); StackGeometry(size, index), next);
} }
void
resetStack(Context* c)
{
unsigned i = 0;
Stack* p = 0;
for (Stack* s = c->state->stack; s; s = s->next) {
Stack* n = stack(c, value(c), s->geometry, 0);
n->value->sites = n->pushSite = pushSite(c, s);
n->pushed = true;
if (p) {
p->next = n;
} else {
c->state->stack = n;
}
p = n;
i += s->geometry->size;
}
resetLocals(c);
c->stackReset = true;
}
class StackSyncEvent: public Event { class StackSyncEvent: public Event {
public: public:
StackSyncEvent(Context* c): StackSyncEvent(Context* c):
@ -2047,7 +1942,7 @@ class StackSyncEvent: public Event {
fprintf(stderr, "StackSyncEvent.compile\n"); fprintf(stderr, "StackSyncEvent.compile\n");
} }
cleanStack(c, stack, locals, reads); clean(c, stack, locals, reads);
} }
}; };
@ -2738,11 +2633,12 @@ class MyCompiler: public Compiler {
} }
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint, virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
unsigned localFootprint) unsigned localFootprint, unsigned maxStackFootprint)
{ {
c.logicalCodeLength = logicalCodeLength; c.logicalCodeLength = logicalCodeLength;
c.parameterFootprint = parameterFootprint; c.parameterFootprint = parameterFootprint;
c.localFootprint = localFootprint; c.localFootprint = localFootprint;
c.maxStackFootprint = maxStackFootprint;
c.logicalCode = static_cast<LogicalInstruction**> c.logicalCode = static_cast<LogicalInstruction**>
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength)); (c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
@ -2971,7 +2867,7 @@ class MyCompiler: public Compiler {
Value* result = value(&c); Value* result = value(&c);
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result, appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
resultSize, argumentStack, index, argumentCount ? 0 : padding); resultSize, argumentStack, index, 0);
return result; return result;
} }
@ -2982,25 +2878,9 @@ class MyCompiler: public Compiler {
unsigned resultSize, unsigned resultSize,
unsigned argumentFootprint) unsigned argumentFootprint)
{ {
unsigned padding = c->assembler->stackPadding
(c.state->stack->geometry->index + c.state->stack->geometry->size);
int footprint = argumentFootprint;
for (Stack* s = c.state->stack; s; s = s->next) {
footprint -= s->geometry->size;
if (footprint == 0) {
s->geometry->padding = padding;
}
if (s->pushEvent == 0) {
appendPush(&c, s);
}
s->pushEvent->active = true;
}
Value* result = value(&c); Value* result = value(&c);
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result, appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
resultSize, c.state->stack, 0, argumentFootprint ? 0 : padding); resultSize, c.state->stack, 0, argumentFootprint);
return result; return result;
} }

View File

@ -41,7 +41,7 @@ class Compiler {
virtual void resetStack() = 0; virtual void resetStack() = 0;
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint, virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
unsigned localFootprint) = 0; unsigned localFootprint, unsigned maxStackFootprint) = 0;
virtual void visitLogicalIp(unsigned logicalIp) = 0; virtual void visitLogicalIp(unsigned logicalIp) = 0;
virtual void startLogicalIp(unsigned logicalIp) = 0; virtual void startLogicalIp(unsigned logicalIp) = 0;

View File

@ -385,6 +385,18 @@ class MyArchitecture: public Assembler::Architecture {
return rax; return rax;
} }
virtual bool reserved(int register_) {
switch (register_) {
case rbp:
case rsp:
case rbx:
return true;
default:
return false;
}
}
virtual int returnHigh() { virtual int returnHigh() {
return (BytesPerWord == 4 ? rdx : NoRegister); return (BytesPerWord == 4 ? rdx : NoRegister);
} }
@ -540,8 +552,8 @@ class MyArchitecture: public Assembler::Architecture {
class MyAssembler: public Assembler { class MyAssembler: public Assembler {
public: public:
MyAssembler(System* s, Allocator* a, Zone* zone, ArchitectureContext* ac): MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch):
c(s, a, zone), ac(ac) c(s, a, zone), arch_(arch)
{ } { }
virtual void setClient(Client* client) { virtual void setClient(Client* client) {
@ -549,21 +561,25 @@ class MyAssembler: public Assembler {
c.client = client; c.client = client;
} }
virtual Architecture* arch() {
return arch_;
}
virtual void apply(Operation op) { virtual void apply(Operation op) {
ac->operations[op](&c); arch_->c.operations[op](&c);
} }
virtual void apply(UnaryOperation op, virtual void apply(UnaryOperation op,
unsigned aSize, OperandType aType, Operand* aOperand) unsigned aSize, OperandType aType, Operand* aOperand)
{ {
ac->unaryOperations[index(op, aType)](&c, aSize, aOperand); arch_->c.unaryOperations[index(op, aType)](&c, aSize, aOperand);
} }
virtual void apply(BinaryOperation op, virtual void apply(BinaryOperation op,
unsigned aSize, OperandType aType, Operand* aOperand, unsigned aSize, OperandType aType, Operand* aOperand,
unsigned bSize, OperandType bType, Operand* bOperand) unsigned bSize, OperandType bType, Operand* bOperand)
{ {
ac->binaryOperations[index(op, aType, bType)] arch_->c.binaryOperations[index(op, aType, bType)]
(&c, aSize, aOperand, bSize, bOperand); (&c, aSize, aOperand, bSize, bOperand);
} }
@ -572,7 +588,7 @@ class MyAssembler: public Assembler {
unsigned bSize, OperandType bType, Operand* bOperand, unsigned bSize, OperandType bType, Operand* bOperand,
unsigned cSize, OperandType cType, Operand* cOperand) unsigned cSize, OperandType cType, Operand* cOperand)
{ {
ac->ternaryOperations[index(op, aType, bType, cType)] arch_->c.ternaryOperations[index(op, aType, bType, cType)]
(&c, aSize, aOperand, bSize, bOperand, cSize, cOperand); (&c, aSize, aOperand, bSize, bOperand, cSize, cOperand);
} }
@ -594,7 +610,7 @@ class MyAssembler: public Assembler {
} }
Context c; Context c;
ArchitectureContext* ac; MyArchitecture* arch_;
}; };
} // namespace } // namespace
@ -613,7 +629,7 @@ makeAssembler(System* system, Allocator* allocator, Zone* zone,
{ {
return new (zone->allocate(sizeof(MyAssembler))) return new (zone->allocate(sizeof(MyAssembler)))
MyAssembler(system, allocator, zone, MyAssembler(system, allocator, zone,
&(static_cast<MyArchitecture*>(architecture)->c)); static_cast<MyArchitecture*>(architecture));
} }