lots of JIT bugfixes

This commit is contained in:
Joel Dice 2007-12-14 18:11:01 -07:00
parent 12e10b57f5
commit 403a6b0200
2 changed files with 129 additions and 56 deletions

View File

@ -19,6 +19,7 @@ vmJump(void* address, void* base, void* stack);
namespace { namespace {
const bool Verbose = true; const bool Verbose = true;
const bool DebugTraces = false;
class MyThread: public Thread { class MyThread: public Thread {
public: public:
@ -1801,7 +1802,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
break; break;
case ObjectField: case ObjectField:
frame->pushObject(c->memory(c->memory(table, fieldOffset(t, field)))); frame->pushObject(c->memory(table, fieldOffset(t, field)));
break; break;
default: default:
@ -1830,13 +1831,17 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case i2b: { case i2b: {
Operand* top = frame->topInt(); Operand* tmp = c->temporary();
c->mov(c->select1(top), top); c->mov(frame->topInt(), tmp);
c->mov(c->select1(tmp), frame->topInt());
c->release(tmp);
} break; } break;
case i2c: { case i2c: {
Operand* top = frame->topInt(); Operand* tmp = c->temporary();
c->mov(c->select2z(top), top); c->mov(frame->topInt(), tmp);
c->mov(c->select2z(tmp), frame->topInt());
c->release(tmp);
} break; } break;
case i2d: { case i2d: {
@ -1862,8 +1867,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case i2s: { case i2s: {
Operand* top = frame->topInt(); Operand* tmp = c->temporary();
c->mov(c->select2(top), top); c->mov(frame->topInt(), tmp);
c->mov(c->select2(tmp), frame->topInt());
c->release(tmp);
} break; } break;
case iadd: { case iadd: {
@ -2473,7 +2480,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lreturn: case lreturn:
case dreturn: { case dreturn: {
Operand* a = frame->popLong(); Operand* a = frame->popLong();
c->return_(frame->popLong()); c->return_(a);
c->release(a); c->release(a);
} return; } return;
@ -2972,10 +2979,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/lang/String") == 0 and "java/lang/Boolean") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"charAt") == 0) "booleanValue") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3098,7 +3105,7 @@ invokeNative2(MyThread* t, object method)
types[typeOffset++] = POINTER_TYPE; types[typeOffset++] = POINTER_TYPE;
uintptr_t* sp = static_cast<uintptr_t*>(t->stack) uintptr_t* sp = static_cast<uintptr_t*>(t->stack)
+ (methodParameterFootprint(t, method) + 1); + methodParameterFootprint(t, method);
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
args[argOffset++] = reinterpret_cast<uintptr_t>(&class_); args[argOffset++] = reinterpret_cast<uintptr_t>(&class_);
@ -3820,7 +3827,7 @@ compile(MyThread* t, object method)
object object
findTraceNode(MyThread* t, void* address) findTraceNode(MyThread* t, void* address)
{ {
if (Verbose) { if (DebugTraces) {
fprintf(stderr, "find trace node %p\n", address); fprintf(stderr, "find trace node %p\n", address);
} }
@ -3871,7 +3878,7 @@ resizeTable(MyThread* t, object oldTable, unsigned newLength)
void void
insertTraceNode(MyThread* t, object node) insertTraceNode(MyThread* t, object node)
{ {
if (Verbose) { if (DebugTraces) {
fprintf(stderr, "insert trace node %p\n", fprintf(stderr, "insert trace node %p\n",
reinterpret_cast<void*>(traceNodeAddress(t, node))); reinterpret_cast<void*>(traceNodeAddress(t, node)));
} }

View File

@ -33,7 +33,7 @@ enum SelectionType {
S8Selection S8Selection
}; };
const bool Verbose = true; const bool Verbose = false;
const unsigned RegisterCount = BytesPerWord * 2; const unsigned RegisterCount = BytesPerWord * 2;
@ -77,7 +77,7 @@ class Task {
class Event { class Event {
public: public:
Event(Event* next): next(next), task(0), offset(-1) { Event(Event* next): next(next), task(0) {
if (next) { if (next) {
count = next->count + 1; count = next->count + 1;
} else { } else {
@ -91,17 +91,17 @@ class Event {
Event* next; Event* next;
Task* task; Task* task;
int offset;
unsigned count; unsigned count;
}; };
class Segment { class Segment {
public: public:
Segment(int logicalIp, Event* event): Segment(int logicalIp, Event* event):
logicalIp(logicalIp), event(event) logicalIp(logicalIp), offset(-1), event(event)
{ } { }
int logicalIp; int logicalIp;
int offset;
Event* event; Event* event;
}; };
@ -164,6 +164,9 @@ class MyOperand: public Operand {
virtual void accept(Context* c, Operation, MemoryOperand*) = 0; virtual void accept(Context* c, Operation, MemoryOperand*) = 0;
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType)
= 0;
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType) virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
= 0; = 0;
}; };
@ -198,13 +201,17 @@ class RegisterOperand: public MyOperand {
virtual void apply(Context* c, Operation, SelectionType) { abort(c); } virtual void apply(Context* c, Operation, SelectionType) { abort(c); }
virtual void apply(Context* c, Operation, MyOperand*, SelectionType) virtual void apply(Context* c, Operation operation, MyOperand* operand,
{ abort(c); } SelectionType selection)
{
operand->accept(c, operation, this, selection);
}
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, AbsoluteOperand*); virtual void accept(Context*, Operation, AbsoluteOperand*);
virtual void accept(Context*, Operation, MemoryOperand*); virtual void accept(Context*, Operation, MemoryOperand*);
virtual void accept(Context*, Operation, RegisterOperand*, SelectionType);
virtual void accept(Context*, Operation, MemoryOperand*, SelectionType); virtual void accept(Context*, Operation, MemoryOperand*, SelectionType);
Register value; Register value;
@ -229,13 +236,11 @@ class ImmediateOperand: public MyOperand {
{ abort(c); } { abort(c); }
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, 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); }
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType)
{ abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType) virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
{ abort(c); } { abort(c); }
@ -251,22 +256,16 @@ class AddressOperand: public MyOperand {
virtual void setLabelValue(Context*, CodePromise*); virtual void setLabelValue(Context*, CodePromise*);
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, MyOperand*) { abort(c); }
virtual void apply(Context* c, Operation, SelectionType) { abort(c); } virtual void apply(Context* c, Operation, SelectionType) { abort(c); }
virtual void apply(Context* c, Operation, MyOperand*, SelectionType) virtual void apply(Context* c, Operation, MyOperand*, SelectionType)
{ abort(c); } { abort(c); }
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, 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); }
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType)
{ abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType) virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
{ abort(c); } { abort(c); }
@ -279,6 +278,8 @@ class AbsoluteOperand: public MyOperand {
promise(promise) promise(promise)
{ } { }
virtual Register asRegister(Context* c);
virtual void apply(Context*, Operation); virtual void apply(Context*, Operation);
virtual void apply(Context* c, Operation operation, MyOperand* operand) { virtual void apply(Context* c, Operation operation, MyOperand* operand) {
@ -286,18 +287,14 @@ class AbsoluteOperand: public MyOperand {
} }
virtual void apply(Context* c, Operation, SelectionType) { abort(c); } virtual void apply(Context* c, Operation, SelectionType) { abort(c); }
virtual void apply(Context* c, Operation, MyOperand*, SelectionType) virtual void apply(Context* c, Operation, MyOperand*, SelectionType)
{ abort(c); } { abort(c); }
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, 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); }
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType)
{ abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType) virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
{ abort(c); } { abort(c); }
@ -333,10 +330,10 @@ 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*, Operation, AbsoluteOperand*); virtual void accept(Context*, Operation, AbsoluteOperand*);
virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); } virtual void accept(Context* c, Operation, MemoryOperand*) { abort(c); }
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType);
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType); virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
{ abort(c); }
MyOperand* base; MyOperand* base;
int displacement; int displacement;
@ -367,18 +364,25 @@ class SelectionOperand: public MyOperand {
} }
virtual void apply(Context* c, Operation, SelectionType) { abort(c); } virtual void apply(Context* c, Operation, SelectionType) { abort(c); }
virtual void apply(Context* c, Operation, MyOperand*, SelectionType) virtual void apply(Context* c, Operation, MyOperand*, SelectionType)
{ abort(c); } { abort(c); }
virtual void accept(Context* c, Operation, RegisterOperand*) { abort(c); } virtual void accept(Context* c, Operation operation,
RegisterOperand* operand)
{
base->accept(c, operation, operand, selectionType);
}
virtual void accept(Context* c, Operation, ImmediateOperand*) { abort(c); } virtual void accept(Context* c, Operation, ImmediateOperand*) { 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 operation, MemoryOperand* operand)
{
base->accept(c, operation, operand, selectionType);
}
virtual void accept(Context* c, Operation, RegisterOperand*, SelectionType)
{ abort(c); }
virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType) virtual void accept(Context* c, Operation, MemoryOperand*, SelectionType)
{ abort(c); } { abort(c); }
@ -442,6 +446,12 @@ class WrapperOperand: public MyOperand {
base->accept(c, operation, operand); base->accept(c, operation, operand);
} }
virtual void accept(Context* c, Operation operation,
RegisterOperand* operand, SelectionType selection)
{
base->accept(c, operation, operand, selection);
}
virtual void accept(Context* c, Operation operation, MemoryOperand* operand, virtual void accept(Context* c, Operation operation, MemoryOperand* operand,
SelectionType selection) SelectionType selection)
{ {
@ -630,10 +640,9 @@ class IpPromise: public MyPromise {
if (logicalIp == s->logicalIp) { if (logicalIp == s->logicalIp) {
if (absolute) { if (absolute) {
return reinterpret_cast<intptr_t> return reinterpret_cast<intptr_t>(c->code.data + s->offset);
(c->code.data + s->event->offset);
} else { } else {
return s->event->offset; return s->offset;
} }
} else if (logicalIp < s->logicalIp) { } else if (logicalIp < s->logicalIp) {
top = middle; top = middle;
@ -1084,6 +1093,38 @@ RegisterOperand::accept(Context* c, Operation operation,
} }
} }
void
RegisterOperand::accept(Context* c, Operation operation,
RegisterOperand* operand, SelectionType selection)
{
switch (operation) {
case mov: {
rex(c);
c->code.append(0x0f);
switch (selection) {
case S1Selection:
c->code.append(0xbe);
break;
case S2Selection:
c->code.append(0xbf);
break;
case Z2Selection:
c->code.append(0xb7);
break;
default: abort(c);
}
c->code.append(0xc0 | (value << 3) | operand->value);
} break;
default: abort(c);
}
}
void void
RegisterOperand::accept(Context* c, Operation operation, RegisterOperand::accept(Context* c, Operation operation,
ImmediateOperand* operand) ImmediateOperand* operand)
@ -1347,6 +1388,15 @@ ImmediateOperand::apply(Context* c, Operation operation)
} }
} }
Register
AbsoluteOperand::asRegister(Context* c)
{
RegisterOperand* tmp = temporary(c);
tmp->accept(c, mov, this);
tmp->release(c);
return tmp->value;
}
void void
absoluteApply(Context* c, MyOperand::Operation operation, absoluteApply(Context* c, MyOperand::Operation operation,
AbsoluteOperand* operand) AbsoluteOperand* operand)
@ -1501,16 +1551,28 @@ MemoryOperand::accept(Context* c, Operation operation,
void void
MemoryOperand::accept(Context* c, Operation operation, MemoryOperand::accept(Context* c, Operation operation,
MemoryOperand* operand, SelectionType selection) RegisterOperand* operand, SelectionType selection)
{ {
switch (operation) { switch (operation) {
case mov: { case mov: {
RegisterOperand* tmp = temporary(c); switch (selection) {
case S1Selection:
tmp->accept(c, mov, operand, selection); case S2Selection:
accept(c, mov, tmp); case Z2Selection: {
RegisterOperand* tmp = temporary(c);
tmp->accept(c, mov, operand, selection);
accept(c, mov, tmp);
tmp->release(c);
} break;
tmp->release(c); case S4Selection:
encode(c, 0x89, operand->value, this, false);
break;
default: abort(c);
}
} break; } break;
default: abort(c); default: abort(c);
@ -1544,6 +1606,12 @@ writeCode(Context* c)
if (Verbose and c->codeLength >= 0) { if (Verbose and c->codeLength >= 0) {
fprintf(stderr, "\nip %d\n", s->logicalIp); fprintf(stderr, "\nip %d\n", s->logicalIp);
} }
if (c->codeLength >= 0) {
assert(c, s->offset == static_cast<int>(c->code.length()));
} else {
s->offset = c->code.length();
}
Event* events[s->event->count]; Event* events[s->event->count];
unsigned ei = s->event->count; unsigned ei = s->event->count;
@ -1552,12 +1620,10 @@ writeCode(Context* c)
} }
for (unsigned ei = 0; ei < s->event->count; ++ei) { for (unsigned ei = 0; ei < s->event->count; ++ei) {
if (Verbose and c->codeLength >= 0) { if (Verbose and c->codeLength >= 0 and ei) {
fprintf(stderr, "address %p\n", c->code.data + c->code.length()); fprintf(stderr, "address %p\n", c->code.data + c->code.length());
} }
events[ei]->offset = c->code.length();
events[ei]->run(c); events[ei]->run(c);
if (c->codeLength < 0) { if (c->codeLength < 0) {