mirror of
https://github.com/corda/corda.git
synced 2025-01-17 02:09:50 +00:00
snapshot
This commit is contained in:
parent
ba03aa88df
commit
404d996c1e
@ -11,7 +11,7 @@ public class Method<T> extends AccessibleObject implements Member {
|
||||
private byte[] spec;
|
||||
private Class<T> class_;
|
||||
private Object code;
|
||||
private Object compiled;
|
||||
private long compiled;
|
||||
|
||||
private Method() { }
|
||||
|
||||
|
13
makefile
13
makefile
@ -71,7 +71,7 @@ cflags += -g3 -O3 -DNDEBUG
|
||||
endif
|
||||
|
||||
cpp-objects = $(foreach x,$(1),$(patsubst $(2)/%.cpp,$(bld)/%.o,$(x)))
|
||||
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(bld)/%.o,$(x)))
|
||||
asm-objects = $(foreach x,$(1),$(patsubst $(2)/%.S,$(bld)/%-asm.o,$(x)))
|
||||
java-classes = $(foreach x,$(1),$(patsubst $(2)/%.java,$(cls)/%.class,$(x)))
|
||||
|
||||
stdcpp-sources = $(src)/stdc++.cpp
|
||||
@ -112,14 +112,7 @@ interpreter-sources = \
|
||||
$(src)/jnienv.cpp \
|
||||
$(src)/main.cpp
|
||||
|
||||
interpreter-asm-sources = $(src)/vmInvoke.S
|
||||
|
||||
ifeq ($(arch),i386)
|
||||
interpreter-asm-sources += $(src)/cdecl.S
|
||||
endif
|
||||
ifeq ($(arch),x86_64)
|
||||
interpreter-asm-sources += $(src)/amd64.S
|
||||
endif
|
||||
interpreter-asm-sources = $(src)/compile.S $(src)/system.S
|
||||
|
||||
interpreter-cpp-objects = \
|
||||
$(call cpp-objects,$(interpreter-sources),$(src))
|
||||
@ -219,7 +212,7 @@ $(stdcpp-objects): $(bld)/%.o: $(src)/%.cpp
|
||||
$(interpreter-cpp-objects): $(bld)/%.o: $(src)/%.cpp $(interpreter-depends)
|
||||
$(compile-object)
|
||||
|
||||
$(interpreter-asm-objects): $(bld)/%.o: $(src)/%.S
|
||||
$(interpreter-asm-objects): $(bld)/%-asm.o: $(src)/%.S
|
||||
$(compile-object)
|
||||
|
||||
$(generator-objects): $(bld)/%.o: $(src)/%.cpp
|
||||
|
86
src/cdecl.S
86
src/cdecl.S
@ -1,86 +0,0 @@
|
||||
#include "types.h"
|
||||
|
||||
.text
|
||||
|
||||
#ifdef __APPLE__
|
||||
.globl _cdeclCall
|
||||
_cdeclCall:
|
||||
#else
|
||||
.globl cdeclCall
|
||||
cdeclCall:
|
||||
#endif
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
// 8(%ebp): function
|
||||
// 12(%ebp): stack
|
||||
// 16(%ebp): stackSize
|
||||
// 20(%ebp): returnType
|
||||
|
||||
// reserve space for arguments
|
||||
movl 16(%ebp),%ecx
|
||||
|
||||
#ifdef __APPLE__
|
||||
// align to a 16 byte boundary on Darwin
|
||||
addl $15,%ecx
|
||||
andl $0xFFFFFFF0,%ecx
|
||||
addl $8,%ecx
|
||||
#endif
|
||||
|
||||
subl %ecx,%esp
|
||||
|
||||
// copy arguments into place
|
||||
movl $0,%ecx
|
||||
jmp test
|
||||
|
||||
loop:
|
||||
movl %ecx,%eax
|
||||
movl %ecx,%edx
|
||||
addl %esp,%edx
|
||||
addl 12(%ebp),%eax
|
||||
movl (%eax),%eax
|
||||
movl %eax,(%edx)
|
||||
addl $4,%ecx
|
||||
|
||||
test:
|
||||
cmpl 16(%ebp),%ecx
|
||||
jb loop
|
||||
|
||||
// call function
|
||||
call *8(%ebp)
|
||||
|
||||
// handle return value based on expected type
|
||||
movl 20(%ebp),%ecx
|
||||
|
||||
void:
|
||||
cmpl $VOID_TYPE,%ecx
|
||||
jne int64
|
||||
jmp exit
|
||||
|
||||
int64:
|
||||
cmpl $INT64_TYPE,%ecx
|
||||
jne float
|
||||
jmp exit
|
||||
|
||||
float:
|
||||
cmpl $FLOAT_TYPE,%ecx
|
||||
jne double
|
||||
fstps 8(%ebp)
|
||||
movl 8(%ebp),%eax
|
||||
jmp int32
|
||||
|
||||
double:
|
||||
cmpl $DOUBLE_TYPE,%ecx
|
||||
jne int32
|
||||
fstpl 8(%ebp)
|
||||
movl 8(%ebp),%eax
|
||||
movl 12(%ebp),%edx
|
||||
jmp exit
|
||||
|
||||
int32:
|
||||
movl $0,%edx
|
||||
|
||||
exit:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
@ -2,10 +2,10 @@
|
||||
|
||||
.text
|
||||
|
||||
.globl vmInvoke
|
||||
vmInvoke:
|
||||
#ifdef __x86_64__
|
||||
|
||||
.globl vmInvoke
|
||||
vmInvoke:
|
||||
pushq %rbp
|
||||
movq %rsp,%rbp
|
||||
|
||||
@ -40,9 +40,19 @@ test:
|
||||
movq %rbp,%rsp
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
// %rdi: address
|
||||
// %rsi: base
|
||||
movq %rsi,%rsp
|
||||
popq %rbp
|
||||
jmp *(%rdi)
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
.globl vmInvoke
|
||||
vmInvoke:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
@ -96,7 +106,16 @@ exit:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
|
||||
.globl vmJump
|
||||
vmJump:
|
||||
// 8(%ebp): address
|
||||
// 12(%ebp): base
|
||||
movq 8(%ebp),%eax
|
||||
movq 12(%ebp),%rsp
|
||||
popq %rbp
|
||||
jmp *(%eax)
|
||||
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
429
src/compile.cpp
429
src/compile.cpp
@ -12,15 +12,15 @@ vmInvoke(void* function, void* stack, unsigned stackSize,
|
||||
unsigned returnType);
|
||||
|
||||
extern "C" void NO_RETURN
|
||||
vmJump(void* address);
|
||||
vmJump(void* address, void* base);
|
||||
|
||||
namespace {
|
||||
|
||||
const bool Verbose = false;
|
||||
const bool Verbose = true;
|
||||
|
||||
const unsigned FrameThread = BytesPerWord * 2;
|
||||
const unsigned FrameMethod = FrameThread + BytesPerWord;
|
||||
const unsigned FrameNext = FrameNext + BytesPerWord;
|
||||
const unsigned FrameNext = FrameMethod + BytesPerWord;
|
||||
const unsigned FrameFootprint = BytesPerWord * 3;
|
||||
|
||||
class ArgumentList;
|
||||
@ -121,50 +121,6 @@ class Buffer {
|
||||
unsigned minimumCapacity;
|
||||
};
|
||||
|
||||
class Code {
|
||||
public:
|
||||
Code(Buffer* code, Buffer* lineNumbers, Buffer* exceptionHandlers):
|
||||
codeLength_(code->length()),
|
||||
lineNumberTableLength_(lineNumbers->length()),
|
||||
exceptionHandlerTableLength_(exceptionHandlers->length())
|
||||
{
|
||||
code->copyTo(body);
|
||||
lineNumbers->copyTo(lineNumber(0));
|
||||
exceptionHandlers->copyTo(exceptionHandler(0));
|
||||
}
|
||||
|
||||
uint8_t* code() {
|
||||
return body;
|
||||
}
|
||||
|
||||
unsigned codeLength() {
|
||||
return codeLength_;
|
||||
}
|
||||
|
||||
NativeLineNumber* lineNumber(unsigned index) {
|
||||
return reinterpret_cast<NativeLineNumber*>
|
||||
(body + pad(codeLength_)) + index;
|
||||
}
|
||||
|
||||
unsigned lineNumberTableLength() {
|
||||
return lineNumberTableLength_ / sizeof(NativeLineNumber);
|
||||
}
|
||||
|
||||
NativeExceptionHandler* exceptionHandler(unsigned index) {
|
||||
return reinterpret_cast<NativeExceptionHandler*>
|
||||
(body + pad(codeLength_) + pad(lineNumberTableLength_)) + index;
|
||||
}
|
||||
|
||||
unsigned exceptionHandlerTableLength() {
|
||||
return exceptionHandlerTableLength_ / sizeof(NativeExceptionHandler);
|
||||
}
|
||||
|
||||
uint32_t codeLength_;
|
||||
uint32_t lineNumberTableLength_;
|
||||
uint32_t exceptionHandlerTableLength_;
|
||||
uint8_t body[0];
|
||||
};
|
||||
|
||||
class MyThread: public Thread {
|
||||
public:
|
||||
MyThread(Machine* m, object javaThread, vm::Thread* parent):
|
||||
@ -179,22 +135,22 @@ class MyThread: public Thread {
|
||||
Reference* reference;
|
||||
};
|
||||
|
||||
inline bool
|
||||
frameValid(void* frame)
|
||||
{
|
||||
return frame != 0;
|
||||
}
|
||||
|
||||
inline void*
|
||||
frameBase(void* frame)
|
||||
{
|
||||
return static_cast<void**>(frame)[- (FrameFootprint / BytesPerWord) - 1];
|
||||
return *static_cast<void**>(frame);
|
||||
}
|
||||
|
||||
inline bool
|
||||
frameValid(void* frame)
|
||||
{
|
||||
return frameBase(frame) != 0;
|
||||
}
|
||||
|
||||
inline void*
|
||||
frameNext(void* frame)
|
||||
{
|
||||
return static_cast<void**>(frameBase(frame))[FrameNext / BytesPerWord];
|
||||
return static_cast<void**>(frameBase(frame))[FrameNext / BytesPerWord] ;
|
||||
}
|
||||
|
||||
inline object
|
||||
@ -206,7 +162,7 @@ frameMethod(void* frame)
|
||||
inline void*
|
||||
frameAddress(void* frame)
|
||||
{
|
||||
return static_cast<void**>(frame)[- (FrameFootprint / BytesPerWord)];
|
||||
return static_cast<void**>(frame)[1];
|
||||
}
|
||||
|
||||
inline void*
|
||||
@ -215,21 +171,71 @@ frameReturnAddress(void* frame)
|
||||
return static_cast<void**>(frameBase(frame))[1];
|
||||
}
|
||||
|
||||
inline uint8_t*
|
||||
compiledCode(Compiled* code)
|
||||
{
|
||||
return compiledBody(code);
|
||||
}
|
||||
|
||||
inline NativeLineNumber*
|
||||
compiledLineNumber(Thread* t, Compiled* code, unsigned index)
|
||||
{
|
||||
assert(t, index < compiledLineNumberTableLength(code));
|
||||
return reinterpret_cast<NativeLineNumber*>
|
||||
(compiledBody(code) + pad(compiledCodeLength(code)));
|
||||
}
|
||||
|
||||
inline NativeExceptionHandler*
|
||||
compiledExceptionHandler(Thread* t, Compiled* code, unsigned index)
|
||||
{
|
||||
assert(t, index < compiledExceptionHandlerTableLength(code));
|
||||
return reinterpret_cast<NativeExceptionHandler*>
|
||||
(compiledBody(code) + pad(compiledCodeLength(code))
|
||||
+ pad(compiledLineNumberTableLength(code)));
|
||||
}
|
||||
|
||||
inline Compiled*
|
||||
makeCompiled(Thread* t, Buffer* code, Buffer* lineNumbers,
|
||||
Buffer* exceptionHandlers)
|
||||
{
|
||||
Compiled* c = static_cast<Compiled*>
|
||||
(t->m->system->allocate(sizeof(Compiled)
|
||||
+ pad(code->length())
|
||||
+ pad(lineNumbers->length())
|
||||
+ pad(exceptionHandlers->length())));
|
||||
|
||||
compiledCodeLength(c) = code->length();
|
||||
compiledLineNumberTableLength(c) = lineNumbers->length();
|
||||
compiledExceptionHandlerTableLength(c) = exceptionHandlers->length();
|
||||
|
||||
if (code->length()) {
|
||||
code->copyTo(compiledCode(c));
|
||||
}
|
||||
if (lineNumbers->length()) {
|
||||
lineNumbers->copyTo(compiledLineNumber(t, c, 0));
|
||||
}
|
||||
if (exceptionHandlers->length()) {
|
||||
exceptionHandlers->copyTo(compiledExceptionHandler(t, c, 0));
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
addressOffset(Thread* t, object method, void* address)
|
||||
{
|
||||
Code* code = static_cast<Code*>(methodCompiled(t, method));
|
||||
return static_cast<uint8_t*>(address) - code->code();
|
||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||
return static_cast<uint8_t*>(address) - compiledCode(code);
|
||||
}
|
||||
|
||||
NativeExceptionHandler*
|
||||
findExceptionHandler(Thread* t, void* frame)
|
||||
{
|
||||
object method = frameMethod(frame);
|
||||
Code* code = static_cast<Code*>(methodCompiled(t, method));
|
||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||
|
||||
for (unsigned i = 0; i < code->exceptionHandlerTableLength(); ++i) {
|
||||
NativeExceptionHandler* handler = code->exceptionHandler(i);
|
||||
for (unsigned i = 0; i < compiledExceptionHandlerTableLength(code); ++i) {
|
||||
NativeExceptionHandler* handler = compiledExceptionHandler(t, code, i);
|
||||
unsigned offset = addressOffset(t, method, frameAddress(frame));
|
||||
|
||||
if (offset - 1 >= nativeExceptionHandlerStart(handler)
|
||||
@ -262,13 +268,15 @@ unwind(MyThread* t)
|
||||
or methodFlags(t, frameMethod(next)) & ACC_NATIVE)
|
||||
{
|
||||
t->frame = next;
|
||||
vmJump(frameReturnAddress(frame));
|
||||
vmJump(frameReturnAddress(frame), frameBase(frame));
|
||||
} else if ((methodFlags(t, frameMethod(frame)) & ACC_NATIVE) == 0) {
|
||||
NativeExceptionHandler* eh = findExceptionHandler(t, frame);
|
||||
if (eh) {
|
||||
Code* code = static_cast<Code*>(methodCompiled(t, frameMethod(frame)));
|
||||
Compiled* code = reinterpret_cast<Compiled*>
|
||||
(methodCompiled(t, frameMethod(frame)));
|
||||
t->frame = frame;
|
||||
vmJump(code->code() + nativeExceptionHandlerIp(eh));
|
||||
vmJump(compiledCode(code) + nativeExceptionHandlerIp(eh),
|
||||
frameBase(frame));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,9 +294,9 @@ void NO_RETURN
|
||||
throw_(MyThread* t, object o)
|
||||
{
|
||||
if (o) {
|
||||
t->exception = makeNullPointerException(t);
|
||||
} else {
|
||||
t->exception = o;
|
||||
} else {
|
||||
t->exception = makeNullPointerException(t);
|
||||
}
|
||||
unwind(t);
|
||||
}
|
||||
@ -652,6 +660,11 @@ class Assembler {
|
||||
code.appendAddress(v);
|
||||
}
|
||||
|
||||
void lea(Register src, int32_t srcOffset, Register dst) {
|
||||
rex();
|
||||
offsetInstruction(0x8d, 0, 0x40, 0x80, dst, src, srcOffset);
|
||||
}
|
||||
|
||||
void nop() {
|
||||
code.append(0x90);
|
||||
}
|
||||
@ -949,17 +962,15 @@ parameterOffset(unsigned index)
|
||||
|
||||
class Compiler: public Assembler {
|
||||
public:
|
||||
Compiler(Thread* t):
|
||||
Assembler(s),
|
||||
Compiler(MyThread* t):
|
||||
Assembler(t->m->system),
|
||||
t(t),
|
||||
threadFrameOffset(reinterpret_cast<uintptr_t>(&(t->frame))
|
||||
- reinterpret_cast<uintptr_t>(t))
|
||||
poolRegisterClobbered(true),
|
||||
javaIPs(s, 1024),
|
||||
machineIPs(s, 1024),
|
||||
lineNumbers(s, 256),
|
||||
exceptionHandlers(s, 256),
|
||||
pool(s, 256)
|
||||
javaIPs(t->m->system, 1024),
|
||||
machineIPs(t->m->system, 1024),
|
||||
lineNumbers(t->m->system, 256),
|
||||
exceptionHandlers(t->m->system, 256),
|
||||
pool(t->m->system, 256)
|
||||
{ }
|
||||
|
||||
void pushReturnValue(unsigned code) {
|
||||
@ -992,19 +1003,31 @@ class Compiler: public Assembler {
|
||||
unsigned footprint = FrameFootprint
|
||||
+ (methodParameterFootprint(t, target) * BytesPerWord);
|
||||
|
||||
Code* code = static_cast<Code*>(methodCompiled(t, target));
|
||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, target));
|
||||
|
||||
push(rsp);
|
||||
push(rbp);
|
||||
push(poolRegister(), poolReference(target));
|
||||
push(rbp, FrameThread);
|
||||
|
||||
callAlignedAddress(code->code());
|
||||
callAlignedAddress(compiledCode(code));
|
||||
|
||||
add(footprint, rsp); // pop arguments
|
||||
|
||||
pushReturnValue(methodReturnCode(t, target));
|
||||
}
|
||||
|
||||
void compileCall2(void* function, unsigned argCount) {
|
||||
mov(rbp, FrameThread, rax);
|
||||
lea(rsp, -(BytesPerWord * 2), rcx);
|
||||
mov(rcx, rax, threadFrameOffset()); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * argCount, rsp);
|
||||
}
|
||||
}
|
||||
|
||||
void compileCall(void* function, object arg1) {
|
||||
if (BytesPerWord == 4) {
|
||||
push(poolRegister(), poolReference(arg1));
|
||||
@ -1014,14 +1037,7 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 2, rsp);
|
||||
}
|
||||
compileCall2(function, 2);
|
||||
}
|
||||
|
||||
void compileCall(void* function, Register arg1) {
|
||||
@ -1033,14 +1049,7 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 2, rsp);
|
||||
}
|
||||
compileCall2(function, 2);
|
||||
}
|
||||
|
||||
void compileCall(void* function, object arg1, Register arg2) {
|
||||
@ -1054,38 +1063,21 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 3, rsp);
|
||||
}
|
||||
compileCall2(function, 3);
|
||||
}
|
||||
|
||||
void compileCall(void* function, void* arg1, Register arg2) {
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, frameOffset); // set thread frame to current
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
push(arg2);
|
||||
pushAddress(arg1);
|
||||
pushAddress(reinterpret_cast<uintptr_t>(arg1));
|
||||
push(rbp, FrameThread);
|
||||
} else {
|
||||
mov(arg2, rdx);
|
||||
mov(arg1, rsi);
|
||||
mov(reinterpret_cast<uintptr_t>(arg1), rsi);
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 3, rsp);
|
||||
}
|
||||
compileCall2(function, 3);
|
||||
}
|
||||
|
||||
void compileCall(void* function, Register arg1, Register arg2) {
|
||||
@ -1099,17 +1091,10 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
callAddress(function);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
add(BytesPerWord * 3, rsp);
|
||||
}
|
||||
compileCall2(function, 3);
|
||||
}
|
||||
|
||||
void compile(MyThread* t, object method) {
|
||||
Compiled* compile(object method) {
|
||||
PROTECT(t, method);
|
||||
|
||||
object code = methodCode(t, method);
|
||||
@ -1133,7 +1118,7 @@ class Compiler: public Assembler {
|
||||
if (lnt and lineNumberTableLength(t, lnt)) {
|
||||
lineNumberIndex = 0;
|
||||
} else {
|
||||
lineNumberIndex = 0;
|
||||
lineNumberIndex = -1;
|
||||
}
|
||||
|
||||
for (unsigned ip = 0; ip < codeLength(t, code);) {
|
||||
@ -1144,11 +1129,15 @@ class Compiler: public Assembler {
|
||||
object lnt = codeLineNumberTable(t, code);
|
||||
LineNumber* ln = lineNumberTableBody(t, lnt, lineNumberIndex);
|
||||
|
||||
if (lineNumberIp(t, ln) == ip) {
|
||||
if (lineNumberIp(ln) == ip) {
|
||||
lineNumbers.append4(this->code.length());
|
||||
lineNumbers.append4(lineNumberLine(t, ln));
|
||||
if (lineNumberIndex < lineNumberTableLength(t, lnt)) {
|
||||
lineNumbers.append4(lineNumberLine(ln));
|
||||
if (static_cast<unsigned>(lineNumberIndex) + 1
|
||||
< lineNumberTableLength(t, lnt))
|
||||
{
|
||||
++ lineNumberIndex;
|
||||
} else {
|
||||
lineNumberIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1221,7 +1210,7 @@ class Compiler: public Assembler {
|
||||
|
||||
outOfBounds.mark();
|
||||
compileCall
|
||||
(throwNew,
|
||||
(reinterpret_cast<void*>(throwNew),
|
||||
arrayBody
|
||||
(t, t->m->types, Machine::ArrayIndexOutOfBoundsExceptionType));
|
||||
|
||||
@ -1289,7 +1278,7 @@ class Compiler: public Assembler {
|
||||
|
||||
outOfBounds.mark();
|
||||
compileCall
|
||||
(throwNew,
|
||||
(reinterpret_cast<void*>(throwNew),
|
||||
arrayBody
|
||||
(t, t->m->types, Machine::ArrayIndexOutOfBoundsExceptionType));
|
||||
|
||||
@ -1334,7 +1323,7 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
Label nonnegative(this);
|
||||
|
||||
@ -1343,11 +1332,12 @@ class Compiler: public Assembler {
|
||||
jle(nonnegative);
|
||||
|
||||
compileCall
|
||||
(throwNew,
|
||||
(reinterpret_cast<void*>(throwNew),
|
||||
arrayBody(t, t->m->types, Machine::NegativeArraySizeExceptionType));
|
||||
|
||||
nonnegative.mark();
|
||||
compileCall(makeBlankObjectArray, class_, rax);
|
||||
compileCall(reinterpret_cast<void*>(makeBlankObjectArray),
|
||||
class_, rax);
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
@ -1397,7 +1387,7 @@ class Compiler: public Assembler {
|
||||
|
||||
case athrow:
|
||||
pop(rax);
|
||||
compileCall(throw_, rax);
|
||||
compileCall(reinterpret_cast<void*>(throw_), rax);
|
||||
break;
|
||||
|
||||
case bipush: {
|
||||
@ -1408,7 +1398,7 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
Label next(this);
|
||||
|
||||
@ -1421,12 +1411,12 @@ class Compiler: public Assembler {
|
||||
cmp(rcx, rax);
|
||||
je(next);
|
||||
|
||||
compileCall(isAssignableFrom, rcx, rax);
|
||||
compileCall(reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
||||
cmp(0, rax);
|
||||
jne(next);
|
||||
|
||||
compileCall
|
||||
(throwNew,
|
||||
(reinterpret_cast<void*>(throwNew),
|
||||
arrayBody(t, t->m->types, Machine::ClassCastExceptionType));
|
||||
|
||||
next.mark();
|
||||
@ -1440,7 +1430,7 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
pop(rax);
|
||||
|
||||
@ -1485,11 +1475,11 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
PROTECT(t, field);
|
||||
|
||||
initClass(t, fieldClass(t, field));
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
object table = classStaticTable(t, fieldClass(t, field));
|
||||
|
||||
@ -1725,7 +1715,7 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
Label call(this);
|
||||
Label zero(this);
|
||||
@ -1744,7 +1734,7 @@ class Compiler: public Assembler {
|
||||
jmp(next);
|
||||
|
||||
call.mark();
|
||||
compileCall(isAssignableFrom, rcx, rax);
|
||||
compileCall(reinterpret_cast<void*>(isAssignableFrom), rcx, rax);
|
||||
push(rax);
|
||||
jmp(next);
|
||||
|
||||
@ -1758,34 +1748,34 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
object class_ = methodClass(t, target);
|
||||
if (isSpecialMethod(t, target, class_)) {
|
||||
target = findMethod(t, target, classSuper(t, class_));
|
||||
}
|
||||
|
||||
compileDirectInvoke(t, target);
|
||||
compileDirectInvoke(target);
|
||||
} break;
|
||||
|
||||
case invokestatic: {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
PROTECT(t, target);
|
||||
|
||||
initClass(t, methodClass(t, target));
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
compileDirectInvoke(t, target);
|
||||
compileDirectInvoke(target);
|
||||
} break;
|
||||
|
||||
case invokevirtual: {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object target = resolveMethod(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
unsigned parameterFootprint
|
||||
= methodParameterFootprint(t, target) * BytesPerWord;
|
||||
@ -1812,7 +1802,7 @@ class Compiler: public Assembler {
|
||||
|
||||
add(footprint, rsp); // pop arguments
|
||||
|
||||
pushReturnValue(t, methodReturnCode(t, target));
|
||||
pushReturnValue(methodReturnCode(t, target));
|
||||
} break;
|
||||
|
||||
case isub:
|
||||
@ -1857,16 +1847,16 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object class_ = resolveClass(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
PROTECT(t, class_);
|
||||
|
||||
initClass(t, class_);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
if (classVmFlags(t, class_) & WeakReferenceFlag) {
|
||||
compileCall(makeNewWeakReference, class_);
|
||||
compileCall(reinterpret_cast<void*>(makeNewWeakReference), class_);
|
||||
} else {
|
||||
compileCall(makeNew, class_);
|
||||
compileCall(reinterpret_cast<void*>(makeNew), class_);
|
||||
}
|
||||
|
||||
push(rax);
|
||||
@ -1882,7 +1872,7 @@ class Compiler: public Assembler {
|
||||
jge(nonnegative);
|
||||
|
||||
compileCall
|
||||
(throwNew,
|
||||
(reinterpret_cast<void*>(throwNew),
|
||||
arrayBody
|
||||
(t, t->m->types, Machine::NegativeArraySizeExceptionType));
|
||||
|
||||
@ -1925,7 +1915,8 @@ class Compiler: public Assembler {
|
||||
default: abort(t);
|
||||
}
|
||||
|
||||
compileCall(makeBlankArray, constructor, rax);
|
||||
compileCall(reinterpret_cast<void*>(makeBlankArray),
|
||||
reinterpret_cast<void*>(constructor), rax);
|
||||
push(rax);
|
||||
} break;
|
||||
|
||||
@ -1937,7 +1928,7 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
case ByteField:
|
||||
@ -1989,10 +1980,10 @@ class Compiler: public Assembler {
|
||||
uint16_t index = codeReadInt16(t, code, ip);
|
||||
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
initClass(t, fieldClass(t, field));
|
||||
if (UNLIKELY(t->exception)) return;
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
object table = classStaticTable(t, fieldClass(t, field));
|
||||
|
||||
@ -2006,14 +1997,16 @@ class Compiler: public Assembler {
|
||||
case ShortField:
|
||||
case FloatField:
|
||||
case IntField: {
|
||||
compileCall(makeNew, arrayBody(t, t->m->types, Machine::IntType));
|
||||
compileCall(reinterpret_cast<void*>(makeNew),
|
||||
arrayBody(t, t->m->types, Machine::IntType));
|
||||
|
||||
pop4(rax, IntValue);
|
||||
} break;
|
||||
|
||||
case DoubleField:
|
||||
case LongField: {
|
||||
compileCall(makeNew, arrayBody(t, t->m->types, Machine::LongType));
|
||||
compileCall(reinterpret_cast<void*>(makeNew),
|
||||
arrayBody(t, t->m->types, Machine::LongType));
|
||||
|
||||
pop4(rax, LongValue);
|
||||
pop4(rax, LongValue + 4);
|
||||
@ -2051,7 +2044,6 @@ class Compiler: public Assembler {
|
||||
uint32_t machineIpForJavaIp(uint16_t javaIP) {
|
||||
unsigned bottom = 0;
|
||||
unsigned top = javaIPs.length() / 2;
|
||||
bool success = false;
|
||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||
unsigned middle = bottom + (span / 2);
|
||||
uint32_t k = javaIPs.get2(middle * 2);
|
||||
@ -2080,36 +2072,45 @@ class Compiler: public Assembler {
|
||||
PROTECT(t, code);
|
||||
|
||||
object eht = codeExceptionHandlerTable(t, code);
|
||||
PROTECT(t, eht);
|
||||
if (eht) {
|
||||
PROTECT(t, eht);
|
||||
|
||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||
|
||||
exceptionHandlers.append4(machineIpForJavaIp(exceptionHandlerStart(eh)));
|
||||
exceptionHandlers.append4(machineIpForJavaIp(exceptionHandlerEnd(eh)));
|
||||
exceptionHandlers.append4(machineIpForJavaIp(exceptionHandlerIp(eh)));
|
||||
exceptionHandlers.append4
|
||||
(machineIpForJavaIp(exceptionHandlerStart(eh)));
|
||||
|
||||
unsigned ct = exceptionHandlerCatchType(eh);
|
||||
object catchType;
|
||||
if (ct) {
|
||||
catchType = resolveClass
|
||||
(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1);
|
||||
} else {
|
||||
catchType = 0;
|
||||
exceptionHandlers.append4
|
||||
(machineIpForJavaIp(exceptionHandlerEnd(eh)));
|
||||
|
||||
exceptionHandlers.append4
|
||||
(machineIpForJavaIp(exceptionHandlerIp(eh)));
|
||||
|
||||
unsigned ct = exceptionHandlerCatchType(eh);
|
||||
object catchType;
|
||||
if (ct) {
|
||||
catchType = resolveClass
|
||||
(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1);
|
||||
} else {
|
||||
catchType = 0;
|
||||
}
|
||||
|
||||
exceptionHandlers.append4
|
||||
(catchType ? (poolReference(catchType) / BytesPerWord) - 1 : 0);
|
||||
}
|
||||
|
||||
exceptionHandlers.append4
|
||||
(catchType ? (poolReference(catchType) / BytesPerWord) - 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
Code* compileNativeInvoker() {
|
||||
unsigned threadFrameOffset() {
|
||||
return reinterpret_cast<uintptr_t>(&(t->frame))
|
||||
- reinterpret_cast<uintptr_t>(t);
|
||||
}
|
||||
|
||||
Compiled* compileNativeInvoker() {
|
||||
push(rbp);
|
||||
mov(rsp, rbp);
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
push(rbp, FrameMethod);
|
||||
push(rbp, FrameThread);
|
||||
@ -2118,6 +2119,9 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset()); // set thread frame to current
|
||||
|
||||
mov(reinterpret_cast<uintptr_t>(invokeNative), rax);
|
||||
call(rax);
|
||||
|
||||
@ -2132,13 +2136,10 @@ class Compiler: public Assembler {
|
||||
return finish();
|
||||
}
|
||||
|
||||
Code* compileStub() {
|
||||
Compiled* compileStub() {
|
||||
push(rbp);
|
||||
mov(rsp, rbp);
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset); // set thread frame to current
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
push(rbp, FrameMethod);
|
||||
push(rbp, FrameThread);
|
||||
@ -2147,6 +2148,9 @@ class Compiler: public Assembler {
|
||||
mov(rbp, FrameThread, rdi);
|
||||
}
|
||||
|
||||
mov(rbp, FrameThread, rax);
|
||||
mov(rbp, rax, threadFrameOffset()); // set thread frame to current
|
||||
|
||||
mov(reinterpret_cast<uintptr_t>(compileMethod), rax);
|
||||
call(rax);
|
||||
|
||||
@ -2166,19 +2170,14 @@ class Compiler: public Assembler {
|
||||
return finish();
|
||||
}
|
||||
|
||||
Code* finish() {
|
||||
unsigned footprint = pad(code.length())
|
||||
+ pad(lineNumbers.length())
|
||||
+ pad(exceptionHandlers.length());
|
||||
|
||||
return new (t->m->system->allocate(sizeof(Code) + footprint))
|
||||
Code(&code, &lineNumbers, &exceptionHandlers);
|
||||
Compiled* finish() {
|
||||
return makeCompiled(t, &code, &lineNumbers, &exceptionHandlers);
|
||||
}
|
||||
|
||||
object makePool() {
|
||||
if (pool.length()) {
|
||||
object array = makeArray(t, pool.length() / BytesPerWord, false);
|
||||
pool.copyTo(&arrayBody(t, array));
|
||||
pool.copyTo(&arrayBody(t, array, 0));
|
||||
return array;
|
||||
} else {
|
||||
return 0;
|
||||
@ -2195,7 +2194,7 @@ class Compiler: public Assembler {
|
||||
mov(rdi, MethodCode, rdi);
|
||||
poolRegisterClobbered = false;
|
||||
}
|
||||
pool.appendAddress(o);
|
||||
pool.appendAddress(reinterpret_cast<uintptr_t>(o));
|
||||
return pool.length() + BytesPerWord;
|
||||
}
|
||||
|
||||
@ -2212,7 +2211,6 @@ class Compiler: public Assembler {
|
||||
}
|
||||
|
||||
MyThread* t;
|
||||
unsigned threadFrameOffset;
|
||||
bool poolRegisterClobbered;
|
||||
Buffer javaIPs;
|
||||
Buffer machineIPs;
|
||||
@ -2224,12 +2222,16 @@ class Compiler: public Assembler {
|
||||
void
|
||||
compileMethod2(MyThread* t, object method)
|
||||
{
|
||||
if (methodCompiled(t, method) == t->m->processor->methodStub(t)) {
|
||||
if (reinterpret_cast<Compiled*>(methodCompiled(t, method))
|
||||
== t->m->processor->methodStub(t))
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
ACQUIRE(t, t->m->classLock);
|
||||
|
||||
if (methodCompiled(t, method) == t->m->processor->methodStub(t)) {
|
||||
if (reinterpret_cast<Compiled*>(methodCompiled(t, method))
|
||||
== t->m->processor->methodStub(t))
|
||||
{
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "compiling %s.%s\n",
|
||||
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||
@ -2237,17 +2239,17 @@ compileMethod2(MyThread* t, object method)
|
||||
}
|
||||
|
||||
Compiler c(t);
|
||||
Code* code = c.compile(method);
|
||||
Compiled* code = c.compile(method);
|
||||
|
||||
if (Verbose) {
|
||||
fprintf(stderr, "compiled %s.%s from %p to %p\n",
|
||||
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
|
||||
&byteArrayBody(t, methodName(t, method), 0),
|
||||
code->code(),
|
||||
code->code() + code->codeLength());
|
||||
compiledCode(code),
|
||||
compiledCode(code) + compiledCodeLength(code));
|
||||
}
|
||||
|
||||
set(t, methodCompiled(t, method), compiled);
|
||||
methodCompiled(t, method) = reinterpret_cast<uint64_t>(code);
|
||||
|
||||
object pool = c.makePool();
|
||||
set(t, methodCode(t, method), pool);
|
||||
@ -2259,7 +2261,7 @@ void
|
||||
updateCaller(MyThread* t, object method)
|
||||
{
|
||||
uintptr_t stub = reinterpret_cast<uintptr_t>
|
||||
(&compiledBody(t, t->m->processor->methodStub(t), 0));
|
||||
(compiledCode(static_cast<Compiled*>(t->m->processor->methodStub(t))));
|
||||
|
||||
Assembler a(t->m->system);
|
||||
a.mov(stub, rax);
|
||||
@ -2277,7 +2279,7 @@ updateCaller(MyThread* t, object method)
|
||||
% BytesPerWord == 0);
|
||||
|
||||
*reinterpret_cast<void**>(caller + offset)
|
||||
= &compiledBody(t, methodCompiled(t, method), 0);
|
||||
= compiledCode(reinterpret_cast<Compiled*>(methodCompiled(t, method)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2466,9 +2468,10 @@ invoke(Thread* thread, object method, ArgumentList* arguments)
|
||||
void* frame = t->frame;
|
||||
Reference* reference = t->reference;
|
||||
|
||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||
uint64_t result = vmInvoke
|
||||
(&compiledBody(t, methodCompiled(t, method), 0), arguments->array,
|
||||
arguments->position * BytesPerWord, returnType);
|
||||
(compiledCode(code), arguments->array, arguments->position * BytesPerWord,
|
||||
returnType);
|
||||
|
||||
while (t->reference != reference) {
|
||||
dispose(t, t->reference);
|
||||
@ -2616,31 +2619,33 @@ class MyProcessor: public Processor {
|
||||
virtual uintptr_t
|
||||
frameStart(Thread* vmt)
|
||||
{
|
||||
return static_cast<MyThread*>(vmt)->frame;
|
||||
return reinterpret_cast<uintptr_t>(static_cast<MyThread*>(vmt)->frame);
|
||||
}
|
||||
|
||||
virtual uintptr_t
|
||||
frameNext(Thread*, uintptr_t frame)
|
||||
{
|
||||
::frameNext(reinterpret_cast<void*>(frame));
|
||||
return reinterpret_cast<uintptr_t>
|
||||
(::frameNext(reinterpret_cast<void*>(frame)));
|
||||
}
|
||||
|
||||
virtual bool
|
||||
frameValid(Thread*, uintptr_t frame)
|
||||
{
|
||||
return ::frameValid(frame);
|
||||
return ::frameValid(reinterpret_cast<void*>(frame));
|
||||
}
|
||||
|
||||
virtual object
|
||||
frameMethod(Thread*, uintptr_t frame)
|
||||
{
|
||||
return ::frameMethod(frame);
|
||||
return ::frameMethod(reinterpret_cast<void*>(frame));
|
||||
}
|
||||
|
||||
virtual unsigned
|
||||
frameIp(Thread* t, uintptr_t frame)
|
||||
{
|
||||
return addressOffset(t, frameMethod(frame), frameAddress(frame));
|
||||
void* f = reinterpret_cast<void*>(frame);
|
||||
return addressOffset(t, ::frameMethod(f), ::frameAddress(f));
|
||||
}
|
||||
|
||||
virtual object*
|
||||
@ -2742,8 +2747,8 @@ class MyProcessor: public Processor {
|
||||
}
|
||||
|
||||
System* s;
|
||||
void* methodStub_;
|
||||
void* nativeInvoker_;
|
||||
Compiled* methodStub_;
|
||||
Compiled* nativeInvoker_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -2855,13 +2855,13 @@ class MyProcessor: public Processor {
|
||||
return new (s->allocate(sizeof(Thread))) Thread(m, javaThread, parent);
|
||||
}
|
||||
|
||||
virtual object
|
||||
virtual Compiled*
|
||||
methodStub(vm::Thread*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual object
|
||||
virtual Compiled*
|
||||
nativeInvoker(vm::Thread*)
|
||||
{
|
||||
return 0;
|
||||
|
@ -992,11 +992,11 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
unsigned parameterFootprint = t->m->processor->parameterFootprint
|
||||
(t, specString, flags & ACC_STATIC);
|
||||
|
||||
object compiled;
|
||||
Compiled* compiled;
|
||||
if (flags & ACC_NATIVE) {
|
||||
compiled = t->m->processor->nativeInvoker(t);
|
||||
compiled = static_cast<Compiled*>(t->m->processor->nativeInvoker(t));
|
||||
} else {
|
||||
compiled = t->m->processor->methodStub(t);
|
||||
compiled = static_cast<Compiled*>(t->m->processor->methodStub(t));
|
||||
}
|
||||
|
||||
object method = makeMethod(t,
|
||||
@ -1010,7 +1010,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
arrayBody(t, pool, spec - 1),
|
||||
class_,
|
||||
code,
|
||||
compiled);
|
||||
reinterpret_cast<uint64_t>(compiled));
|
||||
PROTECT(t, method);
|
||||
|
||||
if (flags & ACC_STATIC) {
|
||||
|
@ -14,10 +14,10 @@ class Processor {
|
||||
virtual Thread*
|
||||
makeThread(Machine* m, object javaThread, Thread* parent) = 0;
|
||||
|
||||
virtual object
|
||||
virtual void*
|
||||
methodStub(Thread* t) = 0;
|
||||
|
||||
virtual object
|
||||
virtual void*
|
||||
nativeInvoker(Thread* t) = 0;
|
||||
|
||||
virtual unsigned
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "types.h"
|
||||
|
||||
.text
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
.globl amd64Call
|
||||
|
||||
amd64Call:
|
||||
pushq %rbp
|
||||
|
||||
@ -100,3 +102,92 @@ exit:
|
||||
|
||||
popq %rbp
|
||||
ret
|
||||
|
||||
#elif defined __i386__
|
||||
|
||||
#ifdef __APPLE__
|
||||
.globl _cdeclCall
|
||||
_cdeclCall:
|
||||
#else
|
||||
.globl cdeclCall
|
||||
cdeclCall:
|
||||
#endif
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
// 8(%ebp): function
|
||||
// 12(%ebp): stack
|
||||
// 16(%ebp): stackSize
|
||||
// 20(%ebp): returnType
|
||||
|
||||
// reserve space for arguments
|
||||
movl 16(%ebp),%ecx
|
||||
|
||||
#ifdef __APPLE__
|
||||
// align to a 16 byte boundary on Darwin
|
||||
addl $15,%ecx
|
||||
andl $0xFFFFFFF0,%ecx
|
||||
addl $8,%ecx
|
||||
#endif
|
||||
|
||||
subl %ecx,%esp
|
||||
|
||||
// copy arguments into place
|
||||
movl $0,%ecx
|
||||
jmp test
|
||||
|
||||
loop:
|
||||
movl %ecx,%eax
|
||||
movl %ecx,%edx
|
||||
addl %esp,%edx
|
||||
addl 12(%ebp),%eax
|
||||
movl (%eax),%eax
|
||||
movl %eax,(%edx)
|
||||
addl $4,%ecx
|
||||
|
||||
test:
|
||||
cmpl 16(%ebp),%ecx
|
||||
jb loop
|
||||
|
||||
// call function
|
||||
call *8(%ebp)
|
||||
|
||||
// handle return value based on expected type
|
||||
movl 20(%ebp),%ecx
|
||||
|
||||
void:
|
||||
cmpl $VOID_TYPE,%ecx
|
||||
jne int64
|
||||
jmp exit
|
||||
|
||||
int64:
|
||||
cmpl $INT64_TYPE,%ecx
|
||||
jne float
|
||||
jmp exit
|
||||
|
||||
float:
|
||||
cmpl $FLOAT_TYPE,%ecx
|
||||
jne double
|
||||
fstps 8(%ebp)
|
||||
movl 8(%ebp),%eax
|
||||
jmp int32
|
||||
|
||||
double:
|
||||
cmpl $DOUBLE_TYPE,%ecx
|
||||
jne int32
|
||||
fstpl 8(%ebp)
|
||||
movl 8(%ebp),%eax
|
||||
movl 12(%ebp),%edx
|
||||
jmp exit
|
||||
|
||||
int32:
|
||||
movl $0,%edx
|
||||
|
||||
exit:
|
||||
movl %ebp,%esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
#else
|
||||
# error unsupported platform
|
||||
#endif
|
@ -14,7 +14,7 @@ inline unsigned
|
||||
pad(unsigned size, unsigned alignment)
|
||||
{
|
||||
unsigned n = alignment;
|
||||
while (n % size and n % sizeof(void*)) ++ n;
|
||||
while (size and n % size and n % sizeof(void*)) ++ n;
|
||||
return n - alignment;
|
||||
}
|
||||
|
||||
@ -46,6 +46,24 @@ startsWith(const char* a, const char* b)
|
||||
return strncmp(a, b, strlen(a)) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
endsWith(const char* a, const char* b)
|
||||
{
|
||||
unsigned al = strlen(a);
|
||||
unsigned bl = strlen(b);
|
||||
return (bl >= al) and strncmp(a, b + (bl - al), al) == 0;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
take(unsigned n, const char* c)
|
||||
{
|
||||
char* r = static_cast<char*>(malloc(n + 1));
|
||||
assert(r);
|
||||
memcpy(r, c, n);
|
||||
r[n] = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
class Object {
|
||||
public:
|
||||
typedef enum {
|
||||
@ -776,6 +794,8 @@ sizeOf(const char* type, Object* declarations)
|
||||
return sizeof(uint64_t);
|
||||
} else if (equal(type, "char")) {
|
||||
return sizeof(char);
|
||||
} else if (endsWith("[0]", type)) {
|
||||
return 0;
|
||||
} else if (namesPointer(type)) {
|
||||
return sizeof(void*);
|
||||
} else {
|
||||
@ -1051,12 +1071,19 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
}
|
||||
|
||||
out->write("inline ");
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
|
||||
if (endsWith("[0]", typeName)) {
|
||||
out->write(take(strlen(typeName) - 3, typeName));
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
}
|
||||
}
|
||||
|
||||
out->write("\n");
|
||||
writeAccessorName(out, member, true, unsafe);
|
||||
if (memberOwner(member)->type == Object::Pod) {
|
||||
@ -1093,18 +1120,28 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
}
|
||||
|
||||
out->write(" return reinterpret_cast<");
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
|
||||
if (endsWith("[0]", typeName)) {
|
||||
out->write(take(strlen(typeName) - 3, typeName));
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
}
|
||||
}
|
||||
|
||||
if (memberOwner(member)->type == Object::Pod) {
|
||||
out->write(">(o->body");
|
||||
} else {
|
||||
out->write(">(reinterpret_cast<uint8_t*>(o)");
|
||||
}
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
if (endsWith("[0]", typeName)
|
||||
or (member->type != Object::Scalar
|
||||
and memberTypeObject(member)))
|
||||
{
|
||||
out->write(" + ");
|
||||
} else {
|
||||
out->write("[");
|
||||
@ -1121,7 +1158,10 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write(elementSize);
|
||||
out->write(")");
|
||||
}
|
||||
if (member->type == Object::Scalar or memberTypeObject(member) == 0) {
|
||||
if (not endsWith("[0]", typeName)
|
||||
and (member->type == Object::Scalar
|
||||
or memberTypeObject(member) == 0))
|
||||
{
|
||||
out->write("]");
|
||||
}
|
||||
out->write(");\n}\n\n");
|
||||
|
@ -38,6 +38,12 @@
|
||||
(object spec)
|
||||
(object class))
|
||||
|
||||
(pod compiled
|
||||
(uint32_t codeLength)
|
||||
(uint16_t lineNumberTableLength)
|
||||
(uint16_t exceptionHandlerTableLength)
|
||||
(uint8_t[0] body))
|
||||
|
||||
(type method java/lang/reflect/Method
|
||||
(extends accessibleObject)
|
||||
(uint8_t vmFlags)
|
||||
@ -50,13 +56,7 @@
|
||||
(object spec)
|
||||
(object class)
|
||||
(object code)
|
||||
(void* compiled))
|
||||
|
||||
(type compiled
|
||||
(nogc object pool)
|
||||
(uint32_t lineNumbers)
|
||||
(uint32_t exceptionHandlers)
|
||||
(array uint8_t body))
|
||||
(uint64_t compiled))
|
||||
|
||||
(type nativeMethodData
|
||||
(void* function)
|
||||
|
Loading…
Reference in New Issue
Block a user