mirror of
https://github.com/corda/corda.git
synced 2025-01-01 10:46:46 +00:00
Merge branch 'master' of dice.ecovate.com:/home/dicej/git/vm
This commit is contained in:
commit
07f4a359ad
@ -108,6 +108,8 @@ Java_java_lang_Object_clone(Thread* t, jclass, jobject o)
|
|||||||
if (classArrayElementSize(t, class_)) {
|
if (classArrayElementSize(t, class_)) {
|
||||||
clone = static_cast<object>(allocate(t, size));
|
clone = static_cast<object>(allocate(t, size));
|
||||||
memcpy(clone, *o, size);
|
memcpy(clone, *o, size);
|
||||||
|
// clear any object header flags:
|
||||||
|
cast<object>(*o, 0) = objectClass(t, *o);
|
||||||
} else {
|
} else {
|
||||||
clone = make(t, objectClass(t, *o));
|
clone = make(t, objectClass(t, *o));
|
||||||
memcpy(reinterpret_cast<void**>(clone) + 1,
|
memcpy(reinterpret_cast<void**>(clone) + 1,
|
||||||
|
139
src/compile.cpp
139
src/compile.cpp
@ -200,9 +200,15 @@ class Assembler {
|
|||||||
if (srcOffset) {
|
if (srcOffset) {
|
||||||
if (isByte(srcOffset)) {
|
if (isByte(srcOffset)) {
|
||||||
code.append(0x40 | (dst << 3) | src);
|
code.append(0x40 | (dst << 3) | src);
|
||||||
|
if (src == rsp) {
|
||||||
|
code.append(0x24);
|
||||||
|
}
|
||||||
code.append(srcOffset);
|
code.append(srcOffset);
|
||||||
} else {
|
} else {
|
||||||
code.append(0x80 | (dst << 3) | src);
|
code.append(0x80 | (dst << 3) | src);
|
||||||
|
if (src == rsp) {
|
||||||
|
code.append(0x24);
|
||||||
|
}
|
||||||
code.append4(srcOffset);
|
code.append4(srcOffset);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -216,9 +222,15 @@ class Assembler {
|
|||||||
if (dstOffset) {
|
if (dstOffset) {
|
||||||
if (isByte(dstOffset)) {
|
if (isByte(dstOffset)) {
|
||||||
code.append(0x40 | (src << 3) | dst);
|
code.append(0x40 | (src << 3) | dst);
|
||||||
|
if (dst == rsp) {
|
||||||
|
code.append(0x24);
|
||||||
|
}
|
||||||
code.append(dstOffset);
|
code.append(dstOffset);
|
||||||
} else {
|
} else {
|
||||||
code.append(0x80 | (src << 3) | dst);
|
code.append(0x80 | (src << 3) | dst);
|
||||||
|
if (dst == rsp) {
|
||||||
|
code.append(0x24);
|
||||||
|
}
|
||||||
code.append4(dstOffset);
|
code.append4(dstOffset);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -254,6 +266,9 @@ class Assembler {
|
|||||||
|
|
||||||
code.append(0xff);
|
code.append(0xff);
|
||||||
code.append(0x70 | reg);
|
code.append(0x70 | reg);
|
||||||
|
if (reg == rsp) {
|
||||||
|
code.append(0x24);
|
||||||
|
}
|
||||||
code.append(offset);
|
code.append(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +279,15 @@ class Assembler {
|
|||||||
code.append(v);
|
code.append(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pushAddress(uintptr_t v) {
|
||||||
|
if (BytesPerWord == 8) {
|
||||||
|
mov(v, rsi);
|
||||||
|
push(rsi);
|
||||||
|
} else {
|
||||||
|
push(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pop(Register dst) {
|
void pop(Register dst) {
|
||||||
code.append(0x58 | dst);
|
code.append(0x58 | dst);
|
||||||
}
|
}
|
||||||
@ -350,12 +374,6 @@ class Assembler {
|
|||||||
code.append(0xe0 | reg);
|
code.append(0xe0 | reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void jmp(Register reg, int offset) {
|
|
||||||
// code.append(0xff);
|
|
||||||
// code.append(0x60 | reg);
|
|
||||||
// code.append(offset);
|
|
||||||
// }
|
|
||||||
|
|
||||||
void jz(Label& label) {
|
void jz(Label& label) {
|
||||||
code.append(0x0F);
|
code.append(0x0F);
|
||||||
code.append(0x84);
|
code.append(0x84);
|
||||||
@ -450,8 +468,10 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
unsigned localFootprint = codeMaxLocals(t, code) * BytesPerWord;
|
unsigned localFootprint = codeMaxLocals(t, code) * BytesPerWord;
|
||||||
|
|
||||||
// reserve space for local variables
|
if (localFootprint > parameterFootprint) {
|
||||||
sub(localFootprint - parameterFootprint, rsp);
|
// reserve space for local variables
|
||||||
|
sub(localFootprint - parameterFootprint, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned ip = 0; ip < codeLength(t, code);) {
|
for (unsigned ip = 0; ip < codeLength(t, code);) {
|
||||||
unsigned instruction = codeBody(t, code, ip++);
|
unsigned instruction = codeBody(t, code, ip++);
|
||||||
@ -465,7 +485,7 @@ class Compiler: public Assembler {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case dup:
|
case dup:
|
||||||
push(rsp, 4);
|
push(rsp, BytesPerWord);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case getstatic: {
|
case getstatic: {
|
||||||
@ -534,9 +554,9 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
case iadd:
|
case iadd:
|
||||||
pop(rax);
|
pop(rax);
|
||||||
pop(rdx);
|
pop(rcx);
|
||||||
add(rax, rdx);
|
add(rax, rcx);
|
||||||
push(rdx);
|
push(rcx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iconst_m1:
|
case iconst_m1:
|
||||||
@ -567,21 +587,31 @@ class Compiler: public Assembler {
|
|||||||
push(5);
|
push(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aload:
|
||||||
|
case iload:
|
||||||
|
case fload:
|
||||||
|
push(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case aload_0:
|
||||||
case iload_0:
|
case iload_0:
|
||||||
case fload_0:
|
case fload_0:
|
||||||
push(rbp, localOffset(0, parameterFootprint));
|
push(rbp, localOffset(0, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aload_1:
|
||||||
case iload_1:
|
case iload_1:
|
||||||
case fload_1:
|
case fload_1:
|
||||||
push(rbp, localOffset(1, parameterFootprint));
|
push(rbp, localOffset(1, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aload_2:
|
||||||
case iload_2:
|
case iload_2:
|
||||||
case fload_2:
|
case fload_2:
|
||||||
push(rbp, localOffset(2, parameterFootprint));
|
push(rbp, localOffset(2, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aload_3:
|
||||||
case iload_3:
|
case iload_3:
|
||||||
case fload_3:
|
case fload_3:
|
||||||
push(rbp, localOffset(3, parameterFootprint));
|
push(rbp, localOffset(3, parameterFootprint));
|
||||||
@ -600,12 +630,12 @@ class Compiler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned footprint = FrameFootprint
|
unsigned footprint = FrameFootprint
|
||||||
+ methodParameterFootprint(t, target) * BytesPerWord;
|
+ (methodParameterFootprint(t, target) * BytesPerWord);
|
||||||
|
|
||||||
uint8_t* code = &compiledBody(t, methodCompiled(t, target), 0);
|
uint8_t* code = &compiledBody(t, methodCompiled(t, target), 0);
|
||||||
|
|
||||||
push(rbp, 0);
|
push(rbp);
|
||||||
push(reinterpret_cast<uintptr_t>(target));
|
pushAddress(reinterpret_cast<uintptr_t>(target));
|
||||||
push(rbp, FrameThread);
|
push(rbp, FrameThread);
|
||||||
|
|
||||||
alignedMov(reinterpret_cast<uintptr_t>(code), rax);
|
alignedMov(reinterpret_cast<uintptr_t>(code), rax);
|
||||||
@ -622,19 +652,24 @@ class Compiler: public Assembler {
|
|||||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
unsigned footprint = FrameFootprint
|
unsigned parameterFootprint
|
||||||
+ methodParameterFootprint(t, target) * BytesPerWord;
|
= methodParameterFootprint(t, target) * BytesPerWord;
|
||||||
|
|
||||||
|
unsigned instance = parameterFootprint - BytesPerWord;
|
||||||
|
|
||||||
|
unsigned footprint = FrameFootprint + parameterFootprint;
|
||||||
|
|
||||||
unsigned offset = ArrayBody + (methodOffset(t, target) * BytesPerWord);
|
unsigned offset = ArrayBody + (methodOffset(t, target) * BytesPerWord);
|
||||||
|
|
||||||
push(rbp, 0);
|
mov(rsp, instance, rax); // load instance
|
||||||
push(reinterpret_cast<uintptr_t>(target));
|
mov(rax, 0, rax); // load class
|
||||||
push(rbp, FrameThread);
|
|
||||||
|
|
||||||
mov(rsp, BytesPerWord * 3, rax); // load target object
|
|
||||||
mov(rax, 0, rax); // load target class
|
|
||||||
mov(rax, ClassVirtualTable, rax); // load vtable
|
mov(rax, ClassVirtualTable, rax); // load vtable
|
||||||
mov(rax, offset, rax); // load method
|
mov(rax, offset, rax); // load method
|
||||||
|
|
||||||
|
push(rbp, 0);
|
||||||
|
push(rax);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
|
||||||
mov(rax, MethodCompiled, rax); // load compiled code
|
mov(rax, MethodCompiled, rax); // load compiled code
|
||||||
add(CompiledBody, rax);
|
add(CompiledBody, rax);
|
||||||
call(rax); // call compiled code
|
call(rax); // call compiled code
|
||||||
@ -644,21 +679,31 @@ class Compiler: public Assembler {
|
|||||||
pushReturnValue(t, methodReturnCode(t, method));
|
pushReturnValue(t, methodReturnCode(t, method));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case astore:
|
||||||
|
case istore:
|
||||||
|
case fstore:
|
||||||
|
pop(rbp, localOffset(codeBody(t, code, ip++), parameterFootprint));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case astore_0:
|
||||||
case istore_0:
|
case istore_0:
|
||||||
case fstore_0:
|
case fstore_0:
|
||||||
pop(rbp, localOffset(0, parameterFootprint));
|
pop(rbp, localOffset(0, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case astore_1:
|
||||||
case istore_1:
|
case istore_1:
|
||||||
case fstore_1:
|
case fstore_1:
|
||||||
pop(rbp, localOffset(1, parameterFootprint));
|
pop(rbp, localOffset(1, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case astore_2:
|
||||||
case istore_2:
|
case istore_2:
|
||||||
case fstore_2:
|
case fstore_2:
|
||||||
pop(rbp, localOffset(2, parameterFootprint));
|
pop(rbp, localOffset(2, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case astore_3:
|
||||||
case istore_3:
|
case istore_3:
|
||||||
case fstore_3:
|
case fstore_3:
|
||||||
pop(rbp, localOffset(3, parameterFootprint));
|
pop(rbp, localOffset(3, parameterFootprint));
|
||||||
@ -687,14 +732,47 @@ class Compiler: public Assembler {
|
|||||||
} else if (objectClass(t, v)
|
} else if (objectClass(t, v)
|
||||||
== arrayBody(t, t->m->types, Machine::StringType))
|
== arrayBody(t, t->m->types, Machine::StringType))
|
||||||
{
|
{
|
||||||
push(reinterpret_cast<uintptr_t>(v));
|
pushAddress(reinterpret_cast<uintptr_t>(v));
|
||||||
} else {
|
} else {
|
||||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||||
|
|
||||||
push(reinterpret_cast<uintptr_t>(class_));
|
pushAddress(reinterpret_cast<uintptr_t>(class_));
|
||||||
}
|
}
|
||||||
} break;
|
} 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_: {
|
case pop_: {
|
||||||
add(BytesPerWord, rsp);
|
add(BytesPerWord, rsp);
|
||||||
} break;
|
} break;
|
||||||
@ -805,16 +883,11 @@ unwind(Thread* t)
|
|||||||
void
|
void
|
||||||
compileMethod(MyThread* t, object method)
|
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);
|
compileMethod2(t, method);
|
||||||
|
|
||||||
if (UNLIKELY(t->exception)) {
|
if (UNLIKELY(t->exception)) {
|
||||||
unwind(t);
|
unwind(t);
|
||||||
} else {
|
} else if (not methodVirtual(t, method)) {
|
||||||
updateCaller(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
|
object
|
||||||
makeByteArray(Thread* t, const char* format, ...)
|
makeByteArray(Thread* t, const char* format, ...)
|
||||||
{
|
{
|
||||||
|
@ -1550,6 +1550,43 @@ makeExceptionInInitializerError(Thread* t, object cause)
|
|||||||
return makeExceptionInInitializerError(t, 0, trace, 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
|
object
|
||||||
make(Thread* t, object class_);
|
make(Thread* t, object class_);
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ public class Instructions {
|
|||||||
int b = 2;
|
int b = 2;
|
||||||
int c = a + b;
|
int c = a + b;
|
||||||
|
|
||||||
// Instructions i = new Instructions();
|
Instructions i = new Instructions();
|
||||||
// i.foo("hello");
|
i.foo("hello");
|
||||||
// i.bar("hello");
|
i.bar("hello");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user