mirror of
https://github.com/corda/corda.git
synced 2025-01-23 21:08:48 +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 int acquireTemporary(int r = NoRegister) = 0;
|
||||||
virtual void releaseTemporary(int r) = 0;
|
virtual void releaseTemporary(int r) = 0;
|
||||||
|
|
||||||
|
virtual void save(int r) = 0;
|
||||||
|
virtual void restore(int r) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Assembler() { }
|
virtual ~Assembler() { }
|
||||||
|
@ -3828,11 +3828,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/StringBuilder") == 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)),
|
||||||
"<init>") == 0)
|
"replace") == 0)
|
||||||
{
|
{
|
||||||
asm("int3");
|
asm("int3");
|
||||||
}
|
}
|
||||||
|
127
src/compiler.cpp
127
src/compiler.cpp
@ -15,10 +15,10 @@ using namespace vm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool DebugAppend = true;
|
const bool DebugAppend = false;
|
||||||
const bool DebugCompile = true;
|
const bool DebugCompile = false;
|
||||||
const bool DebugStack = true;
|
const bool DebugStack = false;
|
||||||
const bool DebugRegisters = true;
|
const bool DebugRegisters = false;
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
class Value;
|
class Value;
|
||||||
@ -101,6 +101,7 @@ class Register {
|
|||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned refCount;
|
unsigned refCount;
|
||||||
bool reserved;
|
bool reserved;
|
||||||
|
bool pushed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConstantPoolNode {
|
class ConstantPoolNode {
|
||||||
@ -826,6 +827,42 @@ pushNow(Context* c, Stack* start)
|
|||||||
pushNow(c, start, count);
|
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
|
bool
|
||||||
tryAcquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
tryAcquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
||||||
Site* newSite)
|
Site* newSite)
|
||||||
@ -842,33 +879,9 @@ tryAcquire(Context* c, int r, Stack* stack, unsigned newSize, Value* newValue,
|
|||||||
and oldValue != newValue
|
and oldValue != newValue
|
||||||
and findSite(c, oldValue, c->registers[r].site))
|
and findSite(c, oldValue, c->registers[r].site))
|
||||||
{
|
{
|
||||||
assert(c, c->registers[r].refCount == 0);
|
if (not trySteal(c, r, stack)) {
|
||||||
|
return false;
|
||||||
if (DebugRegisters) {
|
|
||||||
fprintf(stderr, "try steal %d from %p: next: %p\n",
|
|
||||||
r, oldValue, oldValue->sites->next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
c->registers[r].size = newSize;
|
||||||
@ -1182,15 +1195,15 @@ class MoveEvent: public Event {
|
|||||||
|
|
||||||
nextRead(c, src);
|
nextRead(c, src);
|
||||||
|
|
||||||
|
if (cost) {
|
||||||
|
apply(c, type, size, src->source, target);
|
||||||
|
}
|
||||||
|
|
||||||
if (dst->reads) {
|
if (dst->reads) {
|
||||||
addSite(c, stack, size, dst, target);
|
addSite(c, stack, size, dst, target);
|
||||||
} else {
|
} else {
|
||||||
removeSite(c, dst, target);
|
removeSite(c, dst, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cost) {
|
|
||||||
apply(c, type, size, src->source, target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryOperation type;
|
BinaryOperation type;
|
||||||
@ -1730,7 +1743,7 @@ compile(Context* c)
|
|||||||
|
|
||||||
for (Event* e = li->firstEvent; e; e = e->next) {
|
for (Event* e = li->firstEvent; e; e = e->next) {
|
||||||
if (e->stackReset) {
|
if (e->stackReset) {
|
||||||
fprintf(stderr, "stack reset\n");
|
// fprintf(stderr, "stack reset\n");
|
||||||
for (Stack* s = e->stack; s; s = s->next) {
|
for (Stack* s = e->stack; s; s = s->next) {
|
||||||
if (s->value->sites) {
|
if (s->value->sites) {
|
||||||
assert(c, s->value->sites->next == 0);
|
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) {
|
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) {
|
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
||||||
if (i != except
|
if (i != except
|
||||||
and c->registers[i].refCount == 0)
|
and c->registers[i].refCount == 0)
|
||||||
@ -1924,8 +1937,9 @@ class Client: public Assembler::Client {
|
|||||||
if (r == NoRegister) {
|
if (r == NoRegister) {
|
||||||
r = freeRegisterExcept(c, NoRegister, false);
|
r = freeRegisterExcept(c, NoRegister, false);
|
||||||
} else {
|
} else {
|
||||||
expect(c, c->registers[r].refCount == 0);
|
expect(c, (c->registers[r].refCount == 0
|
||||||
expect(c, c->registers[r].value == 0);
|
and c->registers[r].value == 0)
|
||||||
|
or c->registers[r].pushed);
|
||||||
}
|
}
|
||||||
increment(c, r);
|
increment(c, r);
|
||||||
return r;
|
return r;
|
||||||
@ -1935,6 +1949,22 @@ class Client: public Assembler::Client {
|
|||||||
decrement(c, r);
|
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;
|
Context* c;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2092,7 +2122,10 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void push(unsigned size) {
|
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) {
|
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 {
|
} else {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
|
rex(c);
|
||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
c->code.append(0x0f);
|
c->code.append(0x0f);
|
||||||
}
|
}
|
||||||
@ -606,6 +607,7 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
|
rex(c);
|
||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
c->code.append(0x0f);
|
c->code.append(0x0f);
|
||||||
}
|
}
|
||||||
@ -675,7 +677,7 @@ move4To8RR(Context* c, unsigned size UNUSED, Assembler::Register* a,
|
|||||||
if (BytesPerWord == 8) {
|
if (BytesPerWord == 8) {
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0x63);
|
c->code.append(0x63);
|
||||||
c->code.append(0xc0 | (a->low << 3) | b->low);
|
c->code.append(0xc0 | (b->low << 3) | a->low);
|
||||||
} else {
|
} else {
|
||||||
if (a->low == rax and b->low == rax and b->high == rdx) {
|
if (a->low == rax and b->low == rax and b->high == rdx) {
|
||||||
c->code.append(0x99); // cdq
|
c->code.append(0x99); // cdq
|
||||||
@ -897,6 +899,8 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
{
|
{
|
||||||
if (BytesPerWord == 4 and size == 8) {
|
if (BytesPerWord == 4 and size == 8) {
|
||||||
|
abort(c); // todo: sync stack first
|
||||||
|
|
||||||
Assembler::Register axdx(c->client->acquireTemporary(rax),
|
Assembler::Register axdx(c->client->acquireTemporary(rax),
|
||||||
c->client->acquireTemporary(rdx));
|
c->client->acquireTemporary(rdx));
|
||||||
|
|
||||||
@ -918,10 +922,18 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
c->client->releaseTemporary(axdx.high);
|
c->client->releaseTemporary(axdx.high);
|
||||||
} else {
|
} else {
|
||||||
Assembler::Register ax(rax);
|
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) {
|
if (b->low != rax) {
|
||||||
c->client->acquireTemporary(ax.low);
|
c->client->save(rax);
|
||||||
|
c->client->acquireTemporary(rax);
|
||||||
moveRR(c, BytesPerWord, b, &ax);
|
moveRR(c, BytesPerWord, b, &ax);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,14 +941,85 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
|
|||||||
c->code.append(0x99);
|
c->code.append(0x99);
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0xf7);
|
c->code.append(0xf7);
|
||||||
c->code.append(0xf8 | a->low);
|
c->code.append(0xf8 | divisor.low);
|
||||||
|
|
||||||
if (b->low != rax) {
|
if (b->low != rax) {
|
||||||
moveRR(c, BytesPerWord, &ax, b);
|
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(Divide, Register, Register)] = CAST2(divideRR);
|
||||||
|
|
||||||
|
BinaryOperations[INDEX2(Remainder, Register, Register)] = CAST2(remainderRR);
|
||||||
|
|
||||||
BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR);
|
BinaryOperations[INDEX2(And, Constant, Register)] = CAST2(andCR);
|
||||||
BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM);
|
BinaryOperations[INDEX2(And, Constant, Memory)] = CAST2(andCM);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user