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
test = test
input = $(test-build)/List.class
input = $(test-build)/Threads.class
build-cxx = g++
build-cc = gcc

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

File diff suppressed because it is too large Load Diff