implement jsr, jsr_w, and ret; various bugfixes to get SWT example working in JIT mode

This commit is contained in:
Joel Dice 2007-12-26 16:59:55 -07:00
parent c0cf15bb37
commit 848a67b397
3 changed files with 85 additions and 23 deletions

View File

@ -9,8 +9,12 @@ vmInvoke:
pushq %rbp pushq %rbp
movq %rsp,%rbp movq %rsp,%rbp
// rbx is a callee-saved register (so are r12-r15, but we don't use those) // push callee-saved registers
pushq %rbx pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
// %rdi: thread // %rdi: thread
// %rsi: function // %rsi: function
@ -20,7 +24,7 @@ vmInvoke:
mov %rdi,%rbx mov %rdi,%rbx
// copy memory arguments into place // copy arguments into place
pushq %rcx pushq %rcx
movq $0,%r9 movq $0,%r9
jmp test jmp test
@ -37,14 +41,20 @@ test:
call *%rsi call *%rsi
// pop arguments // pop arguments
mov -16(%rbp),%rcx mov -48(%rbp),%rcx
sal $3,%rcx sal $3,%rcx
addq %rcx,%rsp addq %rcx,%rsp
// pop argument stack size // pop argument stack size
addq $8,%rsp addq $8,%rsp
// pop callee-saved registers
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbx popq %rbx
movq %rbp,%rsp movq %rbp,%rsp
popq %rbp popq %rbp
ret ret

View File

@ -19,6 +19,7 @@ vmJump(void* address, void* base, void* stack, void* thread);
namespace { namespace {
const bool Verbose = false; const bool Verbose = false;
const bool DebugNatives = false;
const bool DebugTraces = false; const bool DebugTraces = false;
class MyThread: public Thread { class MyThread: public Thread {
@ -708,6 +709,11 @@ class Frame {
pushedInt(); pushedInt();
} }
void pushAddress(Operand* o) {
stack = push(c, stack, o);
pushedInt();
}
void pushObject(Operand* o) { void pushObject(Operand* o) {
stack = push(c, stack, o); stack = push(c, stack, o);
pushedObject(); pushedObject();
@ -833,6 +839,21 @@ class Frame {
storedObject(index); storedObject(index);
} }
void storeObjectOrAddress(unsigned index) {
stack = ::pop
(c, stack, c->memory(c->base(), localOffset(t, index, method)));
assert(t, sp >= 1);
assert(t, sp - 1 >= localSize(t, method));
if (getBit(map, sp - 1)) {
storedObject(index);
} else {
storedInt(index);
}
clearBit(map, -- sp);
}
void increment(unsigned index, int count) { void increment(unsigned index, int count) {
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)
@ -864,7 +885,7 @@ class Frame {
} }
void dup2() { void dup2() {
stack = push(c, stack, c->stack(stack, 0)); stack = push(c, stack, c->stack(stack, 1));
stack = push(c, stack, c->stack(stack, 1)); stack = push(c, stack, c->stack(stack, 1));
dupped2(); dupped2();
@ -1568,7 +1589,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case astore: case astore:
frame->storeObject(codeBody(t, code, ip++)); frame->storeObjectOrAddress(codeBody(t, code, ip++));
break; break;
case astore_0: case astore_0:
@ -2067,9 +2088,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->release(a); c->release(a);
} break; } break;
case i2l: { case i2l:
frame->topIntToLong(); frame->topIntToLong();
} break; break;
case i2s: { case i2s: {
Operand* top = frame->topInt(); Operand* top = frame->topInt();
@ -2466,15 +2487,30 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case jsr: case jsr:
case jsr_w: case jsr_w: {
case ret: uint32_t newIp;
// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4381996
abort(t);
case l2i: { if (instruction == jsr) {
frame->topLongToInt(); newIp = (ip - 3) + codeReadInt16(t, code, ip);
} else {
newIp = (ip - 5) + codeReadInt32(t, code, ip);
}
assert(t, newIp < codeLength(t, code));
frame->pushAddress(frame->machineIp(ip));
c->jmp(frame->machineIp(newIp));
// NB: we assume that the stack will look the same on return
// from the subroutine as at call time.
compile(t, frame, newIp);
if (UNLIKELY(t->exception)) return;
} break; } break;
case l2i:
frame->topLongToInt();
break;
case ladd: { case ladd: {
Operand* a = frame->popLong(); Operand* a = frame->popLong();
c->add8(a, frame->topLong()); c->add8(a, frame->topLong());
@ -2964,6 +3000,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
c->release(value); c->release(value);
} break; } break;
case ret:
c->jmp
(c->memory
(c->base(), localOffset(t, codeBody(t, code, ip), frame->method)));
return;
case return_: case return_:
c->epilogue(); c->epilogue();
c->ret(); c->ret();
@ -3066,8 +3108,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case ret: case ret:
// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4381996 c->jmp
abort(t); (c->memory
(c->base(), localOffset
(t, codeReadInt16(t, code, ip), frame->method)));
return;
default: abort(t); default: abort(t);
} }
@ -3204,10 +3249,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/Long") == 0 and "org/eclipse/swt/internal/gtk/OS") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"valueOf") == 0) "ascii") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3403,7 +3448,7 @@ invokeNative2(MyThread* t, object method)
unsigned returnType = fieldType(t, returnCode); unsigned returnType = fieldType(t, returnCode);
uint64_t result; uint64_t result;
if (Verbose) { if (DebugNatives) {
fprintf(stderr, "invoke native method %s.%s\n", fprintf(stderr, "invoke native method %s.%s\n",
&byteArrayBody(t, className(t, methodClass(t, method)), 0), &byteArrayBody(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0)); &byteArrayBody(t, methodName(t, method), 0));
@ -3420,7 +3465,7 @@ invokeNative2(MyThread* t, object method)
returnType); returnType);
} }
if (Verbose) { if (DebugNatives) {
fprintf(stderr, "return from native method %s.%s\n", fprintf(stderr, "return from native method %s.%s\n",
&byteArrayBody(t, className(t, methodClass(t, method)), 0), &byteArrayBody(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0)); &byteArrayBody(t, methodName(t, method), 0));

View File

@ -1333,13 +1333,20 @@ RegisterOperand::accept(Context* c, Operation operation,
case cmp4: case cmp4:
case cmp8: { case cmp8: {
assert(c, isInt8(operand->value)); // todo
assert(c, BytesPerWord == 8 or operation == cmp4); // todo assert(c, BytesPerWord == 8 or operation == cmp4); // todo
rex(c); rex(c);
if (isInt8(operand->value)) {
c->code.append(0x83); c->code.append(0x83);
c->code.append(0xf8 | value(c)); c->code.append(0xf8 | value(c));
c->code.append(operand->value); c->code.append(operand->value);
} else {
assert(c, isInt32(operand->value));
c->code.append(0x81);
c->code.append(0xf8 | value(c));
c->code.append4(operand->value);
}
} break; } break;
case mov4: case mov4: