mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
more bugfixes
This commit is contained in:
parent
8fd1290d02
commit
ab7314e526
@ -1744,12 +1744,26 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} else {
|
} else {
|
||||||
throw_ = c->label();
|
throw_ = c->label();
|
||||||
c->cmp(4, c->constant(0), index);
|
c->cmp(4, c->constant(0), index);
|
||||||
|
|
||||||
|
frame->pushObject(array);
|
||||||
|
frame->pushInt(index);
|
||||||
|
|
||||||
c->jl(throw_);
|
c->jl(throw_);
|
||||||
|
|
||||||
|
index = frame->popInt();
|
||||||
|
array = frame->popObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
c->cmp(BytesPerWord, index, c->memory(array, ArrayLength, 0, 1));
|
c->cmp(BytesPerWord, index, c->memory(array, ArrayLength, 0, 1));
|
||||||
|
|
||||||
|
frame->pushObject(array);
|
||||||
|
frame->pushInt(index);
|
||||||
|
|
||||||
c->jge(load);
|
c->jge(load);
|
||||||
|
|
||||||
|
index = frame->popInt();
|
||||||
|
array = frame->popObject();
|
||||||
|
|
||||||
if (not c->isConstant(index)) {
|
if (not c->isConstant(index)) {
|
||||||
c->mark(throw_);
|
c->mark(throw_);
|
||||||
}
|
}
|
||||||
@ -1762,7 +1776,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
0,
|
0,
|
||||||
3, c->thread(), array, index);
|
3, c->thread(), array, index);
|
||||||
|
|
||||||
|
frame->pushObject(array);
|
||||||
|
frame->pushInt(index);
|
||||||
|
|
||||||
c->mark(load);
|
c->mark(load);
|
||||||
|
|
||||||
|
index = frame->popInt();
|
||||||
|
array = frame->popObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->isConstant(index)) {
|
if (c->isConstant(index)) {
|
||||||
@ -3830,7 +3850,7 @@ finish(MyThread* t, Context* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for debugging:
|
// for debugging:
|
||||||
if (true or//false and
|
if (false and
|
||||||
strcmp
|
strcmp
|
||||||
(reinterpret_cast<const char*>
|
(reinterpret_cast<const char*>
|
||||||
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
||||||
|
378
src/compiler.cpp
378
src/compiler.cpp
@ -43,6 +43,8 @@ class Site {
|
|||||||
|
|
||||||
virtual void acquire(Context*, Stack*, unsigned, Value*, Site*) { }
|
virtual void acquire(Context*, Stack*, unsigned, Value*, Site*) { }
|
||||||
|
|
||||||
|
virtual void release(Context*) { }
|
||||||
|
|
||||||
virtual OperandType type(Context*) = 0;
|
virtual OperandType type(Context*) = 0;
|
||||||
|
|
||||||
virtual Assembler::Operand* asAssemblerOperand(Context*) = 0;
|
virtual Assembler::Operand* asAssemblerOperand(Context*) = 0;
|
||||||
@ -89,6 +91,7 @@ class Register {
|
|||||||
Value* value;
|
Value* value;
|
||||||
Site* site;
|
Site* site;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
unsigned refCount;
|
||||||
bool reserved;
|
bool reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,8 +166,11 @@ class Context {
|
|||||||
{
|
{
|
||||||
memset(registers, 0, sizeof(Register) * assembler->registerCount());
|
memset(registers, 0, sizeof(Register) * assembler->registerCount());
|
||||||
|
|
||||||
|
registers[assembler->base()].refCount = 1;
|
||||||
registers[assembler->base()].reserved = true;
|
registers[assembler->base()].reserved = true;
|
||||||
|
registers[assembler->stack()].refCount = 1;
|
||||||
registers[assembler->stack()].reserved = true;
|
registers[assembler->stack()].reserved = true;
|
||||||
|
registers[assembler->thread()].refCount = 1;
|
||||||
registers[assembler->thread()].reserved = true;
|
registers[assembler->thread()].reserved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,14 +316,6 @@ class Event {
|
|||||||
unsigned logicalIp;
|
unsigned logicalIp;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
addSite(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
|
|
||||||
{
|
|
||||||
s->acquire(c, stack, size, v, s);
|
|
||||||
s->next = v->sites;
|
|
||||||
v->sites = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
findSite(Context*, Value* v, Site* site)
|
findSite(Context*, Value* v, Site* site)
|
||||||
{
|
{
|
||||||
@ -327,11 +325,23 @@ findSite(Context*, Value* v, Site* site)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
addSite(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
|
||||||
|
{
|
||||||
|
if (not findSite(c, v, s)) {
|
||||||
|
fprintf(stderr, "add site %p to %p\n", s, v);
|
||||||
|
s->acquire(c, stack, size, v, s);
|
||||||
|
s->next = v->sites;
|
||||||
|
v->sites = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
removeSite(Context*, Value* v, Site* s)
|
removeSite(Context*, Value* v, Site* s)
|
||||||
{
|
{
|
||||||
for (Site** p = &(v->sites); *p;) {
|
for (Site** p = &(v->sites); *p;) {
|
||||||
if (s == *p) {
|
if (s == *p) {
|
||||||
|
fprintf(stderr, "remove site %p from %p\n", s, v);
|
||||||
*p = (*p)->next;
|
*p = (*p)->next;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -340,6 +350,18 @@ removeSite(Context*, Value* v, Site* s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nextRead(Context* c, Value* v)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "pop read %p from %p; next: %p\n", v->reads, v, v->reads->next);
|
||||||
|
v->reads = v->reads->next;
|
||||||
|
if (v->reads == 0) {
|
||||||
|
for (Site* s = v->sites; s; s = s->next) {
|
||||||
|
s->release(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ConstantSite: public Site {
|
class ConstantSite: public Site {
|
||||||
public:
|
public:
|
||||||
ConstantSite(Promise* value): value(value) { }
|
ConstantSite(Promise* value): value(value) { }
|
||||||
@ -407,6 +429,9 @@ void
|
|||||||
acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
||||||
Site* newSite);
|
Site* newSite);
|
||||||
|
|
||||||
|
void
|
||||||
|
release(Context* c, int r);
|
||||||
|
|
||||||
class RegisterSite: public Site {
|
class RegisterSite: public Site {
|
||||||
public:
|
public:
|
||||||
RegisterSite(int low, int high): register_(low, high) { }
|
RegisterSite(int low, int high): register_(low, high) { }
|
||||||
@ -430,7 +455,16 @@ class RegisterSite: public Site {
|
|||||||
Site* s)
|
Site* s)
|
||||||
{
|
{
|
||||||
::acquire(c, register_.low, stack, size, v, s);
|
::acquire(c, register_.low, stack, size, v, s);
|
||||||
if (register_.high >= 0) ::acquire(c, register_.high, stack, size, v, s);
|
if (register_.high >= 0) {
|
||||||
|
::acquire(c, register_.high, stack, size, v, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void release(Context* c) {
|
||||||
|
::release(c, register_.low);
|
||||||
|
if (register_.high >= 0) {
|
||||||
|
::release(c, register_.high);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual OperandType type(Context*) {
|
virtual OperandType type(Context*) {
|
||||||
@ -447,6 +481,11 @@ class RegisterSite: public Site {
|
|||||||
RegisterSite*
|
RegisterSite*
|
||||||
registerSite(Context* c, int low, int high = NoRegister)
|
registerSite(Context* c, int low, int high = NoRegister)
|
||||||
{
|
{
|
||||||
|
assert(c, low != NoRegister);
|
||||||
|
assert(c, low < static_cast<int>(c->assembler->registerCount()));
|
||||||
|
assert(c, high == NoRegister
|
||||||
|
or high < static_cast<int>(c->assembler->registerCount()));
|
||||||
|
|
||||||
return new (c->zone->allocate(sizeof(RegisterSite)))
|
return new (c->zone->allocate(sizeof(RegisterSite)))
|
||||||
RegisterSite(low, high);
|
RegisterSite(low, high);
|
||||||
}
|
}
|
||||||
@ -475,6 +514,24 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void acquire(Context* c, Stack*, unsigned, Value*, Site*) {
|
||||||
|
fprintf(stderr, "increment ref count for %d\n", value.base);
|
||||||
|
++ c->registers[value.base].refCount;
|
||||||
|
if (value.index != NoRegister) {
|
||||||
|
fprintf(stderr, "increment ref count for %d\n", value.index);
|
||||||
|
++ c->registers[value.index].refCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void release(Context* c) {
|
||||||
|
fprintf(stderr, "decrement ref count for %d\n", value.base);
|
||||||
|
-- c->registers[value.base].refCount;
|
||||||
|
if (value.index != NoRegister) {
|
||||||
|
fprintf(stderr, "decrement ref count for %d\n", value.index);
|
||||||
|
-- c->registers[value.index].refCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual OperandType type(Context*) {
|
virtual OperandType type(Context*) {
|
||||||
return MemoryOperand;
|
return MemoryOperand;
|
||||||
}
|
}
|
||||||
@ -667,7 +724,7 @@ syncStack(Context* c, Stack* start, unsigned count)
|
|||||||
Stack* s = segment[i];
|
Stack* s = segment[i];
|
||||||
assert(c, not s->pushed);
|
assert(c, not s->pushed);
|
||||||
|
|
||||||
if (s->value) {
|
if (s->value and s->value->sites) {
|
||||||
apply(c, Push, s->size * BytesPerWord, pick(c, s->value->sites));
|
apply(c, Push, s->size * BytesPerWord, pick(c, s->value->sites));
|
||||||
++ s->value->pushCount;
|
++ s->value->pushCount;
|
||||||
} else {
|
} else {
|
||||||
@ -699,15 +756,22 @@ void
|
|||||||
acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
||||||
Site* newSite)
|
Site* newSite)
|
||||||
{
|
{
|
||||||
|
if (c->registers[r].reserved) return;
|
||||||
|
|
||||||
|
assert(c, c->registers[r].refCount == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "acquire %d, value %p, site %p\n",
|
||||||
|
r, newValue, newSite);
|
||||||
|
|
||||||
Value* oldValue = c->registers[r].value;
|
Value* oldValue = c->registers[r].value;
|
||||||
if (oldValue
|
if (oldValue
|
||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, c->registers[r].site))
|
and findSite(c, oldValue, c->registers[r].site))
|
||||||
{
|
{
|
||||||
if (oldValue->pushCount == 0
|
fprintf(stderr, "steal %d from %p: push count: %d next: %p\n",
|
||||||
and oldValue->sites->next == 0
|
r, oldValue, oldValue->pushCount, oldValue->sites->next);
|
||||||
and oldValue->reads)
|
|
||||||
{
|
if (oldValue->pushCount == 0 and oldValue->sites->next == 0) {
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
Stack* start = 0;
|
Stack* start = 0;
|
||||||
for (Stack* s = stack; s and (not s->pushed); s = s->next) {
|
for (Stack* s = stack; s and (not s->pushed); s = s->next) {
|
||||||
@ -732,6 +796,14 @@ acquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
c->registers[r].site = newSite;
|
c->registers[r].site = newSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
release(Context* c, int r)
|
||||||
|
{
|
||||||
|
c->registers[r].size = 0;
|
||||||
|
c->registers[r].value = 0;
|
||||||
|
c->registers[r].site = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
apply(Context* c, UnaryOperation op, unsigned size, Site* a)
|
apply(Context* c, UnaryOperation op, unsigned size, Site* a)
|
||||||
{
|
{
|
||||||
@ -759,6 +831,7 @@ insertRead(Context* c, Event* thisEvent, Event* before, Value* v,
|
|||||||
{
|
{
|
||||||
Read* r = new (c->zone->allocate(sizeof(Read)))
|
Read* r = new (c->zone->allocate(sizeof(Read)))
|
||||||
Read(size, v, target, 0, thisEvent, thisEvent->reads);
|
Read(size, v, target, 0, thisEvent, thisEvent->reads);
|
||||||
|
fprintf(stderr, "add read %p to %p\n", r, v);
|
||||||
thisEvent->reads = r;
|
thisEvent->reads = r;
|
||||||
|
|
||||||
if (before) {
|
if (before) {
|
||||||
@ -789,6 +862,31 @@ addRead(Context* c, Value* v, unsigned size, Site* target)
|
|||||||
insertRead(c, c->lastEvent, 0, v, size, target);
|
insertRead(c, c->lastEvent, 0, v, size, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Site*
|
||||||
|
pushSite(Context*, PushEvent*);
|
||||||
|
|
||||||
|
class PushEvent: public Event {
|
||||||
|
public:
|
||||||
|
PushEvent(Context* c):
|
||||||
|
Event(c), active(false)
|
||||||
|
{
|
||||||
|
stack->pushEvent = this;
|
||||||
|
addRead(c, stack->value, stack->size * BytesPerWord, pushSite(c, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void compile(Context* c) {
|
||||||
|
fprintf(stderr, "PushEvent.compile\n");
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
syncStack(c, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
nextRead(c, stack->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
push(Context* c, unsigned size, Value* v);
|
push(Context* c, unsigned size, Value* v);
|
||||||
|
|
||||||
@ -796,7 +894,7 @@ class CallEvent: public Event {
|
|||||||
public:
|
public:
|
||||||
CallEvent(Context* c, Value* address, void* indirection, unsigned flags,
|
CallEvent(Context* c, Value* address, void* indirection, unsigned flags,
|
||||||
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
||||||
unsigned argumentFootprint):
|
Stack* argumentStack, unsigned argumentCount):
|
||||||
Event(c),
|
Event(c),
|
||||||
address(address),
|
address(address),
|
||||||
indirection(indirection),
|
indirection(indirection),
|
||||||
@ -804,8 +902,27 @@ class CallEvent: public Event {
|
|||||||
result(result),
|
result(result),
|
||||||
flags(flags),
|
flags(flags),
|
||||||
resultSize(resultSize),
|
resultSize(resultSize),
|
||||||
argumentFootprint(argumentFootprint)
|
argumentFootprint(0)
|
||||||
{
|
{
|
||||||
|
Stack* s = argumentStack;
|
||||||
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
|
Site* target;
|
||||||
|
if (argumentFootprint < c->assembler->argumentRegisterCount()) {
|
||||||
|
target = registerSite
|
||||||
|
(c, c->assembler->argumentRegister(argumentFootprint));
|
||||||
|
} else {
|
||||||
|
target = 0;
|
||||||
|
s->pushEvent->active = true;
|
||||||
|
}
|
||||||
|
addRead(c, s->value, s->size * BytesPerWord, target);
|
||||||
|
argumentFootprint += s->size;
|
||||||
|
s = s->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
s->pushEvent->active = true;
|
||||||
|
}
|
||||||
|
|
||||||
addRead(c, address, BytesPerWord,
|
addRead(c, address, BytesPerWord,
|
||||||
(indirection ? registerSite(c, c->assembler->returnLow()) : 0));
|
(indirection ? registerSite(c, c->assembler->returnLow()) : 0));
|
||||||
}
|
}
|
||||||
@ -821,10 +938,16 @@ class CallEvent: public Event {
|
|||||||
apply(c, type, BytesPerWord, address->source);
|
apply(c, type, BytesPerWord, address->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
addSite(c, 0, 0, result, registerSite
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
(c, c->assembler->returnLow(),
|
nextRead(c, r->value);
|
||||||
resultSize > BytesPerWord ?
|
}
|
||||||
c->assembler->returnHigh() : NoRegister));
|
|
||||||
|
if (resultSize) {
|
||||||
|
addSite(c, 0, 0, result, registerSite
|
||||||
|
(c, c->assembler->returnLow(),
|
||||||
|
resultSize > BytesPerWord ?
|
||||||
|
c->assembler->returnHigh() : NoRegister));
|
||||||
|
}
|
||||||
|
|
||||||
if (traceHandler) {
|
if (traceHandler) {
|
||||||
traceHandler->handleTrace
|
traceHandler->handleTrace
|
||||||
@ -853,13 +976,13 @@ class CallEvent: public Event {
|
|||||||
void
|
void
|
||||||
appendCall(Context* c, Value* address, void* indirection, unsigned flags,
|
appendCall(Context* c, Value* address, void* indirection, unsigned flags,
|
||||||
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
||||||
unsigned argumentFootprint)
|
Stack* argumentStack, unsigned argumentCount)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "appendCall\n");
|
fprintf(stderr, "appendCall\n");
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(CallEvent)))
|
new (c->zone->allocate(sizeof(CallEvent)))
|
||||||
CallEvent(c, address, indirection, flags, traceHandler, result,
|
CallEvent(c, address, indirection, flags, traceHandler, result,
|
||||||
resultSize, argumentFootprint);
|
resultSize, argumentStack, argumentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReturnEvent: public Event {
|
class ReturnEvent: public Event {
|
||||||
@ -878,6 +1001,10 @@ class ReturnEvent: public Event {
|
|||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "ReturnEvent.compile\n");
|
fprintf(stderr, "ReturnEvent.compile\n");
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
nextRead(c, value);
|
||||||
|
}
|
||||||
|
|
||||||
Assembler::Register base(c->assembler->base());
|
Assembler::Register base(c->assembler->base());
|
||||||
Assembler::Register stack(c->assembler->stack());
|
Assembler::Register stack(c->assembler->stack());
|
||||||
|
|
||||||
@ -929,6 +1056,9 @@ class MoveEvent: public Event {
|
|||||||
apply(c, type, size, src->source, target);
|
apply(c, type, size, src->source, target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextRead(c, src);
|
||||||
|
|
||||||
addSite(c, stack, size, dst, target);
|
addSite(c, stack, size, dst, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,11 +1087,13 @@ class CompareEvent: public Event {
|
|||||||
addRead(c, second, size, 0);
|
addRead(c, second, size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "CompareEvent.compile\n");
|
fprintf(stderr, "CompareEvent.compile\n");
|
||||||
|
|
||||||
apply(c, Compare, size, first->source, second->source);
|
apply(c, Compare, size, first->source, second->source);
|
||||||
|
|
||||||
|
nextRead(c, first);
|
||||||
|
nextRead(c, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
@ -990,6 +1122,8 @@ class BranchEvent: public Event {
|
|||||||
fprintf(stderr, "BranchEvent.compile\n");
|
fprintf(stderr, "BranchEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, BytesPerWord, address->source);
|
apply(c, type, BytesPerWord, address->source);
|
||||||
|
|
||||||
|
nextRead(c, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnaryOperation type;
|
UnaryOperation type;
|
||||||
@ -1029,6 +1163,10 @@ class CombineEvent: public Event {
|
|||||||
fprintf(stderr, "CombineEvent.compile\n");
|
fprintf(stderr, "CombineEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, size, first->source, second->source);
|
apply(c, type, size, first->source, second->source);
|
||||||
|
|
||||||
|
nextRead(c, first);
|
||||||
|
nextRead(c, second);
|
||||||
|
|
||||||
removeSite(c, second, second->source);
|
removeSite(c, second, second->source);
|
||||||
addSite(c, 0, 0, result, second->source);
|
addSite(c, 0, 0, result, second->source);
|
||||||
}
|
}
|
||||||
@ -1063,6 +1201,9 @@ class TranslateEvent: public Event {
|
|||||||
fprintf(stderr, "TranslateEvent.compile\n");
|
fprintf(stderr, "TranslateEvent.compile\n");
|
||||||
|
|
||||||
apply(c, type, size, value->source);
|
apply(c, type, size, value->source);
|
||||||
|
|
||||||
|
nextRead(c, value);
|
||||||
|
|
||||||
removeSite(c, value, value->source);
|
removeSite(c, value, value->source);
|
||||||
addSite(c, 0, 0, result, value->source);
|
addSite(c, 0, 0, result, value->source);
|
||||||
}
|
}
|
||||||
@ -1107,6 +1248,11 @@ class MemoryEvent: public Event {
|
|||||||
assert(c, base->source->type(c) == RegisterOperand);
|
assert(c, base->source->type(c) == RegisterOperand);
|
||||||
int baseRegister = static_cast<RegisterSite*>(base->source)->register_.low;
|
int baseRegister = static_cast<RegisterSite*>(base->source)->register_.low;
|
||||||
|
|
||||||
|
nextRead(c, base);
|
||||||
|
if (index) {
|
||||||
|
nextRead(c, index);
|
||||||
|
}
|
||||||
|
|
||||||
addSite(c, 0, 0, result, memorySite
|
addSite(c, 0, 0, result, memorySite
|
||||||
(c, baseRegister, displacement, indexRegister, scale));
|
(c, baseRegister, displacement, indexRegister, scale));
|
||||||
}
|
}
|
||||||
@ -1132,7 +1278,7 @@ Site*
|
|||||||
stackSyncSite(Context* c, unsigned index, unsigned size)
|
stackSyncSite(Context* c, unsigned index, unsigned size)
|
||||||
{
|
{
|
||||||
int high = NoRegister;
|
int high = NoRegister;
|
||||||
for (int i = c->assembler->registerCount(); i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (not c->registers[i].reserved) {
|
if (not c->registers[i].reserved) {
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
@ -1174,10 +1320,11 @@ class StackSyncEvent: public Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context*) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "StackSyncEvent.compile\n");
|
fprintf(stderr, "StackSyncEvent.compile\n");
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
|
nextRead(c, r->value);
|
||||||
r->value->sites = r->target;
|
r->value->sites = r->target;
|
||||||
r->target->next = 0;
|
r->target->next = 0;
|
||||||
}
|
}
|
||||||
@ -1192,29 +1339,6 @@ appendStackSync(Context* c)
|
|||||||
new (c->zone->allocate(sizeof(StackSyncEvent))) StackSyncEvent(c);
|
new (c->zone->allocate(sizeof(StackSyncEvent))) StackSyncEvent(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
Site*
|
|
||||||
pushSite(Context*, PushEvent*);
|
|
||||||
|
|
||||||
class PushEvent: public Event {
|
|
||||||
public:
|
|
||||||
PushEvent(Context* c):
|
|
||||||
Event(c), active(false)
|
|
||||||
{
|
|
||||||
stack->pushEvent = this;
|
|
||||||
addRead(c, stack->value, stack->size * BytesPerWord, pushSite(c, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
fprintf(stderr, "PushEvent.compile\n");
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
syncStack(c, stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool active;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PushSite: public AbstractSite {
|
class PushSite: public AbstractSite {
|
||||||
public:
|
public:
|
||||||
PushSite(PushEvent* event): event(event) { }
|
PushSite(PushEvent* event): event(event) { }
|
||||||
@ -1244,6 +1368,62 @@ appendPush(Context* c)
|
|||||||
new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c);
|
new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
popNow(Context* c, Event* event, Stack* stack, unsigned count, bool ignore)
|
||||||
|
{
|
||||||
|
Stack* s = stack;
|
||||||
|
unsigned ignored = 0;
|
||||||
|
for (unsigned i = count; i;) {
|
||||||
|
if (s->pushed) {
|
||||||
|
if (s->value->reads and (not ignore)) {
|
||||||
|
assert(c, ignored == 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "pop %p\n", s);
|
||||||
|
|
||||||
|
Site* target = targetOrRegister
|
||||||
|
(c, s->size * BytesPerWord, s->value, event);
|
||||||
|
|
||||||
|
apply(c, Pop, BytesPerWord * s->size, target);
|
||||||
|
-- s->value->pushCount;
|
||||||
|
|
||||||
|
addSite(c, stack, s->size * BytesPerWord, s->value, target);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ignore %p\n", s);
|
||||||
|
|
||||||
|
ignored += s->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->pushed = false;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%p not pushed\n", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
i -= s->size;
|
||||||
|
s = s->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignored) {
|
||||||
|
Assembler::Register stack(c->assembler->stack());
|
||||||
|
Assembler::Constant offset(resolved(c, ignored * BytesPerWord));
|
||||||
|
c->assembler->apply
|
||||||
|
(Add, BytesPerWord, ConstantOperand, &offset, RegisterOperand, &stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
popNow(Context* c, Event* event, Stack* stack, Value* v)
|
||||||
|
{
|
||||||
|
unsigned count = 0;
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
count += s->size;
|
||||||
|
if (s->value == v) {
|
||||||
|
popNow(c, event, stack, count, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
|
||||||
class PopEvent: public Event {
|
class PopEvent: public Event {
|
||||||
public:
|
public:
|
||||||
PopEvent(Context* c, unsigned count, bool ignore):
|
PopEvent(Context* c, unsigned count, bool ignore):
|
||||||
@ -1253,43 +1433,7 @@ class PopEvent: public Event {
|
|||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
fprintf(stderr, "PopEvent.compile\n");
|
fprintf(stderr, "PopEvent.compile\n");
|
||||||
|
|
||||||
Stack* s = stack;
|
popNow(c, this, stack, count, ignore);
|
||||||
unsigned ignored = 0;
|
|
||||||
for (unsigned i = count; i;) {
|
|
||||||
if (s->pushed) {
|
|
||||||
if (s->value->reads and (not ignore)) {
|
|
||||||
assert(c, ignored == 0);
|
|
||||||
|
|
||||||
fprintf(stderr, "pop %p\n", s);
|
|
||||||
|
|
||||||
Site* target = targetOrRegister
|
|
||||||
(c, s->size * BytesPerWord, s->value, this);
|
|
||||||
|
|
||||||
apply(c, Pop, BytesPerWord * s->size, target);
|
|
||||||
-- s->value->pushCount;
|
|
||||||
|
|
||||||
addSite(c, stack, s->size * BytesPerWord, s->value, target);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "ignore %p\n", s);
|
|
||||||
|
|
||||||
ignored += s->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->pushed = false;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%p not pushed\n", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
i -= s->size;
|
|
||||||
s = s->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ignored) {
|
|
||||||
Assembler::Register stack(c->assembler->stack());
|
|
||||||
Assembler::Constant offset(resolved(c, ignored * BytesPerWord));
|
|
||||||
c->assembler->apply
|
|
||||||
(Add, BytesPerWord, ConstantOperand, &offset, RegisterOperand, &stack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned count;
|
unsigned count;
|
||||||
@ -1309,11 +1453,22 @@ readSource(Context* c, Stack* stack, Read* r, Event* e)
|
|||||||
{
|
{
|
||||||
Site* target = (r->target ? r->target->readTarget(c, r, e) : 0);
|
Site* target = (r->target ? r->target->readTarget(c, r, e) : 0);
|
||||||
|
|
||||||
|
fprintf(stderr, "pick from %p\n", r->value);
|
||||||
|
|
||||||
unsigned copyCost;
|
unsigned copyCost;
|
||||||
Site* site = pick(c, r->value->sites, target, ©Cost);
|
Site* site = pick(c, r->value->sites, target, ©Cost);
|
||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
if (copyCost) {
|
if (copyCost) {
|
||||||
|
if (site == 0) {
|
||||||
|
assert(c, r->value->pushCount);
|
||||||
|
|
||||||
|
popNow(c, e, stack, r->value);
|
||||||
|
|
||||||
|
site = pick(c, r->value->sites, target, ©Cost);
|
||||||
|
assert(c, site);
|
||||||
|
}
|
||||||
|
|
||||||
addSite(c, stack, r->size, r->value, target);
|
addSite(c, stack, r->size, r->value, target);
|
||||||
|
|
||||||
apply(c, Move, r->size, site, target);
|
apply(c, Move, r->size, site, target);
|
||||||
@ -1343,6 +1498,8 @@ compile(Context* c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Event* e = c->firstEvent; e; e = e->next) {
|
for (Event* e = c->firstEvent; e; e = e->next) {
|
||||||
|
fprintf(stderr, "ip: %d\n", e->logicalIp);
|
||||||
|
|
||||||
LogicalInstruction* li = c->logicalCode + e->logicalIp;
|
LogicalInstruction* li = c->logicalCode + e->logicalIp;
|
||||||
li->machineOffset = a->length();
|
li->machineOffset = a->length();
|
||||||
|
|
||||||
@ -1350,10 +1507,6 @@ compile(Context* c)
|
|||||||
r->value->source = readSource(c, e->stack, r, e);
|
r->value->source = readSource(c, e->stack, r, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Read* r = e->reads; r; r = r->eventNext) {
|
|
||||||
r->value->reads = r->value->reads->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->compile(c);
|
e->compile(c);
|
||||||
|
|
||||||
for (CodePromise* p = e->promises; p; p = p->next) {
|
for (CodePromise* p = e->promises; p; p = p->next) {
|
||||||
@ -1442,7 +1595,9 @@ bool
|
|||||||
used(Context* c, int r)
|
used(Context* c, int r)
|
||||||
{
|
{
|
||||||
Value* v = c->registers[r].value;
|
Value* v = c->registers[r].value;
|
||||||
return v and findSite(c, v, c->registers[r].site) and v->reads;
|
fprintf(stderr, "v: %p found: %d\n",
|
||||||
|
v, v and findSite(c, v, c->registers[r].site));
|
||||||
|
return v and findSite(c, v, c->registers[r].site);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -1459,7 +1614,7 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
{
|
{
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and (not c->registers[i].reserved)
|
and c->registers[i].refCount == 0
|
||||||
and (not used(c, i)))
|
and (not used(c, i)))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
@ -1468,7 +1623,7 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
|
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and (not c->registers[i].reserved)
|
and c->registers[i].refCount == 0
|
||||||
and (not usedExclusively(c, i)))
|
and (not usedExclusively(c, i)))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
@ -1478,7 +1633,7 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
if (allowAcquired) {
|
if (allowAcquired) {
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and (not c->registers[i].reserved))
|
and c->registers[i].refCount == 0)
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -1491,7 +1646,9 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
|
|||||||
int
|
int
|
||||||
freeRegister(Context* c, bool allowAcquired)
|
freeRegister(Context* c, bool allowAcquired)
|
||||||
{
|
{
|
||||||
return freeRegisterExcept(c, NoRegister, allowAcquired);
|
int r = freeRegisterExcept(c, NoRegister, allowAcquired);
|
||||||
|
fprintf(stderr, "free reg: %d\n", r);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterSite*
|
RegisterSite*
|
||||||
@ -1513,15 +1670,16 @@ class Client: public Assembler::Client {
|
|||||||
if (r == NoRegister) {
|
if (r == NoRegister) {
|
||||||
r = freeRegisterExcept(c, NoRegister, false);
|
r = freeRegisterExcept(c, NoRegister, false);
|
||||||
} else {
|
} else {
|
||||||
expect(c, not c->registers[r].reserved);
|
expect(c, c->registers[r].refCount == 0);
|
||||||
expect(c, c->registers[r].value == 0);
|
expect(c, c->registers[r].value == 0);
|
||||||
}
|
}
|
||||||
c->registers[r].reserved = true;
|
++ c->registers[r].refCount;
|
||||||
|
fprintf(stderr, "acquire temporary: %d\n", r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void releaseTemporary(int r) {
|
virtual void releaseTemporary(int r) {
|
||||||
c->registers[r].reserved = false;
|
-- c->registers[r].refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context* c;
|
Context* c;
|
||||||
@ -1734,34 +1892,18 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
Stack* oldStack = c.state->stack;
|
Stack* oldStack = c.state->stack;
|
||||||
|
|
||||||
for (int i = index - 1; i >= 0; --i) {
|
fprintf(stderr, "argument count: %d\n", argumentCount);
|
||||||
|
for (int i = argumentCount - 1; i >= 0; --i) {
|
||||||
::push(&c, argumentSizes[i], arguments[i]);
|
::push(&c, argumentSizes[i], arguments[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ai = 0;
|
Stack* argumentStack = c.state->stack;
|
||||||
Stack* s = c.state->stack;
|
|
||||||
for (unsigned i = 0; i < index; ++i) {
|
|
||||||
Site* target;
|
|
||||||
if (ai < c.assembler->argumentRegisterCount()) {
|
|
||||||
target = registerSite(&c, c.assembler->argumentRegister(index));
|
|
||||||
} else {
|
|
||||||
target = 0;
|
|
||||||
s->pushEvent->active = true;
|
|
||||||
}
|
|
||||||
addRead(&c, s->value, s->size * BytesPerWord, target);
|
|
||||||
ai += s->size;
|
|
||||||
s = s->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
c.state->stack = oldStack;
|
c.state->stack = oldStack;
|
||||||
|
|
||||||
for (Stack* s = oldStack; s; s = s->next) {
|
|
||||||
s->pushEvent->active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* result = value(&c);
|
Value* result = value(&c);
|
||||||
appendCall(&c, static_cast<Value*>(address), indirection, flags,
|
appendCall(&c, static_cast<Value*>(address), indirection, flags,
|
||||||
traceHandler, result, resultSize, footprint);
|
traceHandler, result, resultSize, argumentStack,
|
||||||
|
index);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
12
src/x86.cpp
12
src/x86.cpp
@ -703,7 +703,7 @@ void
|
|||||||
moveMM(Context* c, unsigned size, Assembler::Memory* a,
|
moveMM(Context* c, unsigned size, Assembler::Memory* a,
|
||||||
Assembler::Memory* b)
|
Assembler::Memory* b)
|
||||||
{
|
{
|
||||||
assert(c, BytesPerWord == 8 or size == 4); // todo
|
assert(c, BytesPerWord == 8 or size <= 4); // todo
|
||||||
|
|
||||||
Assembler::Register tmp(c->client->acquireTemporary());
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
moveMR(c, size, a, &tmp);
|
moveMR(c, size, a, &tmp);
|
||||||
@ -937,6 +937,15 @@ compareRM(Context* c, unsigned size UNUSED, Assembler::Register* a,
|
|||||||
encode(c, 0x39, a->low, b, true);
|
encode(c, 0x39, a->low, b, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compareMR(Context* c, unsigned size UNUSED, Assembler::Memory* a,
|
||||||
|
Assembler::Register* b)
|
||||||
|
{
|
||||||
|
assert(c, BytesPerWord == 8 or size == 4); // todo
|
||||||
|
|
||||||
|
encode(c, 0x3b, b->low, a, true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compareMM(Context* c, unsigned size UNUSED, Assembler::Memory* a,
|
compareMM(Context* c, unsigned size UNUSED, Assembler::Memory* a,
|
||||||
Assembler::Memory* b)
|
Assembler::Memory* b)
|
||||||
@ -1015,6 +1024,7 @@ populateTables()
|
|||||||
BinaryOperations[INDEX2(Compare, Constant, Register)] = CAST2(compareCR);
|
BinaryOperations[INDEX2(Compare, Constant, Register)] = CAST2(compareCR);
|
||||||
BinaryOperations[INDEX2(Compare, Register, Register)] = CAST2(compareRR);
|
BinaryOperations[INDEX2(Compare, Register, Register)] = CAST2(compareRR);
|
||||||
BinaryOperations[INDEX2(Compare, Register, Memory)] = CAST2(compareRM);
|
BinaryOperations[INDEX2(Compare, Register, Memory)] = CAST2(compareRM);
|
||||||
|
BinaryOperations[INDEX2(Compare, Memory, Register)] = CAST2(compareMR);
|
||||||
BinaryOperations[INDEX2(Compare, Constant, Memory)] = CAST2(compareCM);
|
BinaryOperations[INDEX2(Compare, Constant, Memory)] = CAST2(compareCM);
|
||||||
BinaryOperations[INDEX2(Compare, Memory, Memory)] = CAST2(compareMM);
|
BinaryOperations[INDEX2(Compare, Memory, Memory)] = CAST2(compareMM);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user