From 848a67b3970d374ad255cff0154aa36b46561bd6 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 26 Dec 2007 16:59:55 -0700 Subject: [PATCH] implement jsr, jsr_w, and ret; various bugfixes to get SWT example working in JIT mode --- src/compile.S | 16 ++++++++-- src/compile.cpp | 77 ++++++++++++++++++++++++++++++++++++++---------- src/compiler.cpp | 15 +++++++--- 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/src/compile.S b/src/compile.S index c57ef260ed..4daccf30fe 100644 --- a/src/compile.S +++ b/src/compile.S @@ -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 diff --git a/src/compile.cpp b/src/compile.cpp index b7a612d2f5..cc21bc84b7 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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 (&byteArrayBody(t, className(t, methodClass(t, method)), 0)), - "java/lang/Long") == 0 and + "org/eclipse/swt/internal/gtk/OS") == 0 and strcmp(reinterpret_cast (&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)); diff --git a/src/compiler.cpp b/src/compiler.cpp index a5b54671db..a5ff0b6c11 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -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: