mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
implement jsr, jsr_w, and ret; various bugfixes to get SWT example working in JIT mode
This commit is contained in:
parent
c0cf15bb37
commit
848a67b397
@ -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
|
||||||
|
@ -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));
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user