mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
lots of new instructions and bugfixes
This commit is contained in:
parent
b0500a881c
commit
8ae36c05b7
@ -1,12 +1,14 @@
|
|||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
public class PrintStream extends OutputStream {
|
public class PrintStream extends OutputStream {
|
||||||
private static final byte[] newline
|
|
||||||
= System.getProperty("line.separator").getBytes();
|
|
||||||
|
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
private final boolean autoFlush;
|
private final boolean autoFlush;
|
||||||
|
|
||||||
|
private static class Static {
|
||||||
|
private static final byte[] newline
|
||||||
|
= System.getProperty("line.separator").getBytes();
|
||||||
|
}
|
||||||
|
|
||||||
public PrintStream(OutputStream out, boolean autoFlush) {
|
public PrintStream(OutputStream out, boolean autoFlush) {
|
||||||
this.out = out;
|
this.out = out;
|
||||||
this.autoFlush = autoFlush;
|
this.autoFlush = autoFlush;
|
||||||
@ -33,14 +35,14 @@ public class PrintStream extends OutputStream {
|
|||||||
public synchronized void println(String s) {
|
public synchronized void println(String s) {
|
||||||
try {
|
try {
|
||||||
out.write(s.getBytes());
|
out.write(s.getBytes());
|
||||||
out.write(newline);
|
out.write(Static.newline);
|
||||||
if (autoFlush) flush();
|
if (autoFlush) flush();
|
||||||
} catch (IOException e) { }
|
} catch (IOException e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void println() {
|
public synchronized void println() {
|
||||||
try {
|
try {
|
||||||
out.write(newline);
|
out.write(Static.newline);
|
||||||
if (autoFlush) flush();
|
if (autoFlush) flush();
|
||||||
} catch (IOException e) { }
|
} catch (IOException e) { }
|
||||||
}
|
}
|
||||||
|
281
src/compile.cpp
281
src/compile.cpp
@ -32,6 +32,30 @@ throwNew(Thread* t, object class_)
|
|||||||
unwind(t);
|
unwind(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
throw_(Thread* t, object o)
|
||||||
|
{
|
||||||
|
if (o) {
|
||||||
|
t->exception = makeNullPointerException(t);
|
||||||
|
} else {
|
||||||
|
t->exception = o;
|
||||||
|
}
|
||||||
|
unwind(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
makeBlankObjectArray(Thread* t, object class_, int32_t length)
|
||||||
|
{
|
||||||
|
return makeObjectArray(t, class_, length, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
object
|
||||||
|
makeBlankArray(Thread* t, object (*constructor)(Thread*, uintptr_t, bool),
|
||||||
|
int32_t length)
|
||||||
|
{
|
||||||
|
return constructor(t, length, true);
|
||||||
|
}
|
||||||
|
|
||||||
class Buffer {
|
class Buffer {
|
||||||
public:
|
public:
|
||||||
Buffer(System* s, unsigned minimumCapacity):
|
Buffer(System* s, unsigned minimumCapacity):
|
||||||
@ -402,6 +426,17 @@ class Assembler {
|
|||||||
code.append(v);
|
code.append(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add(int32_t v, Register dst, unsigned offset) {
|
||||||
|
rex();
|
||||||
|
unsigned i = (isByte(v) ? 0x83 : 0x81);
|
||||||
|
offsetInstruction(i, 0, 0x40, 0x80, rax, dst, offset);
|
||||||
|
if (isByte(v)) {
|
||||||
|
code.append(v);
|
||||||
|
} else {
|
||||||
|
code.append4(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sub(Register src, Register dst) {
|
void sub(Register src, Register dst) {
|
||||||
rex();
|
rex();
|
||||||
code.append(0x29);
|
code.append(0x29);
|
||||||
@ -470,9 +505,9 @@ class Assembler {
|
|||||||
code.append(0xe0 | reg);
|
code.append(0xe0 | reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void je(Label& label) {
|
void conditional(Label& label, unsigned condition) {
|
||||||
code.append(0x0f);
|
code.append(0x0f);
|
||||||
code.append(0x84);
|
code.append(condition);
|
||||||
label.reference();
|
label.reference();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,32 +521,50 @@ class Assembler {
|
|||||||
code.append4(0);
|
code.append4(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void je(Label& label) {
|
||||||
|
conditional(label, 0x84);
|
||||||
|
}
|
||||||
|
|
||||||
void je(unsigned javaIP) {
|
void je(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x84);
|
conditional(javaIP, 0x84);
|
||||||
}
|
}
|
||||||
|
|
||||||
void jne(Label& label) {
|
void jne(Label& label) {
|
||||||
code.append(0x0f);
|
conditional(label, 0x85);
|
||||||
code.append(0x85);
|
|
||||||
label.reference();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void jne(unsigned javaIP) {
|
void jne(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x85);
|
conditional(javaIP, 0x85);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jg(Label& label) {
|
||||||
|
conditional(label, 0x8f);
|
||||||
|
}
|
||||||
|
|
||||||
void jg(unsigned javaIP) {
|
void jg(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x8f);
|
conditional(javaIP, 0x8f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jge(Label& label) {
|
||||||
|
conditional(label, 0x8d);
|
||||||
|
}
|
||||||
|
|
||||||
void jge(unsigned javaIP) {
|
void jge(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x8d);
|
conditional(javaIP, 0x8d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jl(Label& label) {
|
||||||
|
conditional(label, 0x8c);
|
||||||
|
}
|
||||||
|
|
||||||
void jl(unsigned javaIP) {
|
void jl(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x8c);
|
conditional(javaIP, 0x8c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jle(Label& label) {
|
||||||
|
conditional(label, 0x8e);
|
||||||
|
}
|
||||||
|
|
||||||
void jle(unsigned javaIP) {
|
void jle(unsigned javaIP) {
|
||||||
conditional(javaIP, 0x8e);
|
conditional(javaIP, 0x8e);
|
||||||
}
|
}
|
||||||
@ -539,7 +592,8 @@ localOffset(int v, int parameterFootprint)
|
|||||||
{
|
{
|
||||||
v *= BytesPerWord;
|
v *= BytesPerWord;
|
||||||
if (v < parameterFootprint) {
|
if (v < parameterFootprint) {
|
||||||
return v + (BytesPerWord * 2) + FrameFootprint;
|
return (parameterFootprint - v - BytesPerWord) + (BytesPerWord * 2)
|
||||||
|
+ FrameFootprint;
|
||||||
} else {
|
} else {
|
||||||
return -(v + BytesPerWord - parameterFootprint);
|
return -(v + BytesPerWord - parameterFootprint);
|
||||||
}
|
}
|
||||||
@ -574,11 +628,9 @@ sseRegister(Thread* t, unsigned index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
parameterOffset(Thread* t, object method, unsigned index)
|
parameterOffset(unsigned index)
|
||||||
{
|
{
|
||||||
return FrameFootprint
|
return FrameFootprint + ((index + 2) * BytesPerWord);
|
||||||
+ (((methodParameterFootprint(t, method) - index - 1) + 2)
|
|
||||||
* BytesPerWord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Compiler: public Assembler {
|
class Compiler: public Assembler {
|
||||||
@ -635,7 +687,7 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
void compileCall(uintptr_t function, uintptr_t arg1) {
|
void compileCall(uintptr_t function, uintptr_t arg1) {
|
||||||
if (BytesPerWord == 4) {
|
if (BytesPerWord == 4) {
|
||||||
pushAddress(arg1);
|
push(arg1);
|
||||||
push(rbp, FrameThread);
|
push(rbp, FrameThread);
|
||||||
} else {
|
} else {
|
||||||
mov(arg1, rsi);
|
mov(arg1, rsi);
|
||||||
@ -650,6 +702,42 @@ class Compiler: public Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void compileCall(uintptr_t function, Register arg1) {
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
push(arg1);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
} else {
|
||||||
|
mov(arg1, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
}
|
||||||
|
|
||||||
|
mov(function, rax);
|
||||||
|
call(rax);
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 2, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileCall(uintptr_t function, uintptr_t arg1, Register arg2) {
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
push(arg2);
|
||||||
|
push(arg1);
|
||||||
|
push(rbp, FrameThread);
|
||||||
|
} else {
|
||||||
|
mov(arg2, rdx);
|
||||||
|
mov(arg1, rsi);
|
||||||
|
mov(rbp, FrameThread, rdi);
|
||||||
|
}
|
||||||
|
|
||||||
|
mov(function, rax);
|
||||||
|
call(rax);
|
||||||
|
|
||||||
|
if (BytesPerWord == 4) {
|
||||||
|
add(BytesPerWord * 3, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void compileCall(uintptr_t function, Register arg1, Register arg2) {
|
void compileCall(uintptr_t function, Register arg1, Register arg2) {
|
||||||
if (BytesPerWord == 4) {
|
if (BytesPerWord == 4) {
|
||||||
push(arg2);
|
push(arg2);
|
||||||
@ -682,6 +770,12 @@ class Compiler: public Assembler {
|
|||||||
- reinterpret_cast<uintptr_t>(t);
|
- reinterpret_cast<uintptr_t>(t);
|
||||||
|
|
||||||
void* function = resolveNativeMethod(t, method);
|
void* function = resolveNativeMethod(t, method);
|
||||||
|
if (UNLIKELY(function == 0)) {
|
||||||
|
object message = makeString
|
||||||
|
(t, "%s", &byteArrayBody(t, methodCode(t, method), 0));
|
||||||
|
t->exception = makeUnsatisfiedLinkError(t, message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
push(rbp);
|
push(rbp);
|
||||||
mov(rsp, rbp);
|
mov(rsp, rbp);
|
||||||
@ -697,16 +791,23 @@ class Compiler: public Assembler {
|
|||||||
index = 1;
|
index = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodSpecIterator it(t, reinterpret_cast<const char*>
|
unsigned parameterCodes[methodParameterCount(t, method)];
|
||||||
|
MethodSpecIterator it
|
||||||
|
(t, reinterpret_cast<const char*>
|
||||||
(&byteArrayBody(t, methodSpec(t, method), 0)));
|
(&byteArrayBody(t, methodSpec(t, method), 0)));
|
||||||
|
|
||||||
|
for (unsigned i = 0; it.hasNext(); ++i) {
|
||||||
|
parameterCodes[i] = fieldCode(t, *it.next());
|
||||||
|
}
|
||||||
|
|
||||||
unsigned stackFootprint;
|
unsigned stackFootprint;
|
||||||
|
unsigned parameterCodeIndex = methodParameterCount(t, method);
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (BytesPerWord == 4) {
|
||||||
while (it.hasNext()) {
|
while (parameterCodeIndex) {
|
||||||
unsigned offset = parameterOffset(t, method, index);
|
unsigned offset = parameterOffset(index);
|
||||||
|
|
||||||
switch (fieldCode(t, *it.next())) {
|
switch (parameterCodes[--parameterCodeIndex]) {
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
case ByteField:
|
case ByteField:
|
||||||
case ShortField:
|
case ShortField:
|
||||||
@ -741,7 +842,8 @@ class Compiler: public Assembler {
|
|||||||
sub(BytesPerWord, rax);
|
sub(BytesPerWord, rax);
|
||||||
push(rax); // push pointer to class pointer
|
push(rax); // push pointer to class pointer
|
||||||
} else {
|
} else {
|
||||||
unsigned offset = parameterOffset(t, method, 0);
|
unsigned offset = parameterOffset
|
||||||
|
(methodParameterFootprint(t, method) - 1);
|
||||||
mov(rbp, rax);
|
mov(rbp, rax);
|
||||||
add(offset, rax);
|
add(offset, rax);
|
||||||
push(rax); // push pointer to this pointer
|
push(rax); // push pointer to this pointer
|
||||||
@ -760,10 +862,10 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
stackFootprint = 0;
|
stackFootprint = 0;
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (parameterCodeIndex) {
|
||||||
unsigned offset = parameterOffset(t, method, index);
|
unsigned offset = parameterOffset(index);
|
||||||
|
|
||||||
switch (fieldCode(t, *it.next())) {
|
switch (parameterCodes[--parameterCodeIndex]) {
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
case ByteField:
|
case ByteField:
|
||||||
case ShortField:
|
case ShortField:
|
||||||
@ -817,7 +919,8 @@ class Compiler: public Assembler {
|
|||||||
mov(rbp, rsi);
|
mov(rbp, rsi);
|
||||||
sub(BytesPerWord, rsi); // push pointer to class pointer
|
sub(BytesPerWord, rsi); // push pointer to class pointer
|
||||||
} else {
|
} else {
|
||||||
unsigned offset = parameterOffset(t, method, 0);
|
unsigned offset = parameterOffset
|
||||||
|
(methodParameterFootprint(t, method) - 1);
|
||||||
mov(rbp, rsi);
|
mov(rbp, rsi);
|
||||||
add(offset, rsi); // push pointer to this pointer
|
add(offset, rsi); // push pointer to this pointer
|
||||||
}
|
}
|
||||||
@ -897,6 +1000,31 @@ class Compiler: public Assembler {
|
|||||||
push(rbp, localOffset(3, parameterFootprint));
|
push(rbp, localOffset(3, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case anewarray: {
|
||||||
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
|
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||||
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
|
Label nonnegative(this);
|
||||||
|
|
||||||
|
pop(rax);
|
||||||
|
cmp(0, rax);
|
||||||
|
jle(nonnegative);
|
||||||
|
|
||||||
|
compileCall
|
||||||
|
(reinterpret_cast<uintptr_t>(throwNew),
|
||||||
|
reinterpret_cast<uintptr_t>
|
||||||
|
(arrayBody(t, t->m->types,
|
||||||
|
Machine::NegativeArraySizeExceptionType)));
|
||||||
|
|
||||||
|
nonnegative.mark();
|
||||||
|
compileCall(reinterpret_cast<uintptr_t>(makeBlankObjectArray),
|
||||||
|
reinterpret_cast<uintptr_t>(class_),
|
||||||
|
rax);
|
||||||
|
push(rax);
|
||||||
|
} break;
|
||||||
|
|
||||||
case areturn:
|
case areturn:
|
||||||
case ireturn:
|
case ireturn:
|
||||||
case freturn:
|
case freturn:
|
||||||
@ -936,6 +1064,11 @@ class Compiler: public Assembler {
|
|||||||
pop(rbp, localOffset(3, parameterFootprint));
|
pop(rbp, localOffset(3, parameterFootprint));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case athrow:
|
||||||
|
pop(rax);
|
||||||
|
compileCall(reinterpret_cast<uintptr_t>(throw_), rax);
|
||||||
|
break;
|
||||||
|
|
||||||
case bipush: {
|
case bipush: {
|
||||||
push(static_cast<int8_t>(codeBody(t, code, ip++)));
|
push(static_cast<int8_t>(codeBody(t, code, ip++)));
|
||||||
} break;
|
} break;
|
||||||
@ -948,7 +1081,7 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
Label next(this);
|
Label next(this);
|
||||||
|
|
||||||
pop(rax);
|
mov(rsp, 0, rax);
|
||||||
cmp(0, rax);
|
cmp(0, rax);
|
||||||
je(next);
|
je(next);
|
||||||
|
|
||||||
@ -970,7 +1103,7 @@ class Compiler: public Assembler {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case dup:
|
case dup:
|
||||||
push(rsp, BytesPerWord);
|
push(rsp, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case getfield: {
|
case getfield: {
|
||||||
@ -1031,7 +1164,7 @@ class Compiler: public Assembler {
|
|||||||
object table = classStaticTable(t, fieldClass(t, field));
|
object table = classStaticTable(t, fieldClass(t, field));
|
||||||
|
|
||||||
mov(reinterpret_cast<uintptr_t>(table), rax);
|
mov(reinterpret_cast<uintptr_t>(table), rax);
|
||||||
add(fieldOffset(t, field), rax);
|
add((fieldOffset(t, field) * BytesPerWord) + ArrayBody, rax);
|
||||||
|
|
||||||
switch (fieldCode(t, field)) {
|
switch (fieldCode(t, field)) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -1082,6 +1215,16 @@ class Compiler: public Assembler {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case goto_: {
|
||||||
|
int16_t offset = codeReadInt16(t, code, ip);
|
||||||
|
jmp((ip - 3) + offset);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case goto_w: {
|
||||||
|
int32_t offset = codeReadInt32(t, code, ip);
|
||||||
|
jmp((ip - 5) + offset);
|
||||||
|
} break;
|
||||||
|
|
||||||
case iadd:
|
case iadd:
|
||||||
pop(rax);
|
pop(rax);
|
||||||
pop(rcx);
|
pop(rcx);
|
||||||
@ -1223,14 +1366,11 @@ class Compiler: public Assembler {
|
|||||||
jle((ip - 3) + offset);
|
jle((ip - 3) + offset);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case goto_: {
|
case iinc: {
|
||||||
int16_t offset = codeReadInt16(t, code, ip);
|
uint8_t index = codeBody(t, code, ip++);
|
||||||
jmp((ip - 3) + offset);
|
int8_t c = codeBody(t, code, ip++);
|
||||||
} break;
|
|
||||||
|
|
||||||
case goto_w: {
|
add(c, rbp, localOffset(index, parameterFootprint));
|
||||||
int32_t offset = codeReadInt32(t, code, ip);
|
|
||||||
jmp((ip - 5) + offset);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case instanceof: {
|
case instanceof: {
|
||||||
@ -1326,6 +1466,13 @@ class Compiler: public Assembler {
|
|||||||
pushReturnValue(t, methodReturnCode(t, target));
|
pushReturnValue(t, methodReturnCode(t, target));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case isub:
|
||||||
|
pop(rax);
|
||||||
|
pop(rcx);
|
||||||
|
sub(rax, rcx);
|
||||||
|
push(rcx);
|
||||||
|
break;
|
||||||
|
|
||||||
case ldc:
|
case ldc:
|
||||||
case ldc_w: {
|
case ldc_w: {
|
||||||
uint16_t index;
|
uint16_t index;
|
||||||
@ -1378,6 +1525,66 @@ class Compiler: public Assembler {
|
|||||||
push(rax);
|
push(rax);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case newarray: {
|
||||||
|
uint8_t type = codeBody(t, code, ip++);
|
||||||
|
|
||||||
|
Label nonnegative(this);
|
||||||
|
|
||||||
|
pop(rax);
|
||||||
|
cmp(0, rax);
|
||||||
|
jge(nonnegative);
|
||||||
|
|
||||||
|
compileCall
|
||||||
|
(reinterpret_cast<uintptr_t>(throwNew),
|
||||||
|
reinterpret_cast<uintptr_t>
|
||||||
|
(arrayBody(t, t->m->types,
|
||||||
|
Machine::NegativeArraySizeExceptionType)));
|
||||||
|
|
||||||
|
nonnegative.mark();
|
||||||
|
|
||||||
|
object (*constructor)(Thread*, uintptr_t, bool);
|
||||||
|
switch (type) {
|
||||||
|
case T_BOOLEAN:
|
||||||
|
constructor = makeBooleanArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_CHAR:
|
||||||
|
constructor = makeCharArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_FLOAT:
|
||||||
|
constructor = makeFloatArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_DOUBLE:
|
||||||
|
constructor = makeDoubleArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_BYTE:
|
||||||
|
constructor = makeByteArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_SHORT:
|
||||||
|
constructor = makeShortArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_INT:
|
||||||
|
constructor = makeIntArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_LONG:
|
||||||
|
constructor = makeLongArray;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
compileCall(reinterpret_cast<uintptr_t>(makeBlankArray),
|
||||||
|
reinterpret_cast<uintptr_t>(constructor),
|
||||||
|
rax);
|
||||||
|
push(rax);
|
||||||
|
} break;
|
||||||
|
|
||||||
case pop_: {
|
case pop_: {
|
||||||
add(BytesPerWord, rsp);
|
add(BytesPerWord, rsp);
|
||||||
} break;
|
} break;
|
||||||
@ -1446,7 +1653,7 @@ class Compiler: public Assembler {
|
|||||||
object table = classStaticTable(t, fieldClass(t, field));
|
object table = classStaticTable(t, fieldClass(t, field));
|
||||||
|
|
||||||
mov(reinterpret_cast<uintptr_t>(table), rax);
|
mov(reinterpret_cast<uintptr_t>(table), rax);
|
||||||
add(fieldOffset(t, field), rax);
|
add((fieldOffset(t, field) * BytesPerWord) + ArrayBody, rax);
|
||||||
|
|
||||||
switch (fieldCode(t, field)) {
|
switch (fieldCode(t, field)) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
@ -1486,6 +1693,10 @@ class Compiler: public Assembler {
|
|||||||
ret();
|
ret();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case sipush: {
|
||||||
|
push(static_cast<int16_t>(codeReadInt16(t, code, ip)));
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort(t);
|
abort(t);
|
||||||
}
|
}
|
||||||
@ -1575,7 +1786,7 @@ compileMethod2(MyThread* t, object method)
|
|||||||
Compiler c(t->m->system);
|
Compiler c(t->m->system);
|
||||||
c.compile(t, method);
|
c.compile(t, method);
|
||||||
|
|
||||||
object compiled = makeCompiled(t, 0, c.code.length(), false);
|
object compiled = makeCompiled(t, c.code.length(), false);
|
||||||
if (UNLIKELY(t->exception)) return;
|
if (UNLIKELY(t->exception)) return;
|
||||||
|
|
||||||
c.code.copyTo(&compiledBody(t, compiled, 0));
|
c.code.copyTo(&compiledBody(t, compiled, 0));
|
||||||
@ -1635,7 +1846,7 @@ compileStub(Thread* t)
|
|||||||
Compiler c(t->m->system);
|
Compiler c(t->m->system);
|
||||||
c.compileStub(static_cast<MyThread*>(t));
|
c.compileStub(static_cast<MyThread*>(t));
|
||||||
|
|
||||||
object stub = makeCompiled(t, 0, c.code.length(), false);
|
object stub = makeCompiled(t, c.code.length(), false);
|
||||||
c.code.copyTo(&compiledBody(t, stub, 0));
|
c.code.copyTo(&compiledBody(t, stub, 0));
|
||||||
|
|
||||||
return stub;
|
return stub;
|
||||||
@ -1811,10 +2022,14 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
|||||||
unsigned returnCode = methodReturnCode(t, method);
|
unsigned returnCode = methodReturnCode(t, method);
|
||||||
unsigned returnType = fieldType(t, returnCode);
|
unsigned returnType = fieldType(t, returnCode);
|
||||||
|
|
||||||
|
void* frame = t->frame;
|
||||||
|
|
||||||
uint64_t result = vmInvoke
|
uint64_t result = vmInvoke
|
||||||
(&compiledBody(t, methodCompiled(t, method), 0), arguments->array,
|
(&compiledBody(t, methodCompiled(t, method), 0), arguments->array,
|
||||||
arguments->position * BytesPerWord, returnType);
|
arguments->position * BytesPerWord, returnType);
|
||||||
|
|
||||||
|
t->frame = frame;
|
||||||
|
|
||||||
object r;
|
object r;
|
||||||
switch (returnCode) {
|
switch (returnCode) {
|
||||||
case ByteField:
|
case ByteField:
|
||||||
|
@ -1760,16 +1760,7 @@ interpret(Thread* t)
|
|||||||
object class_ = methodClass(t, frameMethod(t, frame));
|
object class_ = methodClass(t, frameMethod(t, frame));
|
||||||
if (isSpecialMethod(t, method, class_)) {
|
if (isSpecialMethod(t, method, class_)) {
|
||||||
class_ = classSuper(t, class_);
|
class_ = classSuper(t, class_);
|
||||||
|
|
||||||
if (classVirtualTable(t, class_) == 0) {
|
|
||||||
PROTECT(t, method);
|
|
||||||
PROTECT(t, class_);
|
|
||||||
|
|
||||||
resolveClass(t, className(t, class_));
|
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||||
}
|
|
||||||
|
|
||||||
code = findMethod(t, method, class_);
|
code = findMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
@ -1804,16 +1795,7 @@ interpret(Thread* t)
|
|||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
if (LIKELY(peekObject(t, sp - parameterFootprint))) {
|
||||||
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
object class_ = objectClass(t, peekObject(t, sp - parameterFootprint));
|
||||||
|
|
||||||
if (classVirtualTable(t, class_) == 0) {
|
|
||||||
PROTECT(t, method);
|
|
||||||
PROTECT(t, class_);
|
|
||||||
|
|
||||||
resolveClass(t, className(t, class_));
|
|
||||||
if (UNLIKELY(exception)) goto throw_;
|
|
||||||
|
|
||||||
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
if (UNLIKELY(classInit(t, class_, 3))) goto invoke;
|
||||||
}
|
|
||||||
|
|
||||||
code = findMethod(t, method, class_);
|
code = findMethod(t, method, class_);
|
||||||
goto invoke;
|
goto invoke;
|
||||||
@ -2494,10 +2476,7 @@ interpret(Thread* t)
|
|||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case sipush: {
|
case sipush: {
|
||||||
uint8_t byte1 = codeBody(t, code, ip++);
|
pushInt(t, static_cast<int16_t>(codeReadInt16(t, code, ip)));
|
||||||
uint8_t byte2 = codeBody(t, code, ip++);
|
|
||||||
|
|
||||||
pushInt(t, static_cast<int16_t>((byte1 << 8) | byte2));
|
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case swap: {
|
case swap: {
|
||||||
@ -2766,11 +2745,6 @@ invoke(Thread* t, object method)
|
|||||||
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) {
|
||||||
method = findInterfaceMethod(t, method, class_);
|
method = findInterfaceMethod(t, method, class_);
|
||||||
} else {
|
} else {
|
||||||
if (classVirtualTable(t, class_) == 0) {
|
|
||||||
resolveClass(t, className(t, class_));
|
|
||||||
if (UNLIKELY(t->exception)) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
method = findMethod(t, method, class_);
|
method = findMethod(t, method, class_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1451,8 +1451,6 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
|
|
||||||
m->bootstrapClassMap = makeHashMap(this, 0, 0);
|
m->bootstrapClassMap = makeHashMap(this, 0, 0);
|
||||||
|
|
||||||
#include "type-java-initializations.cpp"
|
|
||||||
|
|
||||||
object loaderMap = makeHashMap(this, 0, 0);
|
object loaderMap = makeHashMap(this, 0, 0);
|
||||||
set(t, systemClassLoaderMap(t, m->loader), loaderMap);
|
set(t, systemClassLoaderMap(t, m->loader), loaderMap);
|
||||||
|
|
||||||
@ -1462,6 +1460,17 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
m->jniInterfaceTable = makeVector(this, 0, 0, false);
|
m->jniInterfaceTable = makeVector(this, 0, 0, false);
|
||||||
|
|
||||||
m->localThread->set(this);
|
m->localThread->set(this);
|
||||||
|
|
||||||
|
#include "type-java-initializations.cpp"
|
||||||
|
|
||||||
|
enter(t, Thread::ActiveState);
|
||||||
|
|
||||||
|
resolveClass
|
||||||
|
(t, className(t, arrayBody(t, m->types, Machine::ClassType)));
|
||||||
|
resolveClass
|
||||||
|
(t, className(t, arrayBody(t, m->types, Machine::IntArrayType)));
|
||||||
|
resolveClass
|
||||||
|
(t, className(t, arrayBody(t, m->types, Machine::ByteArrayType)));
|
||||||
} else {
|
} else {
|
||||||
parent->child = this;
|
parent->child = this;
|
||||||
}
|
}
|
||||||
@ -1472,6 +1481,8 @@ Thread::Thread(Machine* m, object javaThread, Thread* parent):
|
|||||||
this->javaThread = makeThread
|
this->javaThread = makeThread
|
||||||
(this, reinterpret_cast<int64_t>(this), 0, 0, 0, 0, m->loader);
|
(this, reinterpret_cast<int64_t>(this), 0, 0, 0, 0, m->loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enter(this, Thread::IdleState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -56,6 +56,7 @@ const unsigned WeakReferenceFlag = 1 << 1;
|
|||||||
const unsigned NeedInitFlag = 1 << 2;
|
const unsigned NeedInitFlag = 1 << 2;
|
||||||
const unsigned InitFlag = 1 << 3;
|
const unsigned InitFlag = 1 << 3;
|
||||||
const unsigned PrimitiveFlag = 1 << 4;
|
const unsigned PrimitiveFlag = 1 << 4;
|
||||||
|
const unsigned BootstrapFlag = 1 << 5;
|
||||||
|
|
||||||
// method flags:
|
// method flags:
|
||||||
const unsigned ClassInitFlag = 1 << 0;
|
const unsigned ClassInitFlag = 1 << 0;
|
||||||
|
@ -40,6 +40,12 @@ equal(const char* a, const char* b)
|
|||||||
return strcmp(a, b) == 0;
|
return strcmp(a, b) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
startsWith(const char* a, const char* b)
|
||||||
|
{
|
||||||
|
return strncmp(a, b, strlen(a)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
class Object {
|
class Object {
|
||||||
public:
|
public:
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -1354,6 +1360,22 @@ writeConstructors(Output* out, Object* declarations)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeJavaName(o)
|
||||||
|
and not equal("class", typeName(o))
|
||||||
|
and startsWith("java/", typeJavaName(o)))
|
||||||
|
{
|
||||||
|
out->write(" object class__ ");
|
||||||
|
out->write("= arrayBody(t, t->m->types, Machine::");
|
||||||
|
out->write(capitalize(typeName(o)));
|
||||||
|
out->write("Type);\n");
|
||||||
|
|
||||||
|
out->write(" if (classVmFlags(t, class__) & BootstrapFlag) {\n");
|
||||||
|
out->write(" classVmFlags(t, class__) &= ~BootstrapFlag;\n");
|
||||||
|
out->write(" resolveClass(t, className(t, class__));\n");
|
||||||
|
out->write(" assert(t, t->exception == 0);\n");
|
||||||
|
out->write(" }\n");
|
||||||
|
}
|
||||||
|
|
||||||
out->write(" object o = allocate(t, ");
|
out->write(" object o = allocate(t, ");
|
||||||
writeOffset(out, typeOffset(o), true);
|
writeOffset(out, typeOffset(o), true);
|
||||||
out->write(");\n");
|
out->write(");\n");
|
||||||
@ -1522,7 +1544,18 @@ writeInitialization(Output* out, Object* type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out->write(" object class_ = makeClass");
|
out->write(" object class_ = makeClass");
|
||||||
out->write("(t, 0, 0, 0, ");
|
out->write("(t, 0, ");
|
||||||
|
|
||||||
|
if (typeJavaName(type)
|
||||||
|
and not equal("class", typeName(type))
|
||||||
|
and startsWith("java/", typeJavaName(type)))
|
||||||
|
{
|
||||||
|
out->write("BootstrapFlag");
|
||||||
|
} else {
|
||||||
|
out->write("0");
|
||||||
|
}
|
||||||
|
|
||||||
|
out->write(", 0, ");
|
||||||
out->write(typeFixedSize(type));
|
out->write(typeFixedSize(type));
|
||||||
out->write(", ");
|
out->write(", ");
|
||||||
out->write(typeArrayElementSize(type));
|
out->write(typeArrayElementSize(type));
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
(object compiled))
|
(object compiled))
|
||||||
|
|
||||||
(type compiled
|
(type compiled
|
||||||
(nogc object method)
|
|
||||||
(array uint8_t body))
|
(array uint8_t body))
|
||||||
|
|
||||||
(type nativeMethodData
|
(type nativeMethodData
|
||||||
|
Loading…
Reference in New Issue
Block a user