mirror of
https://github.com/corda/corda.git
synced 2025-01-22 12:28:11 +00:00
avoid inifinite recursion in trySteal
This commit is contained in:
parent
fb770d10fb
commit
7ea5a4a64f
222
src/compiler.cpp
222
src/compiler.cpp
@ -209,6 +209,8 @@ class FrameResource {
|
|||||||
Value* value;
|
Value* value;
|
||||||
MemorySite* site;
|
MemorySite* site;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
bool frozen;
|
||||||
|
bool includeNeighbor;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstantPoolNode {
|
class ConstantPoolNode {
|
||||||
@ -258,7 +260,7 @@ class Value: public Compiler::Operand {
|
|||||||
public:
|
public:
|
||||||
Value(Site* site, Site* target):
|
Value(Site* site, Site* target):
|
||||||
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
reads(0), lastRead(0), sites(site), source(0), target(target), buddy(this),
|
||||||
local(false)
|
local(false), thief(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void addPredecessor(Context*, Event*) { }
|
virtual void addPredecessor(Context*, Event*) { }
|
||||||
@ -270,6 +272,7 @@ class Value: public Compiler::Operand {
|
|||||||
Site* target;
|
Site* target;
|
||||||
Value* buddy;
|
Value* buddy;
|
||||||
bool local;
|
bool local;
|
||||||
|
bool thief;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Pass {
|
enum Pass {
|
||||||
@ -1053,7 +1056,7 @@ class RegisterSite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void freeze(Context* c UNUSED) {
|
virtual void freeze(Context* c) {
|
||||||
assert(c, low);
|
assert(c, low);
|
||||||
|
|
||||||
::freeze(c, low);
|
::freeze(c, low);
|
||||||
@ -1062,7 +1065,7 @@ class RegisterSite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void thaw(Context* c UNUSED) {
|
virtual void thaw(Context* c) {
|
||||||
assert(c, low);
|
assert(c, low);
|
||||||
|
|
||||||
::thaw(c, low);
|
::thaw(c, low);
|
||||||
@ -1161,10 +1164,16 @@ decrement(Context* c UNUSED, Register* r)
|
|||||||
void
|
void
|
||||||
acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals,
|
acquireFrameIndex(Context* c, int index, Stack* stack, Local* locals,
|
||||||
unsigned newSize, Value* newValue, MemorySite* newSite,
|
unsigned newSize, Value* newValue, MemorySite* newSite,
|
||||||
bool recurse = true);
|
bool includeNeighbor);
|
||||||
|
|
||||||
void
|
void
|
||||||
releaseFrameIndex(Context* c, int index, bool recurse = true);
|
releaseFrameIndex(Context* c, int index);
|
||||||
|
|
||||||
|
void
|
||||||
|
freezeFrameIndex(Context* c, int index);
|
||||||
|
|
||||||
|
void
|
||||||
|
thawFrameIndex(Context* c, int index);
|
||||||
|
|
||||||
MemorySite*
|
MemorySite*
|
||||||
memorySite(Context* c, int base, int offset = 0, int index = NoRegister,
|
memorySite(Context* c, int base, int offset = 0, int index = NoRegister,
|
||||||
@ -1240,7 +1249,7 @@ class MemorySite: public Site {
|
|||||||
assert(c, value.index == NoRegister);
|
assert(c, value.index == NoRegister);
|
||||||
acquireFrameIndex
|
acquireFrameIndex
|
||||||
(c, offsetToFrameIndex(c, value.offset), stack, locals, size, v,
|
(c, offsetToFrameIndex(c, value.offset), stack, locals, size, v,
|
||||||
this);
|
this, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1256,6 +1265,18 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void freeze(Context* c) {
|
||||||
|
if (value.base == c->arch->stack()) {
|
||||||
|
freezeFrameIndex(c, offsetToFrameIndex(c, value.offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void thaw(Context* c) {
|
||||||
|
if (value.base == c->arch->stack()) {
|
||||||
|
thawFrameIndex(c, offsetToFrameIndex(c, value.offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool usesRegister(Context* c, int r) {
|
virtual bool usesRegister(Context* c, int r) {
|
||||||
sync(c);
|
sync(c);
|
||||||
return value.base == r or value.index == r;
|
return value.base == r or value.index == r;
|
||||||
@ -1711,67 +1732,88 @@ find(Value* needle, Value* haystack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
trySteal(Context* c, Site* site, Value* v, unsigned size, Stack* stack,
|
save(Context* c, Site* src, Value* v, unsigned size, Stack* stack,
|
||||||
Local* locals, int avoid)
|
Local* locals, int avoid, bool includeNeighbor)
|
||||||
{
|
{
|
||||||
if (not hasMoreThanOneSite(v)) {
|
int index = NoFrameIndex;
|
||||||
Read* r = live(v);
|
int avoid2 = (includeNeighbor ? avoid + 1 : NoFrameIndex);
|
||||||
if (r->pickSite(c, v, true)) {
|
for (unsigned li = 0; li < c->localFootprint; ++li) {
|
||||||
int index = NoFrameIndex;
|
Local* local = locals + li;
|
||||||
for (unsigned li = 0; li < c->localFootprint; ++li) {
|
if (find(v, local->value)) {
|
||||||
Local* local = locals + li;
|
int fi = frameIndex(c, li, local->footprint);
|
||||||
if (find(v, local->value)) {
|
if (fi != avoid and fi != avoid2) {
|
||||||
int fi = frameIndex(c, li, local->footprint);
|
index = fi;
|
||||||
if (fi != avoid) {
|
break;
|
||||||
index = fi;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == NoFrameIndex) {
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
|
||||||
if (find(v, s->value)) {
|
|
||||||
uint8_t typeMask;
|
|
||||||
uint64_t registerMask;
|
|
||||||
int frameIndex = AnyFrameIndex;
|
|
||||||
live(v)->intersect(&typeMask, ®isterMask, &frameIndex);
|
|
||||||
|
|
||||||
if (frameIndex >= 0 and frameIndex != avoid) {
|
|
||||||
index = frameIndex;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
int fi = ::frameIndex
|
|
||||||
(c, s->index + c->localFootprint, s->footprint);
|
|
||||||
if (fi != avoid) {
|
|
||||||
index = fi;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index != NoFrameIndex) {
|
|
||||||
move(c, stack, locals, size, v, site, frameSite(c, index));
|
|
||||||
} else {
|
|
||||||
if (DebugRegisters or DebugFrameIndexes) {
|
|
||||||
fprintf(stderr, "unable to steal %p from %p\n", site, v);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
move(c, stack, locals, size, v, site, r->allocateSite(c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeSite(c, v, site);
|
if (index == NoFrameIndex) {
|
||||||
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
|
if (find(v, s->value)) {
|
||||||
|
int fi = ::frameIndex
|
||||||
|
(c, s->index + c->localFootprint, s->footprint);
|
||||||
|
if (fi != avoid and fi != avoid2) {
|
||||||
|
index = fi;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
if (index != NoFrameIndex) {
|
||||||
|
move(c, stack, locals, size, v, src, frameSite(c, index));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (DebugRegisters or DebugFrameIndexes) {
|
||||||
|
fprintf(stderr, "unable to save %p\n", v);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
trySteal(Context* c, Register* r, Stack* stack, Local* locals)
|
trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
|
||||||
|
Stack* stack, Local* locals, int avoid, bool includeNeighbor)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
if (not hasMoreThanOneSite(victim)) {
|
||||||
|
thief->thief = true;
|
||||||
|
|
||||||
|
Read* read = live(victim);
|
||||||
|
uint8_t typeMask = ~static_cast<uint8_t>(0);
|
||||||
|
uint64_t registerMask = ~static_cast<uint64_t>(0);
|
||||||
|
int frameIndex = AnyFrameIndex;
|
||||||
|
read->intersect(&typeMask, ®isterMask, &frameIndex);
|
||||||
|
|
||||||
|
if (pickSite(c, victim, typeMask, registerMask, frameIndex, true)
|
||||||
|
or victim->thief)
|
||||||
|
{
|
||||||
|
success = save(c, site, victim, size, stack, locals, avoid,
|
||||||
|
includeNeighbor);
|
||||||
|
} else {
|
||||||
|
Site* s = allocateSite(c, typeMask, registerMask, frameIndex);
|
||||||
|
if (s) {
|
||||||
|
move(c, stack, locals, size, victim, site, s);
|
||||||
|
success = true;
|
||||||
|
} else {
|
||||||
|
success = save(c, site, victim, size, stack, locals, avoid,
|
||||||
|
includeNeighbor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thief->thief = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
removeSite(c, victim, site);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
trySteal(Context* c, Register* r, Value* thief, Stack* stack, Local* locals)
|
||||||
{
|
{
|
||||||
assert(c, r->refCount == 0);
|
assert(c, r->refCount == 0);
|
||||||
|
|
||||||
@ -1782,7 +1824,8 @@ trySteal(Context* c, Register* r, Stack* stack, Local* locals)
|
|||||||
fprintf(stderr, "try steal %d from %p\n", r->number, v);
|
fprintf(stderr, "try steal %d from %p\n", r->number, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
return trySteal(c, r->site, r->value, r->size, stack, locals, NoFrameIndex);
|
return trySteal(c, r->site, thief, r->value, r->size, stack, locals,
|
||||||
|
NoFrameIndex, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -1969,7 +2012,7 @@ acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
|||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, r->site))
|
and findSite(c, oldValue, r->site))
|
||||||
{
|
{
|
||||||
if (not trySteal(c, r, stack, locals)) {
|
if (not trySteal(c, r, newValue, stack, locals)) {
|
||||||
r = replace(c, stack, locals, r);
|
r = replace(c, stack, locals, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2035,7 +2078,8 @@ validate(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
trySteal(Context* c, FrameResource* r, Stack* stack, Local* locals)
|
trySteal(Context* c, FrameResource* r, Value* thief, Stack* stack,
|
||||||
|
Local* locals)
|
||||||
{
|
{
|
||||||
assert(c, live(r->value));
|
assert(c, live(r->value));
|
||||||
|
|
||||||
@ -2046,14 +2090,14 @@ trySteal(Context* c, FrameResource* r, Stack* stack, Local* locals)
|
|||||||
index, frameIndexToOffset(c, index), r->value, r->site);
|
index, frameIndexToOffset(c, index), r->value, r->site);
|
||||||
}
|
}
|
||||||
|
|
||||||
return trySteal(c, r->site, r->value, r->size, stack, locals,
|
return trySteal(c, r->site, thief, r->value, r->size, stack, locals,
|
||||||
r - c->frameResources);
|
r - c->frameResources, r->includeNeighbor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
|
acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
|
||||||
unsigned newSize, Value* newValue, MemorySite* newSite,
|
unsigned newSize, Value* newValue, MemorySite* newSite,
|
||||||
bool recurse)
|
bool includeNeighbor)
|
||||||
{
|
{
|
||||||
assert(c, frameIndex >= 0);
|
assert(c, frameIndex >= 0);
|
||||||
assert(c, frameIndex < static_cast<int>
|
assert(c, frameIndex < static_cast<int>
|
||||||
@ -2066,8 +2110,11 @@ acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrameResource* r = c->frameResources + frameIndex;
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
|
expect(c, not r->frozen);
|
||||||
|
|
||||||
if (recurse and newSize > BytesPerWord) {
|
includeNeighbor &= newSize > BytesPerWord;
|
||||||
|
|
||||||
|
if (includeNeighbor) {
|
||||||
acquireFrameIndex
|
acquireFrameIndex
|
||||||
(c, frameIndex + 1, stack, locals, newSize, newValue, newSite, false);
|
(c, frameIndex + 1, stack, locals, newSize, newValue, newSite, false);
|
||||||
}
|
}
|
||||||
@ -2077,18 +2124,19 @@ acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
|
|||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, r->site))
|
and findSite(c, oldValue, r->site))
|
||||||
{
|
{
|
||||||
if (not trySteal(c, r, stack, locals)) {
|
if (not trySteal(c, r, newValue, stack, locals)) {
|
||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r->includeNeighbor = includeNeighbor;
|
||||||
r->size = newSize;
|
r->size = newSize;
|
||||||
r->value = newValue;
|
r->value = newValue;
|
||||||
r->site = newSite;
|
r->site = newSite;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
releaseFrameIndex(Context* c, int frameIndex, bool recurse)
|
releaseFrameIndex(Context* c, int frameIndex)
|
||||||
{
|
{
|
||||||
assert(c, frameIndex >= 0);
|
assert(c, frameIndex >= 0);
|
||||||
assert(c, frameIndex < static_cast<int>
|
assert(c, frameIndex < static_cast<int>
|
||||||
@ -2101,8 +2149,8 @@ releaseFrameIndex(Context* c, int frameIndex, bool recurse)
|
|||||||
|
|
||||||
FrameResource* r = c->frameResources + frameIndex;
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
|
|
||||||
if (recurse and r->size > BytesPerWord) {
|
if (r->includeNeighbor) {
|
||||||
releaseFrameIndex(c, frameIndex + 1, false);
|
releaseFrameIndex(c, frameIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
r->size = 0;
|
r->size = 0;
|
||||||
@ -2110,6 +2158,40 @@ releaseFrameIndex(Context* c, int frameIndex, bool recurse)
|
|||||||
r->site = 0;
|
r->site = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freezeFrameIndex(Context* c, int frameIndex)
|
||||||
|
{
|
||||||
|
assert(c, frameIndex >= 0);
|
||||||
|
assert(c, frameIndex < static_cast<int>
|
||||||
|
(c->alignedFrameSize + c->parameterFootprint));
|
||||||
|
|
||||||
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
|
assert(c, not r->frozen);
|
||||||
|
|
||||||
|
if (r->includeNeighbor) {
|
||||||
|
freezeFrameIndex(c, frameIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->frozen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
thawFrameIndex(Context* c, int frameIndex)
|
||||||
|
{
|
||||||
|
assert(c, frameIndex >= 0);
|
||||||
|
assert(c, frameIndex < static_cast<int>
|
||||||
|
(c->alignedFrameSize + c->parameterFootprint));
|
||||||
|
|
||||||
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
|
assert(c, r->frozen);
|
||||||
|
|
||||||
|
if (r->includeNeighbor) {
|
||||||
|
thawFrameIndex(c, frameIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
r->frozen = false;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
apply(Context* c, UnaryOperation op,
|
apply(Context* c, UnaryOperation op,
|
||||||
unsigned s1Size, Site* s1)
|
unsigned s1Size, Site* s1)
|
||||||
@ -4029,7 +4111,6 @@ class MyCompiler: public Compiler {
|
|||||||
virtual void endSubroutine(Subroutine* subroutine) {
|
virtual void endSubroutine(Subroutine* subroutine) {
|
||||||
MySubroutine* sr = static_cast<MySubroutine*>(subroutine);
|
MySubroutine* sr = static_cast<MySubroutine*>(subroutine);
|
||||||
if (sr->forkState) {
|
if (sr->forkState) {
|
||||||
fprintf(stderr, "restore sr forkstate\n");
|
|
||||||
Local* locals = c.locals;
|
Local* locals = c.locals;
|
||||||
::restoreState(&c, sr->forkState);
|
::restoreState(&c, sr->forkState);
|
||||||
for (int i = c.localFootprint - 1; i >= 0; --i) {
|
for (int i = c.localFootprint - 1; i >= 0; --i) {
|
||||||
@ -4038,7 +4119,6 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "save sr forkstate\n");
|
|
||||||
sr->forkState = ::saveState(&c);
|
sr->forkState = ::saveState(&c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user