mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
various bugfixes; majority of tests now pass
This commit is contained in:
parent
d5137a7cdf
commit
5b7372a3bb
@ -136,6 +136,9 @@ class Assembler {
|
||||
|
||||
virtual int acquireTemporary(int r = NoRegister) = 0;
|
||||
virtual void releaseTemporary(int r) = 0;
|
||||
|
||||
virtual void save(int r) = 0;
|
||||
virtual void restore(int r) = 0;
|
||||
};
|
||||
|
||||
virtual ~Assembler() { }
|
||||
|
@ -3828,11 +3828,11 @@ finish(MyThread* t, Context* context)
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
||||
"java/lang/StringBuilder") == 0 and
|
||||
"java/lang/Class") == 0 and
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
||||
"<init>") == 0)
|
||||
"replace") == 0)
|
||||
{
|
||||
asm("int3");
|
||||
}
|
||||
|
127
src/compiler.cpp
127
src/compiler.cpp
@ -15,10 +15,10 @@ using namespace vm;
|
||||
|
||||
namespace {
|
||||
|
||||
const bool DebugAppend = true;
|
||||
const bool DebugCompile = true;
|
||||
const bool DebugStack = true;
|
||||
const bool DebugRegisters = true;
|
||||
const bool DebugAppend = false;
|
||||
const bool DebugCompile = false;
|
||||
const bool DebugStack = false;
|
||||
const bool DebugRegisters = false;
|
||||
|
||||
class Context;
|
||||
class Value;
|
||||
@ -101,6 +101,7 @@ class Register {
|
||||
unsigned size;
|
||||
unsigned refCount;
|
||||
bool reserved;
|
||||
bool pushed;
|
||||
};
|
||||
|
||||
class ConstantPoolNode {
|
||||
@ -826,6 +827,42 @@ pushNow(Context* c, Stack* start)
|
||||
pushNow(c, start, count);
|
||||
}
|
||||
|
||||
bool
|
||||
trySteal(Context* c, int r, Stack* stack)
|
||||
{
|
||||
Value* v = c->registers[r].value;
|
||||
|
||||
assert(c, c->registers[r].refCount == 0);
|
||||
|
||||
if (DebugRegisters) {
|
||||
fprintf(stderr, "try steal %d from %p: next: %p\n",
|
||||
r, v, v->sites->next);
|
||||
}
|
||||
|
||||
if (v->sites->next == 0) {
|
||||
unsigned count = 0;
|
||||
Stack* start = 0;
|
||||
for (Stack* s = stack; s and (not s->pushed); s = s->next) {
|
||||
if (s->value == v) {
|
||||
start = s;
|
||||
}
|
||||
if (start) {
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
|
||||
if (start) {
|
||||
pushNow(c, start, count);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
removeSite(c, v, c->registers[r].site);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
tryAcquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
||||
Site* newSite)
|
||||
@ -842,33 +879,9 @@ tryAcquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
||||
and oldValue != newValue
|
||||
and findSite(c, oldValue, c->registers[r].site))
|
||||
{
|
||||
assert(c, c->registers[r].refCount == 0);
|
||||
|
||||
if (DebugRegisters) {
|
||||
fprintf(stderr, "try steal %d from %p: next: %p\n",
|
||||
r, oldValue, oldValue->sites->next);
|
||||
if (not trySteal(c, r, stack)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldValue->sites->next == 0) {
|
||||
unsigned count = 0;
|
||||
Stack* start = 0;
|
||||
for (Stack* s = stack; s and (not s->pushed); s = s->next) {
|
||||
if (s->value == oldValue) {
|
||||
start = s;
|
||||
}
|
||||
if (start) {
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
|
||||
if (start) {
|
||||
pushNow(c, start, count);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
removeSite(c, oldValue, c->registers[r].site);
|
||||
}
|
||||
|
||||
c->registers[r].size = newSize;
|
||||
@ -1182,15 +1195,15 @@ class MoveEvent: public Event {
|
||||
|
||||
nextRead(c, src);
|
||||
|
||||
if (cost) {
|
||||
apply(c, type, size, src->source, target);
|
||||
}
|
||||
|
||||
if (dst->reads) {
|
||||
addSite(c, stack, size, dst, target);
|
||||
} else {
|
||||
removeSite(c, dst, target);
|
||||
}
|
||||
|
||||
if (cost) {
|
||||
apply(c, type, size, src->source, target);
|
||||
}
|
||||
}
|
||||
|
||||
BinaryOperation type;
|
||||
@ -1730,7 +1743,7 @@ compile(Context* c)
|
||||
|
||||
for (Event* e = li->firstEvent; e; e = e->next) {
|
||||
if (e->stackReset) {
|
||||
fprintf(stderr, "stack reset\n");
|
||||
// fprintf(stderr, "stack reset\n");
|
||||
for (Stack* s = e->stack; s; s = s->next) {
|
||||
if (s->value->sites) {
|
||||
assert(c, s->value->sites->next == 0);
|
||||
@ -1863,16 +1876,16 @@ freeRegisterExcept(Context* c, int except, bool 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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
@ -1924,8 +1937,9 @@ class Client: public Assembler::Client {
|
||||
if (r == NoRegister) {
|
||||
r = freeRegisterExcept(c, NoRegister, false);
|
||||
} else {
|
||||
expect(c, c->registers[r].refCount == 0);
|
||||
expect(c, c->registers[r].value == 0);
|
||||
expect(c, (c->registers[r].refCount == 0
|
||||
and c->registers[r].value == 0)
|
||||
or c->registers[r].pushed);
|
||||
}
|
||||
increment(c, r);
|
||||
return r;
|
||||
@ -1935,6 +1949,22 @@ class Client: public Assembler::Client {
|
||||
decrement(c, r);
|
||||
}
|
||||
|
||||
virtual void save(int r) {
|
||||
if (c->registers[r].refCount or c->registers[r].value) {
|
||||
Assembler::Register operand(r);
|
||||
c->assembler->apply(Push, BytesPerWord, RegisterOperand, &operand);
|
||||
c->registers[r].pushed = true;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void restore(int r) {
|
||||
if (c->registers[r].pushed) {
|
||||
Assembler::Register operand(r);
|
||||
c->assembler->apply(Pop, BytesPerWord, RegisterOperand, &operand);
|
||||
c->registers[r].pushed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Context* c;
|
||||
};
|
||||
|
||||
@ -2092,7 +2122,10 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual void push(unsigned size) {
|
||||
::push(&c, size, value(&c));
|
||||
assert(&c, ceiling(size, BytesPerWord));
|
||||
|
||||
c.state->stack = ::stack
|
||||
(&c, value(&c), ceiling(size, BytesPerWord), c.state->stack);
|
||||
}
|
||||
|
||||
virtual void push(unsigned size, Operand* value) {
|
||||
|
97
src/x86.cpp
97
src/x86.cpp
@ -598,6 +598,7 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
} else {
|
||||
switch (size) {
|
||||
case 1:
|
||||
rex(c);
|
||||
if (BytesPerWord == 8) {
|
||||
c->code.append(0x0f);
|
||||
}
|
||||
@ -606,6 +607,7 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
break;
|
||||
|
||||
case 2:
|
||||
rex(c);
|
||||
if (BytesPerWord == 8) {
|
||||
c->code.append(0x0f);
|
||||
}
|
||||
@ -675,7 +677,7 @@ move4To8RR(Context* c, unsigned size UNUSED, Assembler::Register* a,
|
||||
if (BytesPerWord == 8) {
|
||||
rex(c);
|
||||
c->code.append(0x63);
|
||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
||||
c->code.append(0xc0 | (b->low << 3) | a->low);
|
||||
} else {
|
||||
if (a->low == rax and b->low == rax and b->high == rdx) {
|
||||
c->code.append(0x99); // cdq
|
||||
@ -897,6 +899,8 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
abort(c); // todo: sync stack first
|
||||
|
||||
Assembler::Register axdx(c->client->acquireTemporary(rax),
|
||||
c->client->acquireTemporary(rdx));
|
||||
|
||||
@ -918,10 +922,18 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
c->client->releaseTemporary(axdx.high);
|
||||
} else {
|
||||
Assembler::Register ax(rax);
|
||||
Assembler::Register dx(c->client->acquireTemporary(rdx));
|
||||
Assembler::Register divisor(a->low);
|
||||
|
||||
if (a->low == rdx) {
|
||||
divisor.low = c->client->acquireTemporary();
|
||||
moveRR(c, BytesPerWord, a, &divisor);
|
||||
} else if (b->low != rdx) {
|
||||
c->client->save(rdx);
|
||||
}
|
||||
|
||||
if (b->low != rax) {
|
||||
c->client->acquireTemporary(ax.low);
|
||||
c->client->save(rax);
|
||||
c->client->acquireTemporary(rax);
|
||||
moveRR(c, BytesPerWord, b, &ax);
|
||||
}
|
||||
|
||||
@ -929,14 +941,85 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
c->code.append(0x99);
|
||||
rex(c);
|
||||
c->code.append(0xf7);
|
||||
c->code.append(0xf8 | a->low);
|
||||
c->code.append(0xf8 | divisor.low);
|
||||
|
||||
if (b->low != rax) {
|
||||
moveRR(c, BytesPerWord, &ax, b);
|
||||
c->client->releaseTemporary(ax.low);
|
||||
c->client->releaseTemporary(rax);
|
||||
c->client->restore(rax);
|
||||
}
|
||||
|
||||
c->client->releaseTemporary(dx.low);
|
||||
if (a->low == rdx) {
|
||||
moveRR(c, BytesPerWord, &divisor, a);
|
||||
c->client->releaseTemporary(divisor.low);
|
||||
} else if (b->low != rdx) {
|
||||
c->client->restore(rdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
remainderRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
abort(c); // todo: sync stack first
|
||||
|
||||
Assembler::Register axdx(c->client->acquireTemporary(rax),
|
||||
c->client->acquireTemporary(rdx));
|
||||
|
||||
pushR(c, size, a);
|
||||
pushR(c, size, b);
|
||||
|
||||
ResolvedPromise addressPromise(reinterpret_cast<intptr_t>(moduloLong));
|
||||
Assembler::Constant address(&addressPromise);
|
||||
callC(c, BytesPerWord, &address);
|
||||
|
||||
ResolvedPromise offsetPromise(16);
|
||||
Assembler::Constant offset(&offsetPromise);
|
||||
Assembler::Register stack(rsp);
|
||||
addCR(c, BytesPerWord, &offset, &stack);
|
||||
|
||||
moveRR(c, size, &axdx, b);
|
||||
|
||||
c->client->releaseTemporary(axdx.low);
|
||||
c->client->releaseTemporary(axdx.high);
|
||||
} else {
|
||||
Assembler::Register ax(rax);
|
||||
Assembler::Register dx(rdx);
|
||||
Assembler::Register divisor(a->low);
|
||||
|
||||
if (a->low == rdx) {
|
||||
divisor.low = c->client->acquireTemporary();
|
||||
moveRR(c, BytesPerWord, a, &divisor);
|
||||
} else if (b->low != rdx) {
|
||||
c->client->save(rdx);
|
||||
}
|
||||
|
||||
if (b->low != rax) {
|
||||
c->client->save(rax);
|
||||
c->client->acquireTemporary(rax);
|
||||
moveRR(c, BytesPerWord, b, &ax);
|
||||
}
|
||||
|
||||
rex(c);
|
||||
c->code.append(0x99);
|
||||
rex(c);
|
||||
c->code.append(0xf7);
|
||||
c->code.append(0xf8 | divisor.low);
|
||||
|
||||
if (b->low != rdx) {
|
||||
moveRR(c, BytesPerWord, &dx, b);
|
||||
c->client->releaseTemporary(rax);
|
||||
c->client->restore(rax);
|
||||
}
|
||||
|
||||
if (a->low == rdx) {
|
||||
moveRR(c, BytesPerWord, &divisor, a);
|
||||
c->client->releaseTemporary(divisor.low);
|
||||
} else if (b->low != rdx) {
|
||||
c->client->restore(rdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1167,6 +1250,8 @@ populateTables()
|
||||
|
||||
BinaryOperations[INDEX2(Divide, Register, Register)] = CAST2(divideRR);
|
||||
|
||||
BinaryOperations[INDEX2(Remainder, Register, Register)] = CAST2(remainderRR);
|
||||
|
||||
BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR);
|
||||
BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user