lots of JIT bugfixes; all top-level tests now pass

This commit is contained in:
Joel Dice 2007-12-17 13:55:31 -07:00
parent 25ea07aed5
commit 4c3a2575ba
7 changed files with 91 additions and 5372 deletions

View File

@ -28,7 +28,7 @@ src = src
classpath = classpath classpath = classpath
test = test test = test
input = $(test-build)/List.class input = $(test-build)/Threads.class
build-cxx = g++ build-cxx = g++
build-cc = gcc build-cc = gcc

View File

@ -20,22 +20,14 @@ vmInvoke:
mov %rdi,%rbx mov %rdi,%rbx
// reserve space for arguments
pushq %rcx
subq %rcx,%rsp
// copy memory arguments into place // copy memory arguments into place
pushq %rcx
movq $0,%r9 movq $0,%r9
jmp test jmp test
loop: loop:
movq %r9,%rax push (%rdx,%r9,8)
movq %r9,%r10 inc %r9
addq %rsp,%r10
addq %rdx,%rax
movq (%rax),%rax
movq %rax,(%r10)
addq $8,%r9
test: test:
cmpq %rcx,%r9 cmpq %rcx,%r9
@ -80,21 +72,13 @@ vmInvoke:
mov 8(%ebp),%ebx mov 8(%ebp),%ebx
// reserve space for arguments
subl 20(%ebp),%esp
// copy arguments into place // copy arguments into place
movl $0,%ecx movl $0,%ecx
jmp test jmp test
loop: loop:
movl %ecx,%eax push (%rdx,%rcx,4)
movl %ecx,%edx inc %ecx
addl %esp,%edx
addl 16(%ebp),%eax
movl (%eax),%eax
movl %eax,(%edx)
addl $4,%ecx
test: test:
cmpl 20(%ebp),%ecx cmpl 20(%ebp),%ecx

View File

@ -18,7 +18,7 @@ vmJump(void* address, void* base, void* stack, void* thread);
namespace { namespace {
const bool Verbose = true; const bool Verbose = false;
const bool DebugTraces = false; const bool DebugTraces = false;
class MyThread: public Thread { class MyThread: public Thread {
@ -612,7 +612,7 @@ class Frame {
} }
void pushObject() { void pushObject() {
stack = c->push(stack, 1); stack = c->pushed(stack, 1);
pushedObject(); pushedObject();
} }
@ -710,8 +710,8 @@ class Frame {
void loadObject(unsigned index) { void loadObject(unsigned index) {
assert(t, index < codeMaxLocals(t, methodCode(t, method))); assert(t, index < codeMaxLocals(t, methodCode(t, method)));
assert(t, index < parameterFootprint(t, method) // assert(t, index < parameterFootprint(t, method)
or getBit(map, index - parameterFootprint(t, method)) != 0); // or getBit(map, index - parameterFootprint(t, method)) != 0);
pushObject(c->memory(c->base(), localOffset(t, index, method))); pushObject(c->memory(c->base(), localOffset(t, index, method)));
} }
@ -1077,7 +1077,7 @@ makeBlankArray(Thread* t, object (*constructor)(Thread*, uintptr_t, bool),
uintptr_t uintptr_t
lookUpAddress(int32_t key, uintptr_t* start, int32_t count, lookUpAddress(int32_t key, uintptr_t* start, int32_t count,
uintptr_t* default_) uintptr_t default_)
{ {
int32_t bottom = 0; int32_t bottom = 0;
int32_t top = count; int32_t top = count;
@ -1095,7 +1095,7 @@ lookUpAddress(int32_t key, uintptr_t* start, int32_t count,
} }
} }
return *default_; return default_;
} }
void void
@ -2993,10 +2993,10 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
if (false and if (false and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
"java/util/Collections$ArrayListIterator") == 0 and "java/lang/String") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"<init>") == 0) "getChars") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3161,12 +3161,11 @@ invokeNative2(MyThread* t, object method)
case INT64_TYPE: case INT64_TYPE:
case DOUBLE_TYPE: { case DOUBLE_TYPE: {
memcpy(args + argOffset, sp, 8);
if (BytesPerWord == 8) { if (BytesPerWord == 8) {
uint64_t a = *(sp--); ++argOffset;
uint64_t b = *(sp--); --sp;
args[argOffset++] = (a << 32) | b;
} else { } else {
memcpy(args + argOffset, sp, 8);
argOffset += 2; argOffset += 2;
sp -= 2; sp -= 2;
} }
@ -3480,7 +3479,7 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
uint64_t result = vmInvoke uint64_t result = vmInvoke
(t, &singletonValue(t, methodCompiled(t, method), 0), arguments->array, (t, &singletonValue(t, methodCompiled(t, method), 0), arguments->array,
arguments->position * BytesPerWord, returnType); arguments->position, returnType);
while (t->reference != reference) { while (t->reference != reference) {
dispose(t, t->reference); dispose(t, t->reference);
@ -3858,7 +3857,6 @@ findTraceNode(MyThread* t, void* address)
} }
MyProcessor* p = processor(t); MyProcessor* p = processor(t);
ACQUIRE(t, t->m->classLock);
intptr_t key = reinterpret_cast<intptr_t>(address); intptr_t key = reinterpret_cast<intptr_t>(address);
unsigned index = static_cast<uintptr_t>(key) unsigned index = static_cast<uintptr_t>(key)
@ -3911,7 +3909,7 @@ insertTraceNode(MyThread* t, object node)
MyProcessor* p = processor(t); MyProcessor* p = processor(t);
PROTECT(t, node); PROTECT(t, node);
ACQUIRE(t, t->m->classLock); ENTER(t, Thread::ExclusiveState);
++ p->addressCount; ++ p->addressCount;

View File

@ -7,6 +7,7 @@ using namespace vm;
namespace { namespace {
enum Register { enum Register {
NoRegister = -1,
rax = 0, rax = 0,
rcx = 1, rcx = 1,
rdx = 2, rdx = 2,
@ -126,9 +127,10 @@ class MyStack: public Stack {
class RegisterData { class RegisterData {
public: public:
RegisterData(): reserved(false) { } RegisterData(): reserved(false), high(NoRegister) { }
bool reserved; bool reserved;
Register high;
}; };
class Context { class Context {
@ -366,6 +368,8 @@ class MyOperand: public Operand {
virtual void accept(Context* c, Operation, ImmediateOperand*) = 0; 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, AbsoluteOperand*) = 0;
virtual void accept(Context* c, Operation, MemoryOperand*) = 0; virtual void accept(Context* c, Operation, MemoryOperand*) = 0;
@ -403,12 +407,16 @@ release(Context* c, Register v)
fprintf(stderr, "release %d\n", v); fprintf(stderr, "release %d\n", v);
} }
c->registers[v].reserved = false; c->registers[v].reserved = false;
if (c->registers[v].high != NoRegister) {
release(c, c->registers[v].high);
}
} }
class RegisterOperand: public MyOperand { class RegisterOperand: public MyOperand {
public: public:
RegisterOperand(Register value, Register high, SelectionType selection): RegisterOperand(Register value, SelectionType selection):
value(value), high(high), selection(selection) value(value), selection(selection)
{ } { }
virtual unsigned footprint(Context*) { virtual unsigned footprint(Context*) {
@ -422,10 +430,12 @@ class RegisterOperand: public MyOperand {
virtual MyOperand* select(Context* c, SelectionType selection) { virtual MyOperand* select(Context* c, SelectionType selection) {
if (selection == this->selection) { if (selection == this->selection) {
return this; return this;
} else if (selection == S8Selection and BytesPerWord == 4) {
#warning tbc
return register_(c, value, acquire(c), selection);
} else { } else {
if (selection == S8Selection and BytesPerWord == 4
and c->registers[value].high == NoRegister)
{
c->registers[value].high = ::acquire(c);
}
return register_(c, value, selection); return register_(c, value, selection);
} }
} }
@ -435,6 +445,10 @@ class RegisterOperand: public MyOperand {
RegisterNode(value, next); RegisterNode(value, next);
} }
void acquire(Context* c) {
value = ::acquire(c);
}
virtual void release(Context* c) { virtual void release(Context* c) {
::release(c, value); ::release(c, value);
} }
@ -447,11 +461,11 @@ class RegisterOperand: public MyOperand {
virtual void accept(Context*, Operation, RegisterOperand*); virtual void accept(Context*, Operation, RegisterOperand*);
virtual void accept(Context*, Operation, ImmediateOperand*); virtual void accept(Context*, Operation, ImmediateOperand*);
virtual void accept(Context*, Operation, AddressOperand*);
virtual void accept(Context*, Operation, AbsoluteOperand*); virtual void accept(Context*, Operation, AbsoluteOperand*);
virtual void accept(Context*, Operation, MemoryOperand*); virtual void accept(Context*, Operation, MemoryOperand*);
Register value; Register value;
Register high;
SelectionType selection; 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, RegisterOperand*) { abort(c); }
virtual void accept(Context* c, Operation, ImmediateOperand*) { 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, AbsoluteOperand*) { abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*) { 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 setLabelValue(Context*, MyPromise*);
virtual void apply(Context*, Operation); 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, RegisterOperand*) { abort(c); }
virtual void accept(Context* c, Operation, ImmediateOperand*) { 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, AbsoluteOperand*) { abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*) { 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, RegisterOperand*) { abort(c); }
virtual void accept(Context* c, Operation, ImmediateOperand*) { 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, AbsoluteOperand*) { abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*) { 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, RegisterOperand*);
virtual void accept(Context*, Operation, ImmediateOperand*); 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, AbsoluteOperand*);
virtual void accept(Context*, Operation, MemoryOperand*); virtual void accept(Context*, Operation, MemoryOperand*);
@ -574,54 +595,6 @@ class MemoryOperand: public MyOperand {
SelectionType selection; 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* AddressOperand*
address(Context* c, MyPromise* p) address(Context* c, MyPromise* p)
{ {
@ -649,13 +622,6 @@ register_(Context* c, Register v, SelectionType selection)
RegisterOperand(v, 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* MemoryOperand*
memory(Context* c, MyOperand* base, int displacement, memory(Context* c, MyOperand* base, int displacement,
MyOperand* index, unsigned scale, SelectionType selection) 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 { class OpEvent: public Event {
public: public:
OpEvent(MyOperand::Operation operation, Event* next): OpEvent(MyOperand::Operation operation, Event* next):
@ -802,16 +718,16 @@ class BinaryOpEvent: public Event {
class AcquireEvent: public Event { class AcquireEvent: public Event {
public: public:
AcquireEvent(TemporaryOperand* operand, Event* next): AcquireEvent(RegisterOperand* operand, Event* next):
Event(next), Event(next),
operand(operand) operand(operand)
{ } { }
virtual void run(Context* c) { virtual void run(Context* c) {
operand->reference->acquire(c); operand->acquire(c);
} }
TemporaryOperand* operand; RegisterOperand* operand;
}; };
class ReleaseEvent: public Event { class ReleaseEvent: public Event {
@ -946,7 +862,7 @@ appendOperation(Context* c, MyOperand::Operation operation, Operand* a, Operand*
} }
void void
appendAcquire(Context* c, TemporaryOperand* operand) appendAcquire(Context* c, RegisterOperand* operand)
{ {
Segment* s = currentSegment(c); Segment* s = currentSegment(c);
s->event = new (c->zone.allocate(sizeof(AcquireEvent))) 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); 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* MyStack*
push(Context* c, MyStack* stack, MyOperand* v) push(Context* c, MyStack* stack, MyOperand* v)
{ {
@ -1110,6 +1012,7 @@ void
RegisterOperand::apply(Context* c, Operation operation) RegisterOperand::apply(Context* c, Operation operation)
{ {
assert(c, selection == DefaultSelection); assert(c, selection == DefaultSelection);
assert(c, value != NoRegister);
switch (operation) { switch (operation) {
case call: 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 void
RegisterOperand::accept(Context* c, Operation operation, RegisterOperand::accept(Context* c, Operation operation,
MemoryOperand* operand) MemoryOperand* operand)
@ -1324,7 +1250,7 @@ RegisterOperand::accept(Context* c, Operation operation,
(c, operand->base, operand->displacement, (c, operand->base, operand->displacement,
operand->index, operand->scale)); operand->index, operand->scale));
register_(c, high)->accept register_(c, c->registers[value].high)->accept
(c, mov, memory (c, mov, memory
(c, operand->base, operand->displacement + BytesPerWord, (c, operand->base, operand->displacement + BytesPerWord,
operand->index, operand->scale)); operand->index, operand->scale));
@ -1853,7 +1779,18 @@ class MyCompiler: public Compiler {
} }
virtual Stack* push(Stack* s, unsigned count) { 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) { virtual Stack* push(Stack* s, Operand* v) {
@ -1903,10 +1840,7 @@ class MyCompiler: public Compiler {
} }
virtual Operand* temporary() { virtual Operand* temporary() {
RegisterReference* reference = new RegisterOperand* r = register_(&c, NoRegister);
(c.zone.allocate(sizeof(RegisterReference))) RegisterReference();
TemporaryOperand* r = new (c.zone.allocate(sizeof(TemporaryOperand)))
TemporaryOperand(reference, DefaultSelection);
appendAcquire(&c, r); appendAcquire(&c, r);
return r; return r;
} }

View File

@ -63,6 +63,7 @@ class Compiler {
virtual void ret() = 0; virtual void ret() = 0;
virtual Stack* push(Stack*, unsigned count) = 0; virtual Stack* push(Stack*, unsigned count) = 0;
virtual Stack* pushed(Stack*, unsigned count) = 0;
virtual Stack* push(Stack*, Operand*) = 0; virtual Stack* push(Stack*, Operand*) = 0;
virtual Stack* pop(Stack*, unsigned count) = 0; virtual Stack* pop(Stack*, unsigned count) = 0;
virtual Stack* pop(Stack*, Operand*) = 0; virtual Stack* pop(Stack*, Operand*) = 0;

File diff suppressed because it is too large Load Diff