mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
move use of SingleRead::successor; fix build errors
We now use SingleRead::successor in pickTarget, where we use it to determine the prefered target site for the successor without requiring the target to conform to that preference. The previous code made the preference a hard requirement, which is not desirable or even possible in general.
This commit is contained in:
parent
35d1c6e068
commit
dba72409aa
@ -31,6 +31,7 @@ enum UnaryOperation {
|
||||
AlignedCall,
|
||||
Jump,
|
||||
LongJump,
|
||||
AlignedJump,
|
||||
JumpIfLess,
|
||||
JumpIfGreater,
|
||||
JumpIfLessOrEqual,
|
||||
@ -318,7 +319,9 @@ class Assembler {
|
||||
|
||||
virtual Architecture* arch() = 0;
|
||||
|
||||
virtual void popReturnAddress(unsigned addressOffset) = 0;
|
||||
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) = 0;
|
||||
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) = 0;
|
||||
virtual void pushFrame(unsigned argumentCount, ...) = 0;
|
||||
virtual void allocateFrame(unsigned footprint) = 0;
|
||||
virtual void popFrame() = 0;
|
||||
|
@ -1957,7 +1957,7 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
|
||||
rSize,
|
||||
methodParameterFootprint(t, target));
|
||||
} else {
|
||||
unsigned flags = (tailCall ? Compiler::TailCall : 0);
|
||||
unsigned flags = (tailCall ? Compiler::TailJump : 0);
|
||||
|
||||
if (useThunk) {
|
||||
if (tailCall) {
|
||||
@ -6450,6 +6450,8 @@ compileVirtualThunk(MyThread* t, unsigned index)
|
||||
(codeAllocator(t)->allocate(a->length()));
|
||||
|
||||
a->writeTo(start);
|
||||
|
||||
return reinterpret_cast<uintptr_t>(start);
|
||||
}
|
||||
|
||||
uintptr_t
|
||||
|
144
src/compiler.cpp
144
src/compiler.cpp
@ -257,6 +257,8 @@ class Read {
|
||||
{ }
|
||||
|
||||
virtual bool intersect(SiteMask* mask) = 0;
|
||||
|
||||
virtual Value* successor() = 0;
|
||||
|
||||
virtual bool valid() = 0;
|
||||
|
||||
@ -286,13 +288,6 @@ intersect(const SiteMask& a, const SiteMask& b)
|
||||
intersectFrameIndexes(a.frameIndex, b.frameIndex));
|
||||
}
|
||||
|
||||
bool
|
||||
valid(const SiteMask& a)
|
||||
{
|
||||
return a.typeMask
|
||||
and ((a.typeMask & ~(1 << RegisterOperand)) or a.registerMask);
|
||||
}
|
||||
|
||||
class Value: public Compiler::Operand {
|
||||
public:
|
||||
Value(Site* site, Site* target):
|
||||
@ -1191,18 +1186,11 @@ pickAnyFrameTarget(Context* c, Value* v)
|
||||
}
|
||||
|
||||
Target
|
||||
pickTarget(Context* c, Read* read, bool intersectRead,
|
||||
unsigned registerReserveCount)
|
||||
pickTarget(Context* c, Value* value, const SiteMask& mask,
|
||||
unsigned registerPenalty, Target best)
|
||||
{
|
||||
SiteMask mask;
|
||||
read->intersect(&mask);
|
||||
|
||||
unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
|
||||
? 0 : Target::Penalty);
|
||||
|
||||
Target best;
|
||||
if (mask.typeMask & (1 << RegisterOperand)) {
|
||||
Target mine = pickRegisterTarget(c, read->value, mask.registerMask);
|
||||
Target mine = pickRegisterTarget(c, value, mask.registerMask);
|
||||
|
||||
mine.cost += registerPenalty;
|
||||
|
||||
@ -1215,7 +1203,7 @@ pickTarget(Context* c, Read* read, bool intersectRead,
|
||||
|
||||
if ((mask.typeMask & (1 << MemoryOperand)) && mask.frameIndex >= 0) {
|
||||
Target mine(mask.frameIndex, MemoryOperand,
|
||||
frameCost(c, read->value, mask.frameIndex));
|
||||
frameCost(c, value, mask.frameIndex));
|
||||
if (mine.cost == 0) {
|
||||
return mine;
|
||||
} else if (mine.cost < best.cost) {
|
||||
@ -1223,6 +1211,40 @@ pickTarget(Context* c, Read* read, bool intersectRead,
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
Target
|
||||
pickTarget(Context* c, Read* read, bool intersectRead,
|
||||
unsigned registerReserveCount)
|
||||
{
|
||||
unsigned registerPenalty = (c->availableRegisterCount > registerReserveCount
|
||||
? 0 : Target::Penalty);
|
||||
|
||||
SiteMask mask;
|
||||
read->intersect(&mask);
|
||||
|
||||
Target best;
|
||||
|
||||
Value* successor = read->successor();
|
||||
if (successor) {
|
||||
Read* r = live(successor);
|
||||
if (r) {
|
||||
SiteMask intersection = mask;
|
||||
if (r->intersect(&intersection)) {
|
||||
best = pickTarget(c, read->value, mask, registerPenalty, best);
|
||||
if (best.cost == 0) {
|
||||
return best;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best = pickTarget(c, read->value, mask, registerPenalty, best);
|
||||
if (best.cost == 0) {
|
||||
return best;
|
||||
}
|
||||
|
||||
if (intersectRead) {
|
||||
return best;
|
||||
}
|
||||
@ -1887,27 +1909,18 @@ release(Context* c, Resource* resource, Value* value UNUSED, Site* site UNUSED)
|
||||
class SingleRead: public Read {
|
||||
public:
|
||||
SingleRead(const SiteMask& mask, Value* successor):
|
||||
next_(0), mask(mask), successor(successor)
|
||||
next_(0), mask(mask), successor_(successor)
|
||||
{ }
|
||||
|
||||
virtual bool intersect(SiteMask* mask) {
|
||||
SiteMask result = ::intersect(*mask, this->mask);
|
||||
|
||||
if (successor) {
|
||||
Read* r = live(successor);
|
||||
if (r) {
|
||||
SiteMask intersection = result;
|
||||
bool valid = r->intersect(&intersection);
|
||||
if (valid and ::valid(intersection)) {
|
||||
result = intersection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*mask = result;
|
||||
*mask = ::intersect(*mask, this->mask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Value* successor() {
|
||||
return successor_;
|
||||
}
|
||||
|
||||
virtual bool valid() {
|
||||
return true;
|
||||
@ -1924,7 +1937,7 @@ class SingleRead: public Read {
|
||||
|
||||
Read* next_;
|
||||
SiteMask mask;
|
||||
Value* successor;
|
||||
Value* successor_;
|
||||
};
|
||||
|
||||
Read*
|
||||
@ -1981,6 +1994,10 @@ class MultiRead: public Read {
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Value* successor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool valid() {
|
||||
bool result = false;
|
||||
if (not visited) {
|
||||
@ -2008,7 +2025,7 @@ class MultiRead: public Read {
|
||||
}
|
||||
lastRead = cell;
|
||||
|
||||
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
|
||||
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
|
||||
|
||||
lastTarget->value = r;
|
||||
}
|
||||
@ -2020,7 +2037,7 @@ class MultiRead: public Read {
|
||||
void allocateTarget(Context* c) {
|
||||
Cell* cell = cons(c, 0, 0);
|
||||
|
||||
// fprintf(stderr, "allocate target for %p: %p\n", this, cell);
|
||||
// fprintf(stderr, "allocate target for %p: %p\n", this, cell);
|
||||
|
||||
if (lastTarget) {
|
||||
lastTarget->next = cell;
|
||||
@ -2031,7 +2048,7 @@ class MultiRead: public Read {
|
||||
}
|
||||
|
||||
Read* nextTarget() {
|
||||
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
|
||||
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
|
||||
|
||||
Read* r = static_cast<Read*>(firstTarget->value);
|
||||
firstTarget = firstTarget->next;
|
||||
@ -2071,6 +2088,10 @@ class StubRead: public Read {
|
||||
return valid_;
|
||||
}
|
||||
|
||||
virtual Value* successor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool valid() {
|
||||
return valid_;
|
||||
}
|
||||
@ -2180,9 +2201,9 @@ addRead(Context* c, Event* e, Value* v, Read* r)
|
||||
}
|
||||
|
||||
if (v->lastRead) {
|
||||
// if (DebugReads) {
|
||||
// fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v);
|
||||
// }
|
||||
// if (DebugReads) {
|
||||
// fprintf(stderr, "append %p to %p for %p\n", r, v->lastRead, v);
|
||||
// }
|
||||
|
||||
v->lastRead->append(c, r);
|
||||
} else {
|
||||
@ -2334,7 +2355,7 @@ class CallEvent: public Event {
|
||||
(typeMask, registerMask & planRegisterMask, AnyFrameIndex)));
|
||||
}
|
||||
|
||||
if ((flags & (Compiler::TailJump | Compiler::TailCall)_ == 0) {
|
||||
if ((flags & (Compiler::TailJump | Compiler::TailCall)) == 0) {
|
||||
int footprint = stackArgumentFootprint;
|
||||
for (Stack* s = stackBefore; s; s = s->next) {
|
||||
if (s->value) {
|
||||
@ -2932,7 +2953,7 @@ getTarget(Context* c, Value* value, Value* result, const SiteMask& resultMask)
|
||||
preserve(c, v, s, r);
|
||||
}
|
||||
} else {
|
||||
SingleRead r(resultMask);
|
||||
SingleRead r(resultMask, 0);
|
||||
s = pickTargetSite(c, &r, true);
|
||||
v = result;
|
||||
addSite(c, result, s);
|
||||
@ -3017,7 +3038,7 @@ class CombineEvent: public Event {
|
||||
? getTarget(c, second->high, result->high, resultHighMask)
|
||||
: 0);
|
||||
|
||||
// fprintf(stderr, "combine %p and %p into %p\n", first, second, result);
|
||||
// fprintf(stderr, "combine %p and %p into %p\n", first, second, result);
|
||||
apply(c, type, firstSize, first->source, source(first->high),
|
||||
secondSize, second->source, source(second->high),
|
||||
resultSize, low, high);
|
||||
@ -3783,11 +3804,11 @@ frameFootprint(Context* c, Stack* s)
|
||||
void
|
||||
visit(Context* c, Link* link)
|
||||
{
|
||||
// fprintf(stderr, "visit link from %d to %d fork %p junction %p\n",
|
||||
// link->predecessor->logicalInstruction->index,
|
||||
// link->successor->logicalInstruction->index,
|
||||
// link->forkState,
|
||||
// link->junctionState);
|
||||
// fprintf(stderr, "visit link from %d to %d fork %p junction %p\n",
|
||||
// link->predecessor->logicalInstruction->index,
|
||||
// link->successor->logicalInstruction->index,
|
||||
// link->forkState,
|
||||
// link->junctionState);
|
||||
|
||||
ForkState* forkState = link->forkState;
|
||||
if (forkState) {
|
||||
@ -3795,7 +3816,7 @@ visit(Context* c, Link* link)
|
||||
ForkElement* p = forkState->elements + i;
|
||||
Value* v = p->value;
|
||||
v->reads = p->read->nextTarget();
|
||||
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
|
||||
// fprintf(stderr, "next read %p for %p from %p\n", v->reads, v, p->read);
|
||||
if (not live(v)) {
|
||||
clearSites(c, v);
|
||||
}
|
||||
@ -3828,7 +3849,7 @@ class BuddyEvent: public Event {
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
// fprintf(stderr, "original %p buddy %p\n", original, buddy);
|
||||
// fprintf(stderr, "original %p buddy %p\n", original, buddy);
|
||||
assert(c, hasSite(original));
|
||||
|
||||
addBuddy(original, buddy);
|
||||
@ -3886,7 +3907,7 @@ class FreezeRegisterEvent: public Event {
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
c->registers[number].freeze(c, value);
|
||||
c->registerResources[number].freeze(c, value);
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
popRead(c, this, r->value);
|
||||
@ -3915,17 +3936,17 @@ class ThawRegisterEvent: public Event {
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
c->registers[number].thaw(c, value);
|
||||
c->registerResources[number].thaw(c, 0);
|
||||
}
|
||||
|
||||
int number;
|
||||
};
|
||||
|
||||
void
|
||||
appendThawRegister(Context* c, int number, Value* value)
|
||||
appendThawRegister(Context* c, int number)
|
||||
{
|
||||
append(c, new (c->zone->allocate(sizeof(ThawRegisterEvent)))
|
||||
ThawRegisterEvent(c, number, value));
|
||||
ThawRegisterEvent(c, number));
|
||||
}
|
||||
|
||||
class DummyEvent: public Event {
|
||||
@ -4418,9 +4439,9 @@ void
|
||||
restore(Context* c, Event* e, Snapshot* snapshots)
|
||||
{
|
||||
for (Snapshot* s = snapshots; s; s = s->next) {
|
||||
// char buffer[256]; sitesToString(c, s->sites, buffer, 256);
|
||||
// fprintf(stderr, "restore %p buddy %p sites %s live %p\n",
|
||||
// s->value, s->value->buddy, buffer, live(s->value));
|
||||
// char buffer[256]; sitesToString(c, s->sites, buffer, 256);
|
||||
// fprintf(stderr, "restore %p buddy %p sites %s live %p\n",
|
||||
// s->value, s->value->buddy, buffer, live(s->value));
|
||||
|
||||
s->value->buddy = s->buddy;
|
||||
}
|
||||
@ -5001,13 +5022,8 @@ class MyCompiler: public Compiler {
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual Operand* stack() {
|
||||
Site* s = registerSite(&c, c.arch->stack());
|
||||
return value(&c, s, s);
|
||||
}
|
||||
|
||||
virtual Operand* thread() {
|
||||
Site* s = registerSite(&c, c.arch->thread());
|
||||
virtual Operand* register_(int number) {
|
||||
Site* s = registerSite(&c, number);
|
||||
return value(&c, s, s);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ class Compiler {
|
||||
static const unsigned Aligned = 1 << 0;
|
||||
static const unsigned NoReturn = 1 << 1;
|
||||
static const unsigned TailCall = 1 << 2;
|
||||
static const unsigned TailJump = 1 << 3;
|
||||
|
||||
class Operand { };
|
||||
class StackElement { };
|
||||
|
32
src/x86.cpp
32
src/x86.cpp
@ -703,6 +703,21 @@ popR(Context* c, unsigned size, Assembler::Register* a)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
popM(Context* c, unsigned size, Assembler::Memory* a)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
|
||||
|
||||
popM(c, 4, a);
|
||||
popM(c, 4, &ah);
|
||||
} else {
|
||||
assert(c, BytesPerWord == 4 or size == 8);
|
||||
|
||||
encode(c, 0x8f, 0, a, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
|
||||
Assembler::Register* b);
|
||||
@ -2290,6 +2305,11 @@ class MyAssembler: public Assembler {
|
||||
return arch_;
|
||||
}
|
||||
|
||||
virtual void popReturnAddress(unsigned addressOffset) {
|
||||
Memory addressDst(rbx, addressOffset);
|
||||
popM(&c, BytesPerWord, &addressDst);
|
||||
}
|
||||
|
||||
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset) {
|
||||
Register stack(rsp);
|
||||
Memory stackDst(rbx, stackOffset);
|
||||
@ -2302,6 +2322,18 @@ class MyAssembler: public Assembler {
|
||||
BytesPerWord, MemoryOperand, &baseDst);
|
||||
}
|
||||
|
||||
virtual void restoreFrame(unsigned stackOffset, unsigned baseOffset) {
|
||||
Register stack(rsp);
|
||||
Memory stackDst(rbx, stackOffset);
|
||||
apply(Move, BytesPerWord, MemoryOperand, &stackDst,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
Register base(rbp);
|
||||
Memory baseDst(rbx, baseOffset);
|
||||
apply(Move, BytesPerWord, MemoryOperand, &baseDst,
|
||||
BytesPerWord, RegisterOperand, &base);
|
||||
}
|
||||
|
||||
virtual void pushFrame(unsigned argumentCount, ...) {
|
||||
struct {
|
||||
unsigned size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user