This commit is contained in:
Joel Dice 2008-12-24 13:35:43 -07:00
parent f96ee3ea73
commit c678fb30a4
2 changed files with 359 additions and 221 deletions

View File

@ -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)),
"java/lang/Class") == 0 and "Arrays") == 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)),
"replace") == 0) "main") == 0)
{ {
asm("int3"); asm("int3");
} }

View File

@ -16,9 +16,9 @@ using namespace vm;
namespace { namespace {
const bool DebugAppend = false; const bool DebugAppend = false;
const bool DebugCompile = false; const bool DebugCompile = true;
const bool DebugRegisters = false; const bool DebugRegisters = true;
const bool DebugFrameIndexes = false; const bool DebugFrameIndexes = true;
const bool DebugFrame = false; const bool DebugFrame = false;
const bool DebugControl = false; const bool DebugControl = false;
const bool DebugReads = false; const bool DebugReads = false;
@ -28,6 +28,8 @@ const bool DebugMoves = false;
const int AnyFrameIndex = -2; const int AnyFrameIndex = -2;
const int NoFrameIndex = -1; const int NoFrameIndex = -1;
const unsigned MaxTargetDepth = 1;
class Context; class Context;
class Value; class Value;
class Stack; class Stack;
@ -190,28 +192,20 @@ class LogicalInstruction {
class Register { class Register {
public: public:
Register(int number):
value(0), site(0), number(number), size(0), refCount(0),
freezeCount(0), acquireCount(0), reserved(false)
{ }
Value* value; Value* value;
RegisterSite* site; Site* site;
int number;
unsigned size; unsigned size;
unsigned refCount;
unsigned freezeCount; unsigned freezeCount;
unsigned acquireCount; unsigned referenceCount;
bool reserved; bool reserved;
}; };
class FrameResource { class FrameResource {
public: public:
Value* value; Value* value;
MemorySite* site; Site* site;
unsigned size; unsigned size;
unsigned freezeCount; unsigned freezeCount;
unsigned acquireCount;
bool includeNeighbor; bool includeNeighbor;
}; };
@ -297,8 +291,8 @@ class Context {
predecessor(0), predecessor(0),
logicalCode(0), logicalCode(0),
registers registers
(static_cast<Register**> (static_cast<Register*>
(zone->allocate(sizeof(Register*) * arch->registerCount()))), (zone->allocate(sizeof(Register) * arch->registerCount()))),
frameResources(0), frameResources(0),
firstConstant(0), firstConstant(0),
lastConstant(0), lastConstant(0),
@ -319,10 +313,11 @@ class Context {
constantCompare(CompareNone), constantCompare(CompareNone),
pass(ScanPass) pass(ScanPass)
{ {
memset(registers, 0, sizeof(Register) * arch->registerCount());
for (unsigned i = 0; i < arch->registerCount(); ++i) { for (unsigned i = 0; i < arch->registerCount(); ++i) {
registers[i] = new (zone->allocate(sizeof(Register))) Register(i);
if (arch->reserved(i)) { if (arch->reserved(i)) {
registers[i]->reserved = true; registers[i].reserved = true;
-- availableRegisterCount; -- availableRegisterCount;
} }
} }
@ -338,7 +333,7 @@ class Context {
SavedValue* saved; SavedValue* saved;
Event* predecessor; Event* predecessor;
LogicalInstruction** logicalCode; LogicalInstruction** logicalCode;
Register** registers; Register* registers;
FrameResource* frameResources; FrameResource* frameResources;
ConstantPoolNode* firstConstant; ConstantPoolNode* firstConstant;
ConstantPoolNode* lastConstant; ConstantPoolNode* lastConstant;
@ -971,8 +966,8 @@ void
freeze(Context* c, Register* r, Value* v) freeze(Context* c, Register* r, Value* v)
{ {
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "freeze %d to %d for %p\n", fprintf(stderr, "freeze %"LD" to %d for %p\n",
r->number, r->freezeCount + 1, v); r - c->registers, r->freezeCount + 1, v);
} }
++ r->freezeCount; ++ r->freezeCount;
@ -988,8 +983,8 @@ thaw(Context* c, Register* r, Value* v)
assert(c, r->freezeCount); assert(c, r->freezeCount);
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "thaw %d to %d for %p\n", fprintf(stderr, "thaw %"LD" to %d for %p\n",
r->number, r->freezeCount - 1, v); r - c->registers, r->freezeCount - 1, v);
} }
-- r->freezeCount; -- r->freezeCount;
@ -1002,8 +997,8 @@ void
release(Context* c, Register* r); release(Context* c, Register* r);
Register* Register*
validate(Context* c, uint32_t mask, Stack* stack, Local* locals, acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
unsigned size, Value* value, RegisterSite* site, Register* current); unsigned newSize, Value* newValue, Site* newSite, Register* r);
RegisterSite* RegisterSite*
freeRegisterSite(Context* c, uint64_t mask = ~static_cast<uint64_t>(0)); freeRegisterSite(Context* c, uint64_t mask = ~static_cast<uint64_t>(0));
@ -1014,11 +1009,11 @@ class RegisterSite: public Site {
mask(mask), low(low), high(high), register_(NoRegister, NoRegister) mask(mask), low(low), high(high), register_(NoRegister, NoRegister)
{ } { }
void sync(Context* c UNUSED) { void sync(Context* c) {
assert(c, low); assert(c, low);
register_.low = low->number; register_.low = low - c->registers;
register_.high = (high? high->number : NoRegister); register_.high = (high? high - c->registers : NoRegister);
} }
virtual void toString(Context* c, char* buffer, unsigned bufferSize) { virtual void toString(Context* c, char* buffer, unsigned bufferSize) {
@ -1066,10 +1061,10 @@ class RegisterSite: public Site {
virtual void acquire(Context* c, Stack* stack, Local* locals, unsigned size, virtual void acquire(Context* c, Stack* stack, Local* locals, unsigned size,
Value* v) Value* v)
{ {
low = ::validate(c, mask, stack, locals, size, v, this, low); low = ::acquire(c, mask, stack, locals, size, v, this, low);
if (size > BytesPerWord) { if (size > BytesPerWord) {
::freeze(c, low, v); ::freeze(c, low, v);
high = ::validate(c, mask >> 32, stack, locals, size, v, this, high); high = ::acquire(c, mask >> 32, stack, locals, size, v, this, high);
::thaw(c, low, v); ::thaw(c, low, v);
} }
} }
@ -1149,10 +1144,10 @@ registerSite(Context* c, int low, int high = NoRegister)
if (high == NoRegister) { if (high == NoRegister) {
hr = 0; hr = 0;
} else { } else {
hr = c->registers[high]; hr = c->registers + high;
} }
return new (c->zone->allocate(sizeof(RegisterSite))) return new (c->zone->allocate(sizeof(RegisterSite)))
RegisterSite(~static_cast<uint64_t>(0), c->registers[low], hr); RegisterSite(~static_cast<uint64_t>(0), c->registers + low, hr);
} }
RegisterSite* RegisterSite*
@ -1162,30 +1157,28 @@ freeRegisterSite(Context* c, uint64_t mask)
RegisterSite(mask); RegisterSite(mask);
} }
Register* void
increment(Context* c, int i) increment(Context* c, Register* r)
{ {
Register* r = c->registers[i];
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "increment %d to %d\n", r->number, r->refCount + 1); fprintf(stderr, "increment %"LD" to %d\n",
c->registers - r, r->referenceCount + 1);
} }
++ r->refCount; ++ r->referenceCount;
return r;
} }
void void
decrement(Context* c UNUSED, Register* r) decrement(Context* c, Register* r)
{ {
assert(c, r->refCount > 0); assert(c, r->referenceCount > 0);
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "decrement %d to %d\n", r->number, r->refCount - 1); fprintf(stderr, "decrement %"LD" to %d\n",
c->registers - r, r->referenceCount - 1);
} }
-- r->refCount; -- r->referenceCount;
} }
void void
@ -1215,8 +1208,8 @@ class MemorySite: public Site {
void sync(Context* c UNUSED) { void sync(Context* c UNUSED) {
assert(c, base); assert(c, base);
value.base = base->number; value.base = base - c->registers;
value.index = (index? index->number : NoRegister); value.index = (index? index - c->registers : NoRegister);
} }
virtual void toString(Context* c, char* buffer, unsigned bufferSize) { virtual void toString(Context* c, char* buffer, unsigned bufferSize) {
@ -1267,9 +1260,11 @@ class MemorySite: public Site {
virtual void acquire(Context* c, Stack* stack, Local* locals, unsigned size, virtual void acquire(Context* c, Stack* stack, Local* locals, unsigned size,
Value* v) Value* v)
{ {
base = increment(c, value.base); base = c->registers + value.base;
increment(c, base);
if (value.index != NoRegister) { if (value.index != NoRegister) {
index = increment(c, value.index); index = c->registers + value.index;
increment(c, index);
} }
if (value.base == c->arch->stack()) { if (value.base == c->arch->stack()) {
@ -1819,7 +1814,7 @@ registerAvailable(Context* c, uint32_t mask)
{ {
for (int i = c->arch->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 (not (r->reserved or r->freezeCount)) { if (not (r->reserved or r->freezeCount)) {
return true; return true;
} else if ((static_cast<uint32_t>(1) << i) == mask) { } else if ((static_cast<uint32_t>(1) << i) == mask) {
@ -1849,8 +1844,8 @@ registerUnused(Context* c, uint32_t mask)
{ {
for (int i = c->arch->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 (not (r->reserved or r->value or r->refCount)) { if (not (r->reserved or r->value or r->referenceCount)) {
return true; return true;
} else if ((static_cast<uint32_t>(1) << i) == mask) { } else if ((static_cast<uint32_t>(1) << i) == mask) {
return false; return false;
@ -1880,6 +1875,250 @@ unused(Context* c, unsigned size, uint8_t typeMask, uint64_t registerMask,
or (frameIndex >= 0 and frameIndexUnused(c, frameIndex)))); or (frameIndex >= 0 and frameIndexUnused(c, frameIndex))));
} }
class Target {
public:
Target(): cost(Impossible) { }
Target(int lowRegister, int highRegister, unsigned cost):
lowRegister(lowRegister), highRegister(highRegister),
frameIndex(NoFrameIndex), cost(cost)
{ }
Target(int frameIndex, unsigned cost):
lowRegister(NoRegister), highRegister(NoRegister),
frameIndex(frameIndex), cost(cost)
{ }
int lowRegister;
int highRegister;
int frameIndex;
unsigned cost;
};
Target
pickTarget(Context* c, unsigned depth, Value* v, bool strict);
unsigned
resourceCost(Context* c, unsigned depth, unsigned limit, Resource* r)
{
if (r->reserved or r->referenceCount) {
return Impossible;
}
if (r->value) {
assert(c, findSite(c, r->value, r->site));
if (hasMoreThanOneSite(r->value)) {
return 0;
} else if (buddies(r->value, newValue)) {
return 1;
} else if (depth < limit) {
increment(c, r);
Target target = pickTarget(c, depth + 1, r->value, false);
decrement(c, r);
if (target.cost == Impossible) {
return Impossible;
} else {
return target.cost + 2;
}
} else {
return Impossible;
}
} else {
return 0;
}
}
int
pickRegisterTarget(Context* c, unsigned depth, unsigned limit, uint32_t mask,
unsigned* cost)
{
// first, do a quick pass looking for free registers
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->referenceCount)) {
*cost = 0;
return i;
} else if ((static_cast<uint32_t>(1) << i) == mask) {
*cost = resourceCost(c, depth, limit, r);
return i;
}
}
}
// nothing free, and no exact match - try harder
int target = NoRegister;
unsigned bestCost = Impossible;
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
if ((1 << i) & mask) {
Register* r = c->registers + i;
unsigned myCost = resourceCost(c, depth, r);
if (myCost < bestCost) {
bestCost = myCost;
target = i;
}
}
}
*cost = bestCost;
return target;
}
Target
pickRegisterTarget(Context* c, unsigned depth, unsigned limit, uint64_t mask,
unsigned size)
{
unsigned lowCost;
int low = pickRegisterTarget(c, depth, limit, mask, &lowCost);
if (lowCost == Impossible) {
return Target;
}
unsigned highCost;
int high;
if (size > BytesPerWord) {
increment(c, low);
high = pickRegisterTarget(c, depth, limit, mask, &highCost);
decrement(c, low);
if (highCost == Impossible) {
return Target;
}
} else {
highCost = 0;
high = NoRegister;
}
return Target(low, high, lowCost + highCost);
}
unsigned
frameCost(Context* c, unsigned depth, unsigned limit, int frameIndex, int size)
{
unsigned lowCost = frameCost
(c, depth, limit, c->frameResources + frameIndex);
if (lowCost == Impossible) {
return Impossible;
}
unsigned highCost;
if (size > BytesPerWord) {
increment(c, frameIndex);
highCost = frameCost(c, depth, limit, c->frameResources + frameIndex + 1);
decrement(c, frameIndex);
if (highCost == Impossible) {
return Impossible;
}
} else {
highCost = 0;
}
return lowCost + highCost;
}
Target
pickFrameTarget(Context* c, unsigned depth, unsigned limit, Value* v,
unsigned size)
{
Target best;
for (unsigned li = 0; li < c->localFootprint; ++li) {
Local* local = c->locals + li;
if (find(v, local->value)) {
int fi = frameIndex(c, li, local->footprint);
Target mine(fi, frameCost(c, depth, limit, fi, size));
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
}
if (index == NoFrameIndex) {
for (Stack* s = c->stack; s; s = s->next) {
if (find(v, s->value)) {
int fi = ::frameIndex
(c, s->index + c->localFootprint, s->footprint);
Target mine(fi, frameCost(c, depth, limit, fi, size));
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
}
}
return best;
}
Target
pickTarget(Context* c, unsigned depth, unsigned limit, Value* v, bool strict)
{
if (v->target) return v->target;
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, &registerMask, &frameIndex);
Target best;
if (typeMask & (1 << RegisterOperand)) {
Target mine = pickRegisterTarget
(c, depth, limit, registerMask, read->size);
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
if ((typeMask & (1 << MemoryOperand)) && frameIndex >= 0) {
Target mine(frameIndex, frameCost(c, depth, limit, frameIndex, size));
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
if (strict) {
return target;
}
{ Target mine = pickRegisterTarget
(c, depth, limit, ~static_cast<uint64_t>(0), read->size);
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
{ Target mine = pickFrameTarget(c, depth, limit, v, read->size);
if (mine.cost == 0) {
return mine;
} else if (mine.cost < best.cost) {
best = mine;
}
}
return best;
}
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)
@ -1906,12 +2145,17 @@ trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
success = save(c, site, victim, size, stack, locals); success = save(c, site, victim, size, stack, locals);
} }
if ((not success) if (not success) {
and available(c, size, typeMask, registerMask, frameIndex)) if (available(c, size, typeMask, registerMask, frameIndex)) {
{ move(c, stack, locals, size, victim, site,
move(c, stack, locals, size, victim, site, allocateSite(c, typeMask, registerMask, frameIndex));
allocateSite(c, typeMask, registerMask, frameIndex)); success = true;
success = true; } else if (available(c, size, 1 << RegisterOperand,
~static_cast<uint64_t>(0), NoFrameIndex))
{
move(c, stack, locals, size, victim, site, freeRegisterSite(c));
success = true;
}
} }
thief->thief = false; thief->thief = false;
@ -1927,13 +2171,13 @@ trySteal(Context* c, Site* site, Value* thief, Value* victim, unsigned size,
bool bool
trySteal(Context* c, Register* r, Value* thief, Stack* stack, Local* locals) trySteal(Context* c, Register* r, Value* thief, Stack* stack, Local* locals)
{ {
assert(c, r->refCount == 0); assert(c, r->referenceCount == 0);
Value* v = r->value; Value* v = r->value;
assert(c, live(v)); assert(c, live(v));
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "try steal %d from %p\n", r->number, v); fprintf(stderr, "try steal %"LD" from %p\n", r - c->registers, v);
} }
return trySteal(c, r->site, thief, r->value, r->size, stack, locals); return trySteal(c, r->site, thief, r->value, r->size, stack, locals);
@ -2020,14 +2264,14 @@ remainingForfeited(Context* c, Value* v, Site* toRemove)
void void
releaseRegister(Context* c, int r) releaseRegister(Context* c, int r)
{ {
Register* reg = c->registers[r]; Register* reg = c->registers + r;
if (used(c, reg) if (used(c, reg)
and (not usedExclusively(c, reg)) and (not usedExclusively(c, reg))
and (not remainingForfeited(c, reg->value, reg->site))) and (not remainingForfeited(c, reg->value, reg->site)))
{ {
removeSite(c, reg->value, reg->site); removeSite(c, reg->value, reg->site);
if (reg->refCount == 0) return; if (reg->referenceCount == 0) return;
} }
for (FrameIterator it(c, c->stack, c->locals); it.hasMore();) { for (FrameIterator it(c, c->stack, c->locals); it.hasMore();) {
@ -2040,7 +2284,7 @@ releaseRegister(Context* c, int r)
unsigned unsigned
registerCost(Context* c, Register* r) registerCost(Context* c, Register* r)
{ {
if (r->reserved or r->freezeCount) { if (r->reserved or r->freezeCount or r->referenceCount) {
return 6; return 6;
} }
@ -2053,10 +2297,6 @@ registerCost(Context* c, Register* r)
} }
} }
if (r->refCount) {
cost += 2;
}
return cost; return cost;
} }
@ -2067,7 +2307,7 @@ pickRegister(Context* c, uint32_t mask)
unsigned cost = 5; unsigned cost = 5;
for (int i = c->arch->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) {
return r; return r;
} }
@ -2085,84 +2325,32 @@ pickRegister(Context* c, uint32_t mask)
return register_; return register_;
} }
void
swap(Context* c, Register* a, Register* b)
{
assert(c, a != b);
assert(c, a->number != b->number);
Assembler::Register ar(a->number);
Assembler::Register br(b->number);
c->assembler->apply
(Swap, BytesPerWord, RegisterOperand, &ar,
BytesPerWord, RegisterOperand, &br);
c->registers[a->number] = b;
c->registers[b->number] = a;
int t = a->number;
a->number = b->number;
b->number = t;
}
Register* Register*
acquire(Context* c, uint32_t mask, Stack* stack, Local* locals, acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
unsigned newSize, Value* newValue, RegisterSite* newSite); unsigned newSize, Value* newValue, Site* newSite, Register* r)
Register*
replace(Context* c, Register* r, Value* newValue, Stack* stack, Local* locals)
{ {
uint32_t mask = (r->freezeCount ? r->site->mask : ~0); assert(c, newValue);
assert(c, newSite);
assert(c, newSize);
freeze(c, r, r->value); if (r == 0) r = pickRegister(c, mask);
Register* s = acquire(c, mask, stack, locals, r->size, newValue, r->site);
thaw(c, r, r->value);
if (DebugRegisters) {
fprintf(stderr, "replace %d with %d\n", r->number, s->number);
}
swap(c, r, s);
return s;
}
Register*
acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
unsigned newSize, Value* newValue, RegisterSite* newSite)
{
Register* r = pickRegister(c, mask);
if (r->reserved) return r; if (r->reserved) return r;
if (r->refCount) { Value* oldValue = r->value;
r = replace(c, r, newValue, stack, locals); if (oldValue and findSite(c, oldValue, r->site)) {
} else { if (buddies(oldValue, newValue)) {
Value* oldValue = r->value; removeSite(c, oldValue, r->site);
if (oldValue } else {
and oldValue != newValue assert(c, r->freezeCount == 0);
and findSite(c, oldValue, r->site)) if (not trySteal(c, r, newValue, stack, locals)) {
{ abort(c);
if (buddies(oldValue, newValue)) {
removeSite(c, oldValue, r->site);
} else {
assert(c, r->freezeCount == 0);
if (not trySteal(c, r, newValue, stack, locals)) {
r = replace(c, r, newValue, stack, locals);
}
} }
} }
} }
if (r->value == newValue) {
++ r->acquireCount;
} else {
r->acquireCount = 1;
}
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "acquire %d to %d for %p\n", fprintf(stderr, "acquire %"LD" for %p\n", r - c->registers, newValue);
r->number, r->acquireCount, newValue);
} }
r->size = newSize; r->size = newSize;
@ -2173,65 +2361,21 @@ acquire(Context* c, uint32_t mask, Stack* stack, Local* locals,
} }
void void
release(Context* c UNUSED, Register* r) release(Context* c, Register* r)
{ {
if (r->reserved) return; if (r->reserved) return;
assert(c, r->acquireCount > 0);
if (DebugRegisters) { if (DebugRegisters) {
fprintf(stderr, "release %d to %d for %p\n", fprintf(stderr, "release %"LD" for %p\n", r - c->registers, r->value);
r->number, r->acquireCount - 1, r->value);
} }
if ((-- r->acquireCount) == 0) { assert(c, r->value);
r->size = 0; assert(c, r->site);
r->value = 0; assert(c, r->size);
r->site = 0;
}
}
Register* r->size = 0;
validate(Context* c, uint32_t mask, Stack* stack, Local* locals, r->value = 0;
unsigned size, Value* value, RegisterSite* site, Register* current) r->site = 0;
{
if (current and (mask & (1 << current->number))) {
if (DebugRegisters and (current->value == value or current->value == 0)) {
fprintf(stderr,
"validate acquire %d to %d for %p\n",
current->number, current->value ? current->acquireCount + 1 : 1,
value);
}
if (current->reserved or current->value == value) {
if (not current->reserved) {
++ current->acquireCount;
}
return current;
} else if (current->value == 0) {
current->acquireCount = 1;
current->size = size;
current->value = value;
current->site = site;
return current;
}
}
Register* r = acquire(c, mask, stack, locals, size, value, site);
if (current and current != r) {
release(c, current);
Assembler::Register rr(r->number);
Assembler::Register cr(current->number);
c->assembler->apply
(Move, BytesPerWord, RegisterOperand, &cr,
BytesPerWord, RegisterOperand, &rr);
}
return r;
} }
bool bool
@ -2269,6 +2413,9 @@ acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
assert(c, frameIndex >= 0); assert(c, frameIndex >= 0);
assert(c, frameIndex < static_cast<int> assert(c, frameIndex < static_cast<int>
(c->alignedFrameSize + c->parameterFootprint)); (c->alignedFrameSize + c->parameterFootprint));
assert(c, newValue);
assert(c, newSite);
assert(c, newSize);
FrameResource* r = c->frameResources + frameIndex; FrameResource* r = c->frameResources + frameIndex;
@ -2281,7 +2428,6 @@ acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
Value* oldValue = r->value; Value* oldValue = r->value;
if (oldValue if (oldValue
and oldValue != newValue
and findSite(c, oldValue, r->site)) and findSite(c, oldValue, r->site))
{ {
if (buddies(oldValue, newValue)) { if (buddies(oldValue, newValue)) {
@ -2294,17 +2440,10 @@ acquireFrameIndex(Context* c, int frameIndex, Stack* stack, Local* locals,
} }
} }
if (oldValue == newValue) {
++ r->acquireCount;
} else {
r->acquireCount = 1;
}
if (DebugFrameIndexes) { if (DebugFrameIndexes) {
fprintf(stderr, fprintf(stderr,
"acquire frame index %d offset 0x%x to %d for %p\n", "acquire frame index %d offset 0x%x for %p\n",
frameIndex, frameIndexToOffset(c, frameIndex), r->acquireCount, frameIndex, frameIndexToOffset(c, frameIndex), newValue);
newValue);
} }
r->includeNeighbor = includeNeighbor; r->includeNeighbor = includeNeighbor;
@ -2321,22 +2460,23 @@ releaseFrameIndex(Context* c, int frameIndex)
(c->alignedFrameSize + c->parameterFootprint)); (c->alignedFrameSize + c->parameterFootprint));
FrameResource* r = c->frameResources + frameIndex; FrameResource* r = c->frameResources + frameIndex;
assert(c, r->acquireCount > 0); assert(c, r->value);
if (r->includeNeighbor) { if (r->includeNeighbor) {
releaseFrameIndex(c, frameIndex + 1); releaseFrameIndex(c, frameIndex + 1);
} }
if (DebugFrameIndexes) { if (DebugFrameIndexes) {
fprintf(stderr, "release frame index %d to %d for %p\n", fprintf(stderr, "release frame index %d for %p\n", frameIndex, r->value);
frameIndex, r->acquireCount - 1, r->value);
} }
if ((-- r->acquireCount) == 0) { assert(c, r->value);
r->size = 0; assert(c, r->site);
r->value = 0; assert(c, r->size);
r->site = 0;
} r->size = 0;
r->value = 0;
r->site = 0;
} }
void void
@ -2466,10 +2606,10 @@ clean(Context* c, Value* v, unsigned popIndex)
(c, static_cast<MemorySite*>(s)->value.offset) (c, static_cast<MemorySite*>(s)->value.offset)
>= popIndex)) >= popIndex))
{ {
// char buffer[256]; s->toString(c, buffer, 256); char buffer[256]; s->toString(c, buffer, 256);
// fprintf(stderr, "remove %s from %p at %d pop index %d\n", fprintf(stderr, "remove %s from %p at %d pop index %d\n",
// buffer, v, offsetToFrameIndex buffer, v, offsetToFrameIndex
// (c, static_cast<MemorySite*>(s)->value.offset), popIndex); (c, static_cast<MemorySite*>(s)->value.offset), popIndex);
it.remove(c); it.remove(c);
} }
} }
@ -3346,7 +3486,7 @@ class MemoryEvent: public Event {
result->target = memorySite result->target = memorySite
(c, baseRegister, displacement, indexRegister, scale); (c, baseRegister, displacement, indexRegister, scale);
addSite(c, 0, 0, 0, result, result->target); addSite(c, c->stack, c->locals, 0, result, result->target);
} }
Value* base; Value* base;
@ -3494,12 +3634,10 @@ class BoundsCheckEvent: public Event {
assert(c, object->source->type(c) == RegisterOperand); assert(c, object->source->type(c) == RegisterOperand);
int base = static_cast<RegisterSite*>(object->source)->register_.low; int base = static_cast<RegisterSite*>(object->source)->register_.low;
Site* length = memorySite(c, base, lengthOffset); MemorySite length(base, lengthOffset, NoRegister, 1);
length->acquire(c, 0, 0, 0, 0); length.base = c->registers + base;
apply(c, Compare, 4, index->source, 4, length); apply(c, Compare, 4, index->source, 4, &length);
length->release(c);
Assembler::Constant nextConstant(nextPromise); Assembler::Constant nextConstant(nextPromise);
a->apply(JumpIfGreater, BytesPerWord, ConstantOperand, &nextConstant); a->apply(JumpIfGreater, BytesPerWord, ConstantOperand, &nextConstant);
@ -4403,23 +4541,23 @@ class Client: public Assembler::Client {
Client(Context* c): c(c) { } Client(Context* c): c(c) { }
virtual int acquireTemporary(uint32_t mask) { virtual int acquireTemporary(uint32_t mask) {
int r = pickRegister(c, mask)->number; int r = pickRegister(c, mask) - c->registers;
save(r); save(r);
increment(c, r); increment(c, c->registers + r);
return r; return r;
} }
virtual void releaseTemporary(int r) { virtual void releaseTemporary(int r) {
decrement(c, c->registers[r]); decrement(c, c->registers + r);
restore(r); restore(r);
} }
virtual void save(int r) { virtual void save(int r) {
Register* reg = c->registers[r]; Register* reg = c->registers + r;
if (reg->refCount or reg->value) { if (reg->value or reg->referenceCount) {
releaseRegister(c, r); releaseRegister(c, r);
} }
assert(c, reg->refCount == 0); assert(c, reg->referenceCount == 0);
assert(c, reg->value == 0); assert(c, reg->value == 0);
} }