mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
add a few more instructions to compile.cpp and fix bugs in others; invokespecial and invokevirtual are working
This commit is contained in:
parent
bd95ccdbd6
commit
d1681c0918
139
src/compile.cpp
139
src/compile.cpp
@ -200,9 +200,15 @@ class Assembler {
|
||||
if (srcOffset) {
|
||||
if (isByte(srcOffset)) {
|
||||
code.append(0x40 | (dst << 3) | src);
|
||||
if (src == rsp) {
|
||||
code.append(0x24);
|
||||
}
|
||||
code.append(srcOffset);
|
||||
} else {
|
||||
code.append(0x80 | (dst << 3) | src);
|
||||
if (src == rsp) {
|
||||
code.append(0x24);
|
||||
}
|
||||
code.append4(srcOffset);
|
||||
}
|
||||
} else {
|
||||
@ -216,9 +222,15 @@ class Assembler {
|
||||
if (dstOffset) {
|
||||
if (isByte(dstOffset)) {
|
||||
code.append(0x40 | (src << 3) | dst);
|
||||
if (dst == rsp) {
|
||||
code.append(0x24);
|
||||
}
|
||||
code.append(dstOffset);
|
||||
} else {
|
||||
code.append(0x80 | (src << 3) | dst);
|
||||
if (dst == rsp) {
|
||||
code.append(0x24);
|
||||
}
|
||||
code.append4(dstOffset);
|
||||
}
|
||||
} else {
|
||||
@ -254,6 +266,9 @@ class Assembler {
|
||||
|
||||
code.append(0xff);
|
||||
code.append(0x70 | reg);
|
||||
if (reg == rsp) {
|
||||
code.append(0x24);
|
||||
}
|
||||
code.append(offset);
|
||||
}
|
||||
|
||||
@ -264,6 +279,15 @@ class Assembler {
|
||||
code.append(v);
|
||||
}
|
||||
|
||||
void pushAddress(uintptr_t v) {
|
||||
if (BytesPerWord == 8) {
|
||||
mov(v, rsi);
|
||||
push(rsi);
|
||||
} else {
|
||||
push(v);
|
||||
}
|
||||
}
|
||||
|
||||
void pop(Register dst) {
|
||||
code.append(0x58 | dst);
|
||||
}
|
||||
@ -350,12 +374,6 @@ class Assembler {
|
||||
code.append(0xe0 | reg);
|
||||
}
|
||||
|
||||
// void jmp(Register reg, int offset) {
|
||||
// code.append(0xff);
|
||||
// code.append(0x60 | reg);
|
||||
// code.append(offset);
|
||||
// }
|
||||
|
||||
void jz(Label& label) {
|
||||
code.append(0x0F);
|
||||
code.append(0x84);
|
||||
@ -450,8 +468,10 @@ class Compiler: public Assembler {
|
||||
|
||||
unsigned localFootprint = codeMaxLocals(t, code) * BytesPerWord;
|
||||
|
||||
// reserve space for local variables
|
||||
sub(localFootprint - parameterFootprint, rsp);
|
||||
if (localFootprint > parameterFootprint) {
|
||||
// reserve space for local variables
|
||||
sub(localFootprint - parameterFootprint, rsp);
|
||||
}
|
||||
|
||||
for (unsigned ip = 0; ip < codeLength(t, code);) {
|
||||
unsigned instruction = codeBody(t, code, ip++);
|
||||
@ -465,7 +485,7 @@ class Compiler: public Assembler {
|
||||
break;
|
||||
|
||||
case dup:
|
||||
push(rsp, 4);
|
||||
push(rsp, BytesPerWord);
|
||||
break;
|
||||
|
||||
case getstatic: {
|
||||
@ -534,9 +554,9 @@ class Compiler: public Assembler {
|
||||
|
||||
case iadd:
|
||||
pop(rax);
|
||||
pop(rdx);
|
||||
add(rax, rdx);
|
||||
push(rdx);
|
||||
pop(rcx);
|
||||
add(rax, rcx);
|
||||
push(rcx);
|
||||
break;
|
||||
|
||||
case iconst_m1:
|
||||
@ -567,21 +587,31 @@ class Compiler: public Assembler {
|
||||
push(5);
|
||||
break;
|
||||
|
||||
case aload:
|
||||
case iload:
|
||||
case fload:
|
||||
push(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint));
|
||||
break;
|
||||
|
||||
case aload_0:
|
||||
case iload_0:
|
||||
case fload_0:
|
||||
push(rbp, localOffset(0, parameterFootprint));
|
||||
break;
|
||||
|
||||
case aload_1:
|
||||
case iload_1:
|
||||
case fload_1:
|
||||
push(rbp, localOffset(1, parameterFootprint));
|
||||
break;
|
||||
|
||||
case aload_2:
|
||||
case iload_2:
|
||||
case fload_2:
|
||||
push(rbp, localOffset(2, parameterFootprint));
|
||||
break;
|
||||
|
||||
case aload_3:
|
||||
case iload_3:
|
||||
case fload_3:
|
||||
push(rbp, localOffset(3, parameterFootprint));
|
||||
@ -600,12 +630,12 @@ class Compiler: public Assembler {
|
||||
}
|
||||
|
||||
unsigned footprint = FrameFootprint
|
||||
+ methodParameterFootprint(t, target) * BytesPerWord;
|
||||
+ (methodParameterFootprint(t, target) * BytesPerWord);
|
||||
|
||||
uint8_t* code = &compiledBody(t, methodCompiled(t, target), 0);
|
||||
|
||||
push(rbp, 0);
|
||||
push(reinterpret_cast<uintptr_t>(target));
|
||||
push(rbp);
|
||||
pushAddress(reinterpret_cast<uintptr_t>(target));
|
||||
push(rbp, FrameThread);
|
||||
|
||||
alignedMov(reinterpret_cast<uintptr_t>(code), rax);
|
||||
@ -622,19 +652,24 @@ class Compiler: public Assembler {
|
||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
|
||||
unsigned footprint = FrameFootprint
|
||||
+ methodParameterFootprint(t, target) * BytesPerWord;
|
||||
unsigned parameterFootprint
|
||||
= methodParameterFootprint(t, target) * BytesPerWord;
|
||||
|
||||
unsigned instance = parameterFootprint - BytesPerWord;
|
||||
|
||||
unsigned footprint = FrameFootprint + parameterFootprint;
|
||||
|
||||
unsigned offset = ArrayBody + (methodOffset(t, target) * BytesPerWord);
|
||||
|
||||
push(rbp, 0);
|
||||
push(reinterpret_cast<uintptr_t>(target));
|
||||
push(rbp, FrameThread);
|
||||
|
||||
mov(rsp, BytesPerWord * 3, rax); // load target object
|
||||
mov(rax, 0, rax); // load target class
|
||||
|
||||
mov(rsp, instance, rax); // load instance
|
||||
mov(rax, 0, rax); // load class
|
||||
mov(rax, ClassVirtualTable, rax); // load vtable
|
||||
mov(rax, offset, rax); // load method
|
||||
|
||||
push(rbp, 0);
|
||||
push(rax);
|
||||
push(rbp, FrameThread);
|
||||
|
||||
mov(rax, MethodCompiled, rax); // load compiled code
|
||||
add(CompiledBody, rax);
|
||||
call(rax); // call compiled code
|
||||
@ -644,21 +679,31 @@ class Compiler: public Assembler {
|
||||
pushReturnValue(t, methodReturnCode(t, method));
|
||||
} break;
|
||||
|
||||
case astore:
|
||||
case istore:
|
||||
case fstore:
|
||||
pop(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint));
|
||||
break;
|
||||
|
||||
case astore_0:
|
||||
case istore_0:
|
||||
case fstore_0:
|
||||
pop(rbp, localOffset(0, parameterFootprint));
|
||||
break;
|
||||
|
||||
case astore_1:
|
||||
case istore_1:
|
||||
case fstore_1:
|
||||
pop(rbp, localOffset(1, parameterFootprint));
|
||||
break;
|
||||
|
||||
case astore_2:
|
||||
case istore_2:
|
||||
case fstore_2:
|
||||
pop(rbp, localOffset(2, parameterFootprint));
|
||||
break;
|
||||
|
||||
case astore_3:
|
||||
case istore_3:
|
||||
case fstore_3:
|
||||
pop(rbp, localOffset(3, parameterFootprint));
|
||||
@ -687,14 +732,47 @@ class Compiler: public Assembler {
|
||||
} else if (objectClass(t, v)
|
||||
== arrayBody(t, t->m->types, Machine::StringType))
|
||||
{
|
||||
push(reinterpret_cast<uintptr_t>(v));
|
||||
pushAddress(reinterpret_cast<uintptr_t>(v));
|
||||
} else {
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
|
||||
push(reinterpret_cast<uintptr_t>(class_));
|
||||
pushAddress(reinterpret_cast<uintptr_t>(class_));
|
||||
}
|
||||
} break;
|
||||
|
||||
case new_: {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
PROTECT(t, class_);
|
||||
|
||||
initClass(t, class_);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
pushAddress(reinterpret_cast<uintptr_t>(class_));
|
||||
push(rbp, FrameThread);
|
||||
} else {
|
||||
mov(reinterpret_cast<uintptr_t>(class_), rsi);
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
||||
mov(reinterpret_cast<uintptr_t>(makeNewWeakReference), rax);
|
||||
} else {
|
||||
mov(reinterpret_cast<uintptr_t>(makeNew), rax);
|
||||
}
|
||||
|
||||
call(rax);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 2, rsp);
|
||||
}
|
||||
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
case pop_: {
|
||||
add(BytesPerWord, rsp);
|
||||
} break;
|
||||
@ -805,16 +883,11 @@ unwind(Thread* t)
|
||||
void
|
||||
compileMethod(MyThread* t, object method)
|
||||
{
|
||||
if (methodVirtual(t, method)) {
|
||||
object this_ = static_cast<object*>
|
||||
(t->frame)[2 + (FrameFootprint / BytesPerWord)];
|
||||
method = findMethod(t, method, objectClass(t, this_));
|
||||
}
|
||||
|
||||
compileMethod2(t, method);
|
||||
|
||||
if (UNLIKELY(t->exception)) {
|
||||
unwind(t);
|
||||
} else {
|
||||
} else if (not methodVirtual(t, method)) {
|
||||
updateCaller(t, method);
|
||||
}
|
||||
}
|
||||
|
@ -1714,28 +1714,6 @@ allocate2(Thread* t, unsigned sizeInBytes)
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
make(Thread* t, object class_)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
unsigned sizeInBytes = pad(classFixedSize(t, class_));
|
||||
object instance = allocate(t, sizeInBytes);
|
||||
cast<object>(instance, 0) = class_;
|
||||
memset(&cast<object>(instance, 0) + 1, 0,
|
||||
sizeInBytes - sizeof(object));
|
||||
|
||||
if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) {
|
||||
PROTECT(t, instance);
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
jreferenceNextUnsafe(t, instance) = t->m->weakReferences;
|
||||
t->m->weakReferences = instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
object
|
||||
makeByteArray(Thread* t, const char* format, ...)
|
||||
{
|
||||
|
@ -1550,6 +1550,43 @@ makeExceptionInInitializerError(Thread* t, object cause)
|
||||
return makeExceptionInInitializerError(t, 0, trace, cause);
|
||||
}
|
||||
|
||||
inline object
|
||||
makeNew(Thread* t, object class_)
|
||||
{
|
||||
PROTECT(t, class_);
|
||||
unsigned sizeInBytes = pad(classFixedSize(t, class_));
|
||||
object instance = allocate(t, sizeInBytes);
|
||||
cast<object>(instance, 0) = class_;
|
||||
memset(&cast<object>(instance, 0) + 1, 0,
|
||||
sizeInBytes - sizeof(object));
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
inline object
|
||||
makeNewWeakReference(Thread* t, object class_)
|
||||
{
|
||||
object instance = makeNew(t, class_);
|
||||
PROTECT(t, instance);
|
||||
|
||||
ACQUIRE(t, t->m->referenceLock);
|
||||
|
||||
jreferenceNextUnsafe(t, instance) = t->m->weakReferences;
|
||||
t->m->weakReferences = instance;
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
inline object
|
||||
make(Thread* t, object class_)
|
||||
{
|
||||
if (UNLIKELY(classVmFlags(t, class_) & WeakReferenceFlag)) {
|
||||
return makeNewWeakReference(t, class_);
|
||||
} else {
|
||||
return makeNew(t, class_);
|
||||
}
|
||||
}
|
||||
|
||||
object
|
||||
make(Thread* t, object class_);
|
||||
|
||||
|
@ -12,8 +12,8 @@ public class Instructions {
|
||||
int b = 2;
|
||||
int c = a + b;
|
||||
|
||||
// Instructions i = new Instructions();
|
||||
// i.foo("hello");
|
||||
// i.bar("hello");
|
||||
Instructions i = new Instructions();
|
||||
i.foo("hello");
|
||||
i.bar("hello");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user