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
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 %r12
pushq %r13
pushq %r14
pushq %r15
// %rdi: thread
// %rsi: function
@ -20,7 +24,7 @@ vmInvoke:
mov %rdi,%rbx
// copy memory arguments into place
// copy arguments into place
pushq %rcx
movq $0,%r9
jmp test
@ -37,14 +41,20 @@ test:
call *%rsi
// pop arguments
mov -16(%rbp),%rcx
mov -48(%rbp),%rcx
sal $3,%rcx
addq %rcx,%rsp
// pop argument stack size
addq $8,%rsp
// pop callee-saved registers
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbx
movq %rbp,%rsp
popq %rbp
ret

View File

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

View File

@ -1333,13 +1333,20 @@ RegisterOperand::accept(Context* c, Operation operation,
case cmp4:
case cmp8: {
assert(c, isInt8(operand->value)); // todo
assert(c, BytesPerWord == 8 or operation == cmp4); // todo
rex(c);
c->code.append(0x83);
c->code.append(0xf8 | value(c));
c->code.append(operand->value);
if (isInt8(operand->value)) {
c->code.append(0x83);
c->code.append(0xf8 | value(c));
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;
case mov4: