various bugfixes

This commit is contained in:
Joel Dice 2008-04-30 09:44:17 -06:00
parent 3909e3f032
commit e2b24263a2
5 changed files with 196 additions and 169 deletions

View File

@ -27,7 +27,7 @@ vmCall();
namespace {
const bool Verbose = true;
const bool Verbose = false;
const bool DebugNatives = false;
const bool DebugCallTable = false;
const bool DebugMethodTree = false;
@ -3875,11 +3875,11 @@ finish(MyThread* t, Context* context)
strcmp
(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"Floats") == 0 and
"org/eclipse/swt/graphics/ImageData") == 0 and
strcmp
(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)),
"multiply") == 0)
"<clinit>") == 0)
{
asm("int3");
}

View File

@ -387,6 +387,21 @@ removeSite(Context* c, Value* v, Site* s)
}
}
void
removeMemorySites(Context* c, Value* v)
{
for (Site** p = &(v->sites); *p;) {
if ((*p)->type(c) == MemoryOperand) {
// fprintf(stderr, "remove site %p (%d) from %p\n", s, s->type(c), v);
(*p)->release(c);
*p = (*p)->next;
break;
} else {
p = &((*p)->next);
}
}
}
void
clearSites(Context* c, Value* v)
{
@ -542,7 +557,7 @@ registerSite(Context* c, int low, int high = NoRegister)
}
RegisterSite*
freeRegister(Context* c, unsigned size, bool allowAcquired);
freeRegister(Context* c, unsigned size);
void
increment(Context* c, int r)
@ -662,14 +677,40 @@ targetOrNull(Context* c, Value* v, Event* event)
}
}
bool
used(Context* c, int r)
{
Value* v = c->registers[r].value;
// 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
usedExclusively(Context* c, int r)
{
Value* v = c->registers[r].value;
return used(c, r) and v->sites->next == 0;
}
bool
isFree(Context* c, Site* s)
{
return s->type(c) != RegisterOperand
or not (usedExclusively(c, static_cast<RegisterSite*>(s)->register_.low)
or (static_cast<RegisterSite*>(s)->register_.high != NoRegister
and usedExclusively
(c, static_cast<RegisterSite*>(s)->register_.high)));
}
Site*
targetOrRegister(Context* c, unsigned size, Value* v, Event* event)
{
Site* s = targetOrNull(c, v, event);
if (s) {
if (s and isFree(c, s)) {
return s;
} else {
return freeRegister(c, size, true);
return freeRegister(c, size);
}
}
@ -687,7 +728,7 @@ class ValueSite: public AbstractSite {
return s;
}
}
return freeRegister(c, r->size, true);
return freeRegister(c, r->size);
}
}
@ -729,7 +770,7 @@ class AnyRegisterSite: public AbstractSite {
return s;
}
}
return freeRegister(c, r->size, true);
return freeRegister(c, r->size);
}
};
@ -748,7 +789,7 @@ class ConstantOrRegisterSite: public AbstractSite {
return s;
}
}
return freeRegister(c, r->size, true);
return freeRegister(c, r->size);
}
};
@ -800,6 +841,8 @@ pushNow(Context* c, Stack* start, unsigned count)
if (s->value and s->value->sites) {
Site* source = pick(c, s->value->sites);
removeMemorySites(c, s->value);
s->pushSite = pushSite(c, s->index);
addSite(c, 0, s->size * BytesPerWord, s->value, s->pushSite);
@ -1276,7 +1319,7 @@ maybePreserve(Context* c, Stack* stack, unsigned size, Value* v, Site* s)
{
if (v->reads->next and v->sites->next == 0) {
assert(c, v->sites == s);
Site* r = freeRegister(c, size, true);
Site* r = freeRegister(c, size);
addSite(c, stack, size, v, r);
apply(c, Move, size, s, r);
}
@ -1682,68 +1725,24 @@ appendPop(Context* c, unsigned count, bool ignore)
new (c->zone->allocate(sizeof(PopEvent))) PopEvent(c, count, ignore);
}
// void
// swapRegisters(Context* c, int* ap, int* bp)
// {
// Assembler::Register a(*ap);
// Assembler::Register b(*bp);
// c->assembler->apply
// (Xor, BytesPerWord, RegisterOperand, &a, RegisterOperand, &b);
// c->assembler->apply
// (Xor, BytesPerWord, RegisterOperand, &b, RegisterOperand, &a);
// c->assembler->apply
// (Xor, BytesPerWord, RegisterOperand, &a, RegisterOperand, &b);
// int t = *ap;
// *ap = *bp;
// *bp = t;
// }
Site*
readSource(Context* c, Stack* stack, Read* r, Event* e)
{
Site* target = (r->target ? r->target->readTarget(c, r, e) : 0);
if (target and not isFree(c, target)) {
target = 0;
}
unsigned copyCost;
Site* site = pick(c, r->value->sites, target, &copyCost);
if (target) {
if (copyCost) {
if (tryAddSite(c, stack, r->size, r->value, target)) {
apply(c, Move, r->size, site, target);
return target;
} else {
abort(c);
// // this is a filthy hack, but I think the core idea is right:
// assert(c, target->type(c) == RegisterOperand);
// RegisterSite* ts = static_cast<RegisterSite*>(target);
// for (Site* s = r->value->sites; s; s = s->next) {
// if (s->type(c) == RegisterOperand) {
// RegisterSite* rs = static_cast<RegisterSite*>(s);
// RegisterSite* os = static_cast<RegisterSite*>
// (c->registers[ts->register_.low].site);
// assert(c, os->register_.low == ts->register_.low);
// assert(c, os->register_.high == NoRegister);
// assert(c, ts->register_.high == NoRegister);
// assert(c, rs->register_.high == NoRegister);
// swapRegisters(c, &(os->register_.low), &(rs->register_.low));
// return rs;
// }
// }
}
abort(c);
} else {
return target;
addSite(c, stack, r->size, r->value, target);
apply(c, Move, r->size, site, target);
}
return target;
} else {
return site;
}
@ -1896,24 +1895,8 @@ updateJunctions(Context* c)
}
}
bool
used(Context* c, int r)
{
Value* v = c->registers[r].value;
// 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
usedExclusively(Context* c, int r)
{
Value* v = c->registers[r].value;
return used(c, r) and v->sites->next == 0;
}
int
freeRegisterExcept(Context* c, int except, bool allowAcquired)
freeRegisterExcept(Context* c, int except)
{
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except
@ -1924,22 +1907,20 @@ freeRegisterExcept(Context* c, int except, bool allowAcquired)
}
}
if (allowAcquired) {
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except
and c->registers[i].refCount == 0
and (not usedExclusively(c, i)))
{
return i;
}
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except
and c->registers[i].refCount == 0
and (not usedExclusively(c, i)))
{
return i;
}
}
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except
and c->registers[i].refCount == 0)
{
return i;
}
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
if (i != except
and c->registers[i].refCount == 0)
{
return i;
}
}
@ -1959,21 +1940,21 @@ visit(Context* c, unsigned logicalIp)
}
int
freeRegister(Context* c, bool allowAcquired)
freeRegister(Context* c)
{
int r = freeRegisterExcept(c, NoRegister, allowAcquired);
int r = freeRegisterExcept(c, NoRegister);
// fprintf(stderr, "free reg: %d\n", r);
return r;
}
RegisterSite*
freeRegister(Context* c, unsigned size, bool allowAcquired)
freeRegister(Context* c, unsigned size)
{
if (BytesPerWord == 4 and size == 8) {
int low = freeRegister(c, allowAcquired);
return registerSite(c, low, freeRegisterExcept(c, low, allowAcquired));
int low = freeRegister(c);
return registerSite(c, low, freeRegisterExcept(c, low));
} else {
return registerSite(c, freeRegister(c, allowAcquired));
return registerSite(c, freeRegister(c));
}
}
@ -1982,13 +1963,15 @@ class Client: public Assembler::Client {
Client(Context* c): c(c) { }
virtual int acquireTemporary() {
int r = freeRegisterExcept(c, NoRegister, false);
int r = freeRegisterExcept(c, NoRegister);
save(r);
increment(c, r);
return r;
}
virtual void releaseTemporary(int r) {
decrement(c, r);
restore(r);
}
virtual void save(int r) {

View File

@ -29,7 +29,7 @@ const unsigned InitialTenuredFixieCeilingInBytes = 4 * 1024 * 1024;
const unsigned LowMemoryPaddingInBytes = 1024 * 1024;
const bool Verbose = true;
const bool Verbose = false;
const bool Verbose2 = false;
const bool Debug = false;
const bool DebugFixies = false;

View File

@ -563,7 +563,7 @@ popM(Context* c, unsigned size, Assembler::Memory* a)
}
void
addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
addCarryCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4);
@ -1096,7 +1096,7 @@ addCR(Context* c, unsigned size, Assembler::Constant* a,
}
void
subtractBorrowCR(Context* c, unsigned size, Assembler::Constant* a,
subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4);
@ -1112,7 +1112,7 @@ subtractBorrowCR(Context* c, unsigned size, Assembler::Constant* a,
}
void
subtractCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
subtractCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{
int64_t v = a->value->value();
@ -1157,7 +1157,7 @@ subtractRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
}
void
addCarryRR(Context* c, unsigned size, Assembler::Register* a,
addCarryRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4);
@ -1286,7 +1286,7 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register ax(rax);
Assembler::Register divisor(a->low);
if (a->low == rdx) {
if (a->low == rdx or a->low == rax) {
divisor.low = c->client->acquireTemporary();
moveRR(c, BytesPerWord, a, &divisor);
} else if (b->low != rdx) {
@ -1294,7 +1294,9 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
}
if (b->low != rax) {
c->client->save(rax);
if (a->low != rax) {
c->client->save(rax);
}
moveRR(c, BytesPerWord, b, &ax);
}
@ -1306,10 +1308,12 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
if (b->low != rax) {
moveRR(c, BytesPerWord, &ax, b);
c->client->restore(rax);
if (a->low != rax) {
c->client->restore(rax);
}
}
if (a->low == rdx) {
if (a->low == rdx or a->low == rax) {
moveRR(c, BytesPerWord, &divisor, a);
c->client->releaseTemporary(divisor.low);
} else if (b->low != rdx) {
@ -1354,7 +1358,7 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register dx(rdx);
Assembler::Register divisor(a->low);
if (a->low == rdx) {
if (a->low == rdx or a->low == rax) {
divisor.low = c->client->acquireTemporary();
moveRR(c, BytesPerWord, a, &divisor);
} else if (b->low != rdx) {
@ -1362,7 +1366,9 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
}
if (b->low != rax) {
c->client->save(rax);
if (a->low != rax) {
c->client->save(rax);
}
moveRR(c, BytesPerWord, b, &ax);
}
@ -1376,11 +1382,11 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
moveRR(c, BytesPerWord, &dx, b);
}
if (b->low != rax) {
if (b->low != rax and a->low != rax) {
c->client->restore(rax);
}
if (a->low == rdx) {
if (a->low == rdx or a->low == rax) {
moveRR(c, BytesPerWord, &divisor, a);
c->client->releaseTemporary(divisor.low);
} else if (b->low != rdx) {
@ -1389,6 +1395,33 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
}
}
void
remainderCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{
if (BytesPerWord == 4 and size == 8) {
pushC(c, size, a);
pushR(c, size, b);
Assembler::Constant address
(resolved(c, reinterpret_cast<intptr_t>(moduloLong)));
callC(c, BytesPerWord, &address);
Assembler::Register axdx(rax, rdx);
moveRR(c, 4, &axdx, b);
ResolvedPromise offsetPromise(16);
Assembler::Constant offset(&offsetPromise);
Assembler::Register stack(rsp);
addCR(c, BytesPerWord, &offset, &stack);
} else {
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, a, &tmp);
remainderRR(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
}
void
andRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b)
@ -1775,7 +1808,7 @@ unsignedShiftRightCR(Context* c, unsigned size, Assembler::Constant* a,
}
void
compareRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
compareRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b)
{
if (BytesPerWord == 4 and size == 8) {
@ -1799,7 +1832,7 @@ compareRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
}
void
compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
compareCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{
int64_t v = a->value->value();
@ -1988,6 +2021,7 @@ populateTables()
BinaryOperations[INDEX2(Divide, Register, Register)] = CAST2(divideRR);
BinaryOperations[INDEX2(Divide, Constant, Register)] = CAST2(divideCR);
BinaryOperations[INDEX2(Remainder, Constant, Register)] = CAST2(remainderCR);
BinaryOperations[INDEX2(Remainder, Register, Register)] = CAST2(remainderRR);
BinaryOperations[INDEX2(And, Register, Register)] = CAST2(andRR);

View File

@ -66,75 +66,85 @@ public class Misc {
return super.toString();
}
private static int zap() {
return 42;
}
private static int zip() {
return 5 + zap();
}
public static void main(String[] args) {
byte2 = 0;
expect(byte2 == 0);
// byte2 = 0;
// expect(byte2 == 0);
expect(Long.valueOf(231L) == 231L);
// expect(Long.valueOf(231L) == 231L);
long x = 231;
expect((x >> 32) == 0);
expect((x >>> 32) == 0);
expect((x << 32) == 992137445376L);
// long x = 231;
// expect((x >> 32) == 0);
// expect((x >>> 32) == 0);
// expect((x << 32) == 992137445376L);
int shift = 32;
expect((x >> shift) == 0);
expect((x >>> shift) == 0);
expect((x << shift) == 992137445376L);
// int shift = 32;
// expect((x >> shift) == 0);
// expect((x >>> shift) == 0);
// expect((x << shift) == 992137445376L);
long y = -231;
expect((y >> 32) == 0xffffffffffffffffL);
expect((y >>> 32) == 0xffffffffL);
// long y = -231;
// expect((y >> 32) == 0xffffffffffffffffL);
// expect((y >>> 32) == 0xffffffffL);
byte[] array = new byte[8];
putLong(231, array, 0);
expect((array[0] & 0xff) == 0);
expect((array[1] & 0xff) == 0);
expect((array[2] & 0xff) == 0);
expect((array[3] & 0xff) == 0);
expect((array[4] & 0xff) == 0);
expect((array[5] & 0xff) == 0);
expect((array[6] & 0xff) == 0);
expect((array[7] & 0xff) == 231);
// byte[] array = new byte[8];
// putLong(231, array, 0);
// expect((array[0] & 0xff) == 0);
// expect((array[1] & 0xff) == 0);
// expect((array[2] & 0xff) == 0);
// expect((array[3] & 0xff) == 0);
// expect((array[4] & 0xff) == 0);
// expect((array[5] & 0xff) == 0);
// expect((array[6] & 0xff) == 0);
// expect((array[7] & 0xff) == 231);
java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
buffer.putLong(231);
buffer.flip();
expect(buffer.getLong() == 231);
// java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(8);
// buffer.putLong(231);
// buffer.flip();
// expect(buffer.getLong() == 231);
boolean v = Boolean.valueOf("true");
// boolean v = Boolean.valueOf("true");
ClassLoader.getSystemClassLoader().toString();
// ClassLoader.getSystemClassLoader().toString();
int a = 2;
int b = 2;
int c = a + b;
// int a = 2;
// int b = 2;
// int c = a + b;
Misc m = new Misc();
m.toString();
// Misc m = new Misc();
// m.toString();
String s = "hello";
m.foo(s);
m.bar(s);
baz(s);
// String s = "hello";
// m.foo(s);
// m.bar(s);
// baz(s);
m.sync();
syncStatic(false);
try {
syncStatic(true);
} catch (RuntimeException e) {
e.printStackTrace();
}
// m.sync();
// syncStatic(false);
// try {
// syncStatic(true);
// } catch (RuntimeException e) {
// e.printStackTrace();
// }
int d = alpha;
beta = 42;
alpha = 43;
int e = beta;
int f = alpha;
m.gamma = 44;
// int d = alpha;
// beta = 42;
// alpha = 43;
// int e = beta;
// int f = alpha;
// m.gamma = 44;
expect(beta == 42);
expect(alpha == 43);
expect(m.gamma == 44);
// expect(beta == 42);
// expect(alpha == 43);
// expect(m.gamma == 44);
zip();
}
}