mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
lots of JIT bugfixes; all top-level tests now pass
This commit is contained in:
parent
25ea07aed5
commit
4c3a2575ba
2
makefile
2
makefile
@ -28,7 +28,7 @@ src = src
|
||||
classpath = classpath
|
||||
test = test
|
||||
|
||||
input = $(test-build)/List.class
|
||||
input = $(test-build)/Threads.class
|
||||
|
||||
build-cxx = g++
|
||||
build-cc = gcc
|
||||
|
@ -20,22 +20,14 @@ vmInvoke:
|
||||
|
||||
mov %rdi,%rbx
|
||||
|
||||
// reserve space for arguments
|
||||
pushq %rcx
|
||||
subq %rcx,%rsp
|
||||
|
||||
// copy memory arguments into place
|
||||
pushq %rcx
|
||||
movq $0,%r9
|
||||
jmp test
|
||||
|
||||
loop:
|
||||
movq %r9,%rax
|
||||
movq %r9,%r10
|
||||
addq %rsp,%r10
|
||||
addq %rdx,%rax
|
||||
movq (%rax),%rax
|
||||
movq %rax,(%r10)
|
||||
addq $8,%r9
|
||||
push (%rdx,%r9,8)
|
||||
inc %r9
|
||||
|
||||
test:
|
||||
cmpq %rcx,%r9
|
||||
@ -80,21 +72,13 @@ vmInvoke:
|
||||
|
||||
mov 8(%ebp),%ebx
|
||||
|
||||
// reserve space for arguments
|
||||
subl 20(%ebp),%esp
|
||||
|
||||
// copy arguments into place
|
||||
movl $0,%ecx
|
||||
jmp test
|
||||
|
||||
loop:
|
||||
movl %ecx,%eax
|
||||
movl %ecx,%edx
|
||||
addl %esp,%edx
|
||||
addl 16(%ebp),%eax
|
||||
movl (%eax),%eax
|
||||
movl %eax,(%edx)
|
||||
addl $4,%ecx
|
||||
push (%rdx,%rcx,4)
|
||||
inc %ecx
|
||||
|
||||
test:
|
||||
cmpl 20(%ebp),%ecx
|
||||
|
@ -18,7 +18,7 @@ vmJump(void* address, void* base, void* stack, void* thread);
|
||||
|
||||
namespace {
|
||||
|
||||
const bool Verbose = true;
|
||||
const bool Verbose = false;
|
||||
const bool DebugTraces = false;
|
||||
|
||||
class MyThread: public Thread {
|
||||
@ -612,7 +612,7 @@ class Frame {
|
||||
}
|
||||
|
||||
void pushObject() {
|
||||
stack = c->push(stack, 1);
|
||||
stack = c->pushed(stack, 1);
|
||||
pushedObject();
|
||||
}
|
||||
|
||||
@ -710,8 +710,8 @@ class Frame {
|
||||
|
||||
void loadObject(unsigned index) {
|
||||
assert(t, index < codeMaxLocals(t, methodCode(t, method)));
|
||||
assert(t, index < parameterFootprint(t, method)
|
||||
or getBit(map, index - parameterFootprint(t, method)) != 0);
|
||||
// assert(t, index < parameterFootprint(t, method)
|
||||
// or getBit(map, index - parameterFootprint(t, method)) != 0);
|
||||
pushObject(c->memory(c->base(), localOffset(t, index, method)));
|
||||
}
|
||||
|
||||
@ -1077,7 +1077,7 @@ makeBlankArray(Thread* t, object (*constructor)(Thread*, uintptr_t, bool),
|
||||
|
||||
uintptr_t
|
||||
lookUpAddress(int32_t key, uintptr_t* start, int32_t count,
|
||||
uintptr_t* default_)
|
||||
uintptr_t default_)
|
||||
{
|
||||
int32_t bottom = 0;
|
||||
int32_t top = count;
|
||||
@ -1095,7 +1095,7 @@ lookUpAddress(int32_t key, uintptr_t* start, int32_t count,
|
||||
}
|
||||
}
|
||||
|
||||
return *default_;
|
||||
return default_;
|
||||
}
|
||||
|
||||
void
|
||||
@ -2993,10 +2993,10 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
|
||||
if (false and
|
||||
strcmp(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
|
||||
"java/util/Collections$ArrayListIterator") == 0 and
|
||||
"java/lang/String") == 0 and
|
||||
strcmp(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodName(t, method), 0)),
|
||||
"<init>") == 0)
|
||||
"getChars") == 0)
|
||||
{
|
||||
asm("int3");
|
||||
}
|
||||
@ -3161,12 +3161,11 @@ invokeNative2(MyThread* t, object method)
|
||||
|
||||
case INT64_TYPE:
|
||||
case DOUBLE_TYPE: {
|
||||
memcpy(args + argOffset, sp, 8);
|
||||
if (BytesPerWord == 8) {
|
||||
uint64_t a = *(sp--);
|
||||
uint64_t b = *(sp--);
|
||||
args[argOffset++] = (a << 32) | b;
|
||||
++argOffset;
|
||||
--sp;
|
||||
} else {
|
||||
memcpy(args + argOffset, sp, 8);
|
||||
argOffset += 2;
|
||||
sp -= 2;
|
||||
}
|
||||
@ -3480,7 +3479,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
||||
|
||||
uint64_t result = vmInvoke
|
||||
(t, &singletonValue(t, methodCompiled(t, method), 0), arguments->array,
|
||||
arguments->position * BytesPerWord, returnType);
|
||||
arguments->position, returnType);
|
||||
|
||||
while (t->reference != reference) {
|
||||
dispose(t, t->reference);
|
||||
@ -3858,7 +3857,6 @@ findTraceNode(MyThread* t, void* address)
|
||||
}
|
||||
|
||||
MyProcessor* p = processor(t);
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
intptr_t key = reinterpret_cast<intptr_t>(address);
|
||||
unsigned index = static_cast<uintptr_t>(key)
|
||||
@ -3911,7 +3909,7 @@ insertTraceNode(MyThread* t, object node)
|
||||
|
||||
MyProcessor* p = processor(t);
|
||||
PROTECT(t, node);
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
ENTER(t, Thread::ExclusiveState);
|
||||
|
||||
++ p->addressCount;
|
||||
|
||||
|
208
src/compiler.cpp
208
src/compiler.cpp
@ -7,6 +7,7 @@ using namespace vm;
|
||||
namespace {
|
||||
|
||||
enum Register {
|
||||
NoRegister = -1,
|
||||
rax = 0,
|
||||
rcx = 1,
|
||||
rdx = 2,
|
||||
@ -126,9 +127,10 @@ class MyStack: public Stack {
|
||||
|
||||
class RegisterData {
|
||||
public:
|
||||
RegisterData(): reserved(false) { }
|
||||
RegisterData(): reserved(false), high(NoRegister) { }
|
||||
|
||||
bool reserved;
|
||||
Register high;
|
||||
};
|
||||
|
||||
class Context {
|
||||
@ -366,6 +368,8 @@ class MyOperand: public Operand {
|
||||
|
||||
virtual void accept(Context* c, Operation, ImmediateOperand*) = 0;
|
||||
|
||||
virtual void accept(Context* c, Operation, AddressOperand*) = 0;
|
||||
|
||||
virtual void accept(Context* c, Operation, AbsoluteOperand*) = 0;
|
||||
|
||||
virtual void accept(Context* c, Operation, MemoryOperand*) = 0;
|
||||
@ -403,12 +407,16 @@ release(Context* c, Register v)
|
||||
fprintf(stderr, "release %d\n", v);
|
||||
}
|
||||
c->registers[v].reserved = false;
|
||||
|
||||
if (c->registers[v].high != NoRegister) {
|
||||
release(c, c->registers[v].high);
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterOperand: public MyOperand {
|
||||
public:
|
||||
RegisterOperand(Register value, Register high, SelectionType selection):
|
||||
value(value), high(high), selection(selection)
|
||||
RegisterOperand(Register value, SelectionType selection):
|
||||
value(value), selection(selection)
|
||||
{ }
|
||||
|
||||
virtual unsigned footprint(Context*) {
|
||||
@ -422,10 +430,12 @@ class RegisterOperand: public MyOperand {
|
||||
virtual MyOperand* select(Context* c, SelectionType selection) {
|
||||
if (selection == this->selection) {
|
||||
return this;
|
||||
} else if (selection == S8Selection and BytesPerWord == 4) {
|
||||
#warning tbc
|
||||
return register_(c, value, acquire(c), selection);
|
||||
} else {
|
||||
if (selection == S8Selection and BytesPerWord == 4
|
||||
and c->registers[value].high == NoRegister)
|
||||
{
|
||||
c->registers[value].high = ::acquire(c);
|
||||
}
|
||||
return register_(c, value, selection);
|
||||
}
|
||||
}
|
||||
@ -435,6 +445,10 @@ class RegisterOperand: public MyOperand {
|
||||
RegisterNode(value, next);
|
||||
}
|
||||
|
||||
void acquire(Context* c) {
|
||||
value = ::acquire(c);
|
||||
}
|
||||
|
||||
virtual void release(Context* c) {
|
||||
::release(c, value);
|
||||
}
|
||||
@ -447,11 +461,11 @@ class RegisterOperand: public MyOperand {
|
||||
|
||||
virtual void accept(Context*, Operation, RegisterOperand*);
|
||||
virtual void accept(Context*, Operation, ImmediateOperand*);
|
||||
virtual void accept(Context*, Operation, AddressOperand*);
|
||||
virtual void accept(Context*, Operation, AbsoluteOperand*);
|
||||
virtual void accept(Context*, Operation, MemoryOperand*);
|
||||
|
||||
Register value;
|
||||
Register high;
|
||||
SelectionType selection;
|
||||
};
|
||||
|
||||
@ -477,6 +491,7 @@ class ImmediateOperand: public MyOperand {
|
||||
|
||||
virtual void accept(Context* c, Operation, RegisterOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AddressOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AbsoluteOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
|
||||
|
||||
@ -495,9 +510,13 @@ class AddressOperand: public MyOperand {
|
||||
virtual void setLabelValue(Context*, MyPromise*);
|
||||
|
||||
virtual void apply(Context*, Operation);
|
||||
virtual void apply(Context* c, Operation, MyOperand*) { abort(c); }
|
||||
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||
operand->accept(c, operation, this);
|
||||
}
|
||||
|
||||
virtual void accept(Context* c, Operation, RegisterOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AddressOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AbsoluteOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
|
||||
|
||||
@ -520,6 +539,7 @@ class AbsoluteOperand: public MyOperand {
|
||||
|
||||
virtual void accept(Context* c, Operation, RegisterOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AddressOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, AbsoluteOperand*) { abort(c); }
|
||||
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
|
||||
|
||||
@ -564,6 +584,7 @@ class MemoryOperand: public MyOperand {
|
||||
|
||||
virtual void accept(Context*, Operation, RegisterOperand*);
|
||||
virtual void accept(Context*, Operation, ImmediateOperand*);
|
||||
virtual void accept(Context* c, Operation, AddressOperand*) { abort(c); }
|
||||
virtual void accept(Context*, Operation, AbsoluteOperand*);
|
||||
virtual void accept(Context*, Operation, MemoryOperand*);
|
||||
|
||||
@ -574,54 +595,6 @@ class MemoryOperand: public MyOperand {
|
||||
SelectionType selection;
|
||||
};
|
||||
|
||||
class WrapperOperand: public MyOperand {
|
||||
public:
|
||||
virtual MyOperand* base(Context*) = 0;
|
||||
|
||||
virtual unsigned footprint(Context* c) {
|
||||
return base(c)->footprint(c);
|
||||
}
|
||||
|
||||
virtual Register asRegister(Context* c) {
|
||||
return base(c)->asRegister(c);
|
||||
}
|
||||
|
||||
virtual RegisterNode* dependencies(Context* c, RegisterNode* next) {
|
||||
return base(c)->dependencies(c, next);
|
||||
}
|
||||
|
||||
virtual void apply(Context* c, Operation operation) {
|
||||
base(c)->apply(c, operation);
|
||||
}
|
||||
|
||||
virtual void apply(Context* c, Operation operation, MyOperand* operand) {
|
||||
base(c)->apply(c, operation, operand);
|
||||
}
|
||||
|
||||
virtual void accept(Context* c, Operation operation,
|
||||
RegisterOperand* operand)
|
||||
{
|
||||
base(c)->accept(c, operation, operand);
|
||||
}
|
||||
|
||||
virtual void accept(Context* c, Operation operation,
|
||||
ImmediateOperand* operand)
|
||||
{
|
||||
base(c)->accept(c, operation, operand);
|
||||
}
|
||||
|
||||
virtual void accept(Context* c, Operation operation,
|
||||
AbsoluteOperand* operand)
|
||||
{
|
||||
base(c)->accept(c, operation, operand);
|
||||
}
|
||||
|
||||
virtual void accept(Context* c, Operation operation, MemoryOperand* operand)
|
||||
{
|
||||
base(c)->accept(c, operation, operand);
|
||||
}
|
||||
};
|
||||
|
||||
AddressOperand*
|
||||
address(Context* c, MyPromise* p)
|
||||
{
|
||||
@ -649,13 +622,6 @@ register_(Context* c, Register v, SelectionType selection)
|
||||
RegisterOperand(v, selection);
|
||||
}
|
||||
|
||||
RegisterOperand*
|
||||
register_(Context* c, Register v, Register high, SelectionType selection)
|
||||
{
|
||||
return new (c->zone.allocate(sizeof(RegisterOperand)))
|
||||
RegisterOperand(v, high, selection);
|
||||
}
|
||||
|
||||
MemoryOperand*
|
||||
memory(Context* c, MyOperand* base, int displacement,
|
||||
MyOperand* index, unsigned scale, SelectionType selection)
|
||||
@ -696,56 +662,6 @@ apply(Context* c, MyOperand::Operation op)
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterReference {
|
||||
public:
|
||||
RegisterReference(): valid(false) { }
|
||||
|
||||
Register value(Context* c) {
|
||||
assert(c, valid);
|
||||
return value_;
|
||||
}
|
||||
|
||||
void acquire(Context* c) {
|
||||
value_ = ::acquire(c);
|
||||
valid = true;
|
||||
}
|
||||
|
||||
void release(Context* c) {
|
||||
::release(c, value_);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
Register value_;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
class TemporaryOperand: public WrapperOperand {
|
||||
public:
|
||||
TemporaryOperand(RegisterReference* reference, SelectionType selection):
|
||||
reference(reference), selection(selection)
|
||||
{ }
|
||||
|
||||
virtual MyOperand* base(Context* c) {
|
||||
return register_(c, reference->value(c), selection);
|
||||
}
|
||||
|
||||
virtual unsigned footprint(Context*) {
|
||||
return (selection == S8Selection ? 8 : BytesPerWord);
|
||||
}
|
||||
|
||||
virtual MyOperand* select(Context* c, SelectionType selection) {
|
||||
return new (c->zone.allocate(sizeof(TemporaryOperand)))
|
||||
TemporaryOperand(reference, selection);
|
||||
}
|
||||
|
||||
virtual void release(Context* c) {
|
||||
reference->release(c);
|
||||
}
|
||||
|
||||
RegisterReference* reference;
|
||||
SelectionType selection;
|
||||
};
|
||||
|
||||
class OpEvent: public Event {
|
||||
public:
|
||||
OpEvent(MyOperand::Operation operation, Event* next):
|
||||
@ -802,16 +718,16 @@ class BinaryOpEvent: public Event {
|
||||
|
||||
class AcquireEvent: public Event {
|
||||
public:
|
||||
AcquireEvent(TemporaryOperand* operand, Event* next):
|
||||
AcquireEvent(RegisterOperand* operand, Event* next):
|
||||
Event(next),
|
||||
operand(operand)
|
||||
{ }
|
||||
|
||||
virtual void run(Context* c) {
|
||||
operand->reference->acquire(c);
|
||||
operand->acquire(c);
|
||||
}
|
||||
|
||||
TemporaryOperand* operand;
|
||||
RegisterOperand* operand;
|
||||
};
|
||||
|
||||
class ReleaseEvent: public Event {
|
||||
@ -946,7 +862,7 @@ appendOperation(Context* c, MyOperand::Operation operation, Operand* a, Operand*
|
||||
}
|
||||
|
||||
void
|
||||
appendAcquire(Context* c, TemporaryOperand* operand)
|
||||
appendAcquire(Context* c, RegisterOperand* operand)
|
||||
{
|
||||
Segment* s = currentSegment(c);
|
||||
s->event = new (c->zone.allocate(sizeof(AcquireEvent)))
|
||||
@ -983,20 +899,6 @@ pushed(Context* c, MyStack* stack, unsigned footprint)
|
||||
return new (c->zone.allocate(sizeof(MyStack))) MyStack(value, index, stack);
|
||||
}
|
||||
|
||||
MyStack*
|
||||
push(Context* c, MyStack* stack, int count)
|
||||
{
|
||||
appendOperation
|
||||
(c, MyOperand::sub, immediate(c, count * BytesPerWord), register_(c, rsp));
|
||||
|
||||
while (count) {
|
||||
-- count;
|
||||
stack = pushed(c, stack, BytesPerWord);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
MyStack*
|
||||
push(Context* c, MyStack* stack, MyOperand* v)
|
||||
{
|
||||
@ -1110,6 +1012,7 @@ void
|
||||
RegisterOperand::apply(Context* c, Operation operation)
|
||||
{
|
||||
assert(c, selection == DefaultSelection);
|
||||
assert(c, value != NoRegister);
|
||||
|
||||
switch (operation) {
|
||||
case call:
|
||||
@ -1277,6 +1180,29 @@ RegisterOperand::accept(Context* c, Operation operation,
|
||||
}
|
||||
}
|
||||
|
||||
ImmediateOperand*
|
||||
value(Context* c, AddressOperand* operand)
|
||||
{
|
||||
if (operand->promise->resolved(c)) {
|
||||
return immediate(c, operand->promise->value(c));
|
||||
} else {
|
||||
return immediate(c, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegisterOperand::accept(Context* c, Operation operation,
|
||||
AddressOperand* operand)
|
||||
{
|
||||
switch (operation) {
|
||||
case mov: {
|
||||
accept(c, operation, ::value(c, operand));
|
||||
} break;
|
||||
|
||||
default: abort(c);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegisterOperand::accept(Context* c, Operation operation,
|
||||
MemoryOperand* operand)
|
||||
@ -1324,7 +1250,7 @@ RegisterOperand::accept(Context* c, Operation operation,
|
||||
(c, operand->base, operand->displacement,
|
||||
operand->index, operand->scale));
|
||||
|
||||
register_(c, high)->accept
|
||||
register_(c, c->registers[value].high)->accept
|
||||
(c, mov, memory
|
||||
(c, operand->base, operand->displacement + BytesPerWord,
|
||||
operand->index, operand->scale));
|
||||
@ -1853,7 +1779,18 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual Stack* push(Stack* s, unsigned count) {
|
||||
return ::push(&c, static_cast<MyStack*>(s), count);
|
||||
sub(immediate(&c, count * BytesPerWord), register_(&c, rsp));
|
||||
|
||||
return pushed(s, count);
|
||||
}
|
||||
|
||||
virtual Stack* pushed(Stack* s, unsigned count) {
|
||||
MyStack* stack = static_cast<MyStack*>(s);
|
||||
while (count) {
|
||||
-- count;
|
||||
stack = ::pushed(&c, stack, BytesPerWord);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
virtual Stack* push(Stack* s, Operand* v) {
|
||||
@ -1903,10 +1840,7 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual Operand* temporary() {
|
||||
RegisterReference* reference = new
|
||||
(c.zone.allocate(sizeof(RegisterReference))) RegisterReference();
|
||||
TemporaryOperand* r = new (c.zone.allocate(sizeof(TemporaryOperand)))
|
||||
TemporaryOperand(reference, DefaultSelection);
|
||||
RegisterOperand* r = register_(&c, NoRegister);
|
||||
appendAcquire(&c, r);
|
||||
return r;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ class Compiler {
|
||||
virtual void ret() = 0;
|
||||
|
||||
virtual Stack* push(Stack*, unsigned count) = 0;
|
||||
virtual Stack* pushed(Stack*, unsigned count) = 0;
|
||||
virtual Stack* push(Stack*, Operand*) = 0;
|
||||
virtual Stack* pop(Stack*, unsigned count) = 0;
|
||||
virtual Stack* pop(Stack*, Operand*) = 0;
|
||||
|
5198
src/old-compile.cpp
5198
src/old-compile.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user