mirror of
https://github.com/corda/corda.git
synced 2025-02-08 20:10:22 +00:00
only steal sites recursively when all else fails in trySteal
This commit is contained in:
parent
c78e76c747
commit
c9bec0ce96
@ -4016,11 +4016,11 @@ finish(MyThread* t, Context* context)
|
|||||||
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)),
|
||||||
"Arrays") == 0 and
|
"java/lang/Class") == 0 and
|
||||||
strcmp
|
strcmp
|
||||||
(reinterpret_cast<const char*>
|
(reinterpret_cast<const char*>
|
||||||
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
||||||
"main") == 0)
|
"replace") == 0)
|
||||||
{
|
{
|
||||||
asm("int3");
|
asm("int3");
|
||||||
}
|
}
|
||||||
|
173
src/compiler.cpp
173
src/compiler.cpp
@ -191,13 +191,12 @@ class LogicalInstruction {
|
|||||||
class Register {
|
class Register {
|
||||||
public:
|
public:
|
||||||
Register(int number):
|
Register(int number):
|
||||||
value(0), site(0), freezeValue(0), number(number), size(0), refCount(0),
|
value(0), site(0), number(number), size(0), refCount(0),
|
||||||
freezeCount(0), acquireCount(0), reserved(false)
|
freezeCount(0), acquireCount(0), reserved(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Value* value;
|
Value* value;
|
||||||
RegisterSite* site;
|
RegisterSite* site;
|
||||||
Value* freezeValue;
|
|
||||||
int number;
|
int number;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned refCount;
|
unsigned refCount;
|
||||||
@ -210,7 +209,6 @@ class FrameResource {
|
|||||||
public:
|
public:
|
||||||
Value* value;
|
Value* value;
|
||||||
MemorySite* site;
|
MemorySite* site;
|
||||||
Value* freezeValue;
|
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned freezeCount;
|
unsigned freezeCount;
|
||||||
unsigned acquireCount;
|
unsigned acquireCount;
|
||||||
@ -972,9 +970,6 @@ buddies(Value* a, Value* b)
|
|||||||
void
|
void
|
||||||
freeze(Context* c, Register* r, Value* v)
|
freeze(Context* c, Register* r, Value* v)
|
||||||
{
|
{
|
||||||
assert(c, (r->freezeCount == 0 and r->freezeValue == 0)
|
|
||||||
or r->reserved or buddies(r->freezeValue, v));
|
|
||||||
|
|
||||||
if (DebugRegisters) {
|
if (DebugRegisters) {
|
||||||
fprintf(stderr, "freeze %d to %d for %p\n",
|
fprintf(stderr, "freeze %d to %d for %p\n",
|
||||||
r->number, r->freezeCount + 1, v);
|
r->number, r->freezeCount + 1, v);
|
||||||
@ -982,9 +977,6 @@ freeze(Context* c, Register* r, Value* v)
|
|||||||
|
|
||||||
++ r->freezeCount;
|
++ r->freezeCount;
|
||||||
if ((not r->reserved) and r->freezeCount == 1) {
|
if ((not r->reserved) and r->freezeCount == 1) {
|
||||||
assert(c, buddies(r->value, v));
|
|
||||||
r->freezeValue = v;
|
|
||||||
|
|
||||||
assert(c, c->availableRegisterCount);
|
assert(c, c->availableRegisterCount);
|
||||||
-- c->availableRegisterCount;
|
-- c->availableRegisterCount;
|
||||||
}
|
}
|
||||||
@ -994,7 +986,6 @@ void
|
|||||||
thaw(Context* c, Register* r, Value* v)
|
thaw(Context* c, Register* r, Value* v)
|
||||||
{
|
{
|
||||||
assert(c, r->freezeCount);
|
assert(c, r->freezeCount);
|
||||||
assert(c, r->reserved or buddies(r->freezeValue, v));
|
|
||||||
|
|
||||||
if (DebugRegisters) {
|
if (DebugRegisters) {
|
||||||
fprintf(stderr, "thaw %d to %d for %p\n",
|
fprintf(stderr, "thaw %d to %d for %p\n",
|
||||||
@ -1003,7 +994,6 @@ thaw(Context* c, Register* r, Value* v)
|
|||||||
|
|
||||||
-- r->freezeCount;
|
-- r->freezeCount;
|
||||||
if ((not r->reserved) and r->freezeCount == 0) {
|
if ((not r->reserved) and r->freezeCount == 0) {
|
||||||
r->freezeValue = 0;
|
|
||||||
++ c->availableRegisterCount;
|
++ c->availableRegisterCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1854,6 +1844,42 @@ available(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
|||||||
or (frameIndex >= 0 and frameIndexAvailable(c, frameIndex))));
|
or (frameIndex >= 0 and frameIndexAvailable(c, frameIndex))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
registerUnused(Context* c, uint32_t mask)
|
||||||
|
{
|
||||||
|
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
|
||||||
|
if ((1 << i) & mask) {
|
||||||
|
Register* r = c->registers[i];
|
||||||
|
if (not (r->reserved or r->value or r->refCount)) {
|
||||||
|
return true;
|
||||||
|
} else if ((static_cast<uint32_t>(1) << i) == mask) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
frameIndexUnused(Context* c, int index)
|
||||||
|
{
|
||||||
|
return c->frameResources[index].value == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
unused(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
||||||
|
int frameIndex)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
((typeMask & (1 << RegisterOperand))
|
||||||
|
and registerMask
|
||||||
|
and (size <= BytesPerWord or registerUnused(c, registerMask >> 32))
|
||||||
|
and registerUnused(c, registerMask))
|
||||||
|
or ((typeMask & (1 << MemoryOperand))
|
||||||
|
and (frameIndex == AnyFrameIndex
|
||||||
|
or (frameIndex >= 0 and frameIndexUnused(c, frameIndex))));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
|
trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
|
||||||
Stack* stack, Local* locals)
|
Stack* stack, Local* locals)
|
||||||
@ -1872,12 +1898,19 @@ trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
|
|||||||
or victim->thief)
|
or victim->thief)
|
||||||
{
|
{
|
||||||
success = save(c, site, victim, size, stack, locals);
|
success = save(c, site, victim, size, stack, locals);
|
||||||
} else if (available(c, size, typeMask, registerMask, frameIndex)) {
|
} else if (unused(c, size, typeMask, registerMask, frameIndex)) {
|
||||||
Site* s = allocateSite(c, typeMask, registerMask, frameIndex);
|
move(c, stack, locals, size, victim, site,
|
||||||
move(c, stack, locals, size, victim, site, s);
|
allocateSite(c, typeMask, registerMask, frameIndex));
|
||||||
success = true;
|
success = true;
|
||||||
} else {
|
} else {
|
||||||
success = save(c, site, victim, size, stack, locals);
|
success = save(c, site, victim, size, stack, locals);
|
||||||
|
if ((not success)
|
||||||
|
and available(c, size, typeMask, registerMask, frameIndex))
|
||||||
|
{
|
||||||
|
move(c, stack, locals, size, victim, site,
|
||||||
|
allocateSite(c, typeMask, registerMask, frameIndex));
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thief->thief = false;
|
thief->thief = false;
|
||||||
@ -2072,21 +2105,17 @@ swap(Context* c, Register* a, Register* b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Register*
|
Register*
|
||||||
acquire(Context* c, uint32_t mask, uint32_t replaceMask, Stack* stack,
|
acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
||||||
Local* locals, unsigned newSize, Value* newValue,
|
unsigned newSize, Value* newValue, RegisterSite* newSite);
|
||||||
RegisterSite* newSite);
|
|
||||||
|
|
||||||
Register*
|
Register*
|
||||||
replace(Context* c, uint32_t replaceMask, Register* r, Value* newValue,
|
replace(Context* c, Register* r, Value* newValue, Stack* stack, Local* locals)
|
||||||
Stack* stack, Local* locals)
|
|
||||||
{
|
{
|
||||||
replaceMask &= ~(1 << r->number);
|
uint32_t mask = (r->freezeCount ? r->site->mask : ~0);
|
||||||
|
|
||||||
uint32_t mask = replaceMask;
|
freeze(c, r, r->value);
|
||||||
if (r->freezeCount) mask &= r->site->mask;
|
Register* s = acquire(c, mask, stack, locals, r->size, newValue, r->site);
|
||||||
|
thaw(c, r, r->value);
|
||||||
Register* s = acquire
|
|
||||||
(c, mask, replaceMask, stack, locals, r->size, newValue, r->site);
|
|
||||||
|
|
||||||
if (DebugRegisters) {
|
if (DebugRegisters) {
|
||||||
fprintf(stderr, "replace %d with %d\n", r->number, s->number);
|
fprintf(stderr, "replace %d with %d\n", r->number, s->number);
|
||||||
@ -2098,28 +2127,28 @@ replace(Context* c, uint32_t replaceMask, Register* r, Value* newValue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Register*
|
Register*
|
||||||
acquire(Context* c, uint32_t mask, uint32_t replaceMask, Stack* stack,
|
acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
||||||
Local* locals, unsigned newSize, Value* newValue,
|
unsigned newSize, Value* newValue, RegisterSite* newSite)
|
||||||
RegisterSite* newSite)
|
|
||||||
{
|
{
|
||||||
Register* r = pickRegister(c, mask);
|
Register* r = pickRegister(c, mask);
|
||||||
|
|
||||||
if (r->reserved) return r;
|
if (r->reserved) return r;
|
||||||
|
|
||||||
if (r->refCount) {
|
if (r->refCount) {
|
||||||
r = replace(c, replaceMask, r, newValue, stack, locals);
|
r = replace(c, r, newValue, stack, locals);
|
||||||
} else {
|
} else {
|
||||||
Value* oldValue = r->value;
|
Value* oldValue = r->value;
|
||||||
if (oldValue
|
if (oldValue
|
||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, r->site))
|
and findSite(c, oldValue, r->site))
|
||||||
{
|
{
|
||||||
assert(c, r->freezeCount == 0);
|
|
||||||
|
|
||||||
if (buddies(oldValue, newValue)) {
|
if (buddies(oldValue, newValue)) {
|
||||||
removeSite(c, oldValue, r->site);
|
removeSite(c, oldValue, r->site);
|
||||||
} else if (not trySteal(c, r, newValue, stack, locals)) {
|
} else {
|
||||||
r = replace(c, replaceMask, r, newValue, stack, locals);
|
assert(c, r->freezeCount == 0);
|
||||||
|
if (not trySteal(c, r, newValue, stack, locals)) {
|
||||||
|
r = replace(c, r, newValue, stack, locals);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2189,7 +2218,7 @@ validate(Context* c, uint32_t mask, Stack* stack, Local* locals,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Register* r = acquire(c, mask, ~0, stack, locals, size, value, site);
|
Register* r = acquire(c, mask, stack, locals, size, value, site);
|
||||||
|
|
||||||
if (current and current != r) {
|
if (current and current != r) {
|
||||||
release(c, current);
|
release(c, current);
|
||||||
@ -2254,12 +2283,13 @@ 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))
|
||||||
{
|
{
|
||||||
assert(c, r->freezeCount == 0);
|
|
||||||
|
|
||||||
if (buddies(oldValue, newValue)) {
|
if (buddies(oldValue, newValue)) {
|
||||||
removeSite(c, oldValue, r->site);
|
removeSite(c, oldValue, r->site);
|
||||||
} else if (not trySteal(c, r, newValue, stack, locals)) {
|
} else {
|
||||||
abort(c);
|
assert(c, r->freezeCount == 0);
|
||||||
|
if (not trySteal(c, r, newValue, stack, locals)) {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2316,8 +2346,6 @@ freezeFrameIndex(Context* c, int frameIndex, Value* v, unsigned size)
|
|||||||
(c->alignedFrameSize + c->parameterFootprint));
|
(c->alignedFrameSize + c->parameterFootprint));
|
||||||
|
|
||||||
FrameResource* r = c->frameResources + frameIndex;
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
assert(c, (r->freezeCount == 0 and r->freezeValue == 0)
|
|
||||||
or buddies(r->freezeValue, v));
|
|
||||||
|
|
||||||
if (r->includeNeighbor and (size > BytesPerWord)) {
|
if (r->includeNeighbor and (size > BytesPerWord)) {
|
||||||
freezeFrameIndex(c, frameIndex + 1, v, BytesPerWord);
|
freezeFrameIndex(c, frameIndex + 1, v, BytesPerWord);
|
||||||
@ -2330,10 +2358,6 @@ freezeFrameIndex(Context* c, int frameIndex, Value* v, unsigned size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
++ r->freezeCount;
|
++ r->freezeCount;
|
||||||
if (r->freezeCount == 1) {
|
|
||||||
assert(c, buddies(r->value, v));
|
|
||||||
r->freezeValue = v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2345,7 +2369,6 @@ thawFrameIndex(Context* c, int frameIndex, Value* v, unsigned size)
|
|||||||
|
|
||||||
FrameResource* r = c->frameResources + frameIndex;
|
FrameResource* r = c->frameResources + frameIndex;
|
||||||
assert(c, r->freezeCount);
|
assert(c, r->freezeCount);
|
||||||
assert(c, buddies(r->freezeValue, v));
|
|
||||||
|
|
||||||
if (r->includeNeighbor and (size > BytesPerWord)) {
|
if (r->includeNeighbor and (size > BytesPerWord)) {
|
||||||
thawFrameIndex(c, frameIndex + 1, v, BytesPerWord);
|
thawFrameIndex(c, frameIndex + 1, v, BytesPerWord);
|
||||||
@ -2358,9 +2381,6 @@ thawFrameIndex(Context* c, int frameIndex, Value* v, unsigned size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- r->freezeCount;
|
-- r->freezeCount;
|
||||||
if (r->freezeCount == 0) {
|
|
||||||
r->freezeValue = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3735,42 +3755,6 @@ acceptJunctionSite(Context* c, Site* s)
|
|||||||
and (c->availableRegisterCount > 1 or s->type(c) != RegisterOperand);
|
and (c->availableRegisterCount > 1 or s->type(c) != RegisterOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
registerUnused(Context* c, uint32_t mask)
|
|
||||||
{
|
|
||||||
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
|
|
||||||
if ((1 << i) & mask) {
|
|
||||||
Register* r = c->registers[i];
|
|
||||||
if (not (r->reserved or r->value or r->refCount)) {
|
|
||||||
return true;
|
|
||||||
} else if ((static_cast<uint32_t>(1) << i) == mask) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
frameIndexUnused(Context* c, int index)
|
|
||||||
{
|
|
||||||
return c->frameResources[index].value == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
unused(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
|
|
||||||
int frameIndex)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((typeMask & (1 << RegisterOperand))
|
|
||||||
and registerMask
|
|
||||||
and (size <= BytesPerWord or registerUnused(c, registerMask >> 32))
|
|
||||||
and registerUnused(c, registerMask))
|
|
||||||
or ((typeMask & (1 << MemoryOperand))
|
|
||||||
and (frameIndex == AnyFrameIndex
|
|
||||||
or (frameIndex >= 0 and frameIndexUnused(c, frameIndex))));
|
|
||||||
}
|
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
pickJunctionSite(Context* c, Value* v, Read* r, unsigned frameIndex)
|
pickJunctionSite(Context* c, Value* v, Read* r, unsigned frameIndex)
|
||||||
{
|
{
|
||||||
@ -3789,22 +3773,29 @@ pickJunctionSite(Context* c, Value* v, Read* r, unsigned frameIndex)
|
|||||||
and s->match(c, (1 << RegisterOperand)
|
and s->match(c, (1 << RegisterOperand)
|
||||||
| (1 << MemoryOperand), ~0, AnyFrameIndex))
|
| (1 << MemoryOperand), ~0, AnyFrameIndex))
|
||||||
{
|
{
|
||||||
// fprintf(stderr, "use picked\n");
|
if (DebugControl) {
|
||||||
|
fprintf(stderr, "use picked\n");
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
} else if (unused(c, r->size, typeMask, registerMask, frameIndexDesired)) {
|
||||||
if (unused(c, r->size, typeMask, registerMask, frameIndexDesired)) {
|
|
||||||
s = allocateSite(c, typeMask, registerMask, frameIndexDesired);
|
s = allocateSite(c, typeMask, registerMask, frameIndexDesired);
|
||||||
if (acceptJunctionSite(c, s)) {
|
if (acceptJunctionSite(c, s)) {
|
||||||
// fprintf(stderr, "use allocated\n");
|
if (DebugControl) {
|
||||||
|
fprintf(stderr, "use allocated\n");
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->availableRegisterCount > 1) {
|
if (c->availableRegisterCount > 1) {
|
||||||
// fprintf(stderr, "use register\n");
|
if (DebugControl) {
|
||||||
|
fprintf(stderr, "use register\n");
|
||||||
|
}
|
||||||
return freeRegisterSite(c);
|
return freeRegisterSite(c);
|
||||||
} else {
|
} else if (frameIndexAvailable(c, frameIndex)) {
|
||||||
// fprintf(stderr, "use frame\n");
|
if (DebugControl) {
|
||||||
|
fprintf(stderr, "use frame\n");
|
||||||
|
}
|
||||||
return frameSite(c, frameIndex);
|
return frameSite(c, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user