mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
more work on JIT unwinding
This commit is contained in:
parent
2135f62584
commit
feeaecbfd8
@ -590,7 +590,7 @@ Java_java_lang_Throwable_resolveTrace(Thread* t, jclass, jobject trace)
|
|||||||
object method = methodName(t, traceElementMethod(t, e));
|
object method = methodName(t, traceElementMethod(t, e));
|
||||||
method = makeString(t, method, 0, byteArrayLength(t, method) - 1, 0);
|
method = makeString(t, method, 0, byteArrayLength(t, method) - 1, 0);
|
||||||
|
|
||||||
unsigned line = lineNumber
|
unsigned line = t->m->processor->lineNumber
|
||||||
(t, traceElementMethod(t, e), traceElementIp(t, e));
|
(t, traceElementMethod(t, e), traceElementIp(t, e));
|
||||||
|
|
||||||
object ste = makeStackTraceElement(t, class_, method, 0, line);
|
object ste = makeStackTraceElement(t, class_, method, 0, line);
|
||||||
|
@ -43,12 +43,10 @@ test:
|
|||||||
|
|
||||||
.globl vmJump
|
.globl vmJump
|
||||||
vmJump:
|
vmJump:
|
||||||
// %rdi: address
|
movq %rsi,%rbp
|
||||||
// %rsi: base
|
movq %rdx,%rsp
|
||||||
movq %rsi,%rsp
|
jmp *%rdi
|
||||||
popq %rbp
|
|
||||||
jmp *(%rdi)
|
|
||||||
|
|
||||||
#elif defined __i386__
|
#elif defined __i386__
|
||||||
|
|
||||||
.globl vmInvoke
|
.globl vmInvoke
|
||||||
@ -109,11 +107,9 @@ exit:
|
|||||||
|
|
||||||
.globl vmJump
|
.globl vmJump
|
||||||
vmJump:
|
vmJump:
|
||||||
// 4(%esp): address
|
|
||||||
// 8(%esp): base
|
|
||||||
movl 4(%esp),%eax
|
movl 4(%esp),%eax
|
||||||
movl 8(%esp),%esp
|
movl 8(%esp),%ebp
|
||||||
popl %ebp
|
movl 12(%esp),%esp
|
||||||
jmp *%eax
|
jmp *%eax
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
241
src/compile.cpp
241
src/compile.cpp
@ -15,7 +15,7 @@ extern "C" void
|
|||||||
vmCall();
|
vmCall();
|
||||||
|
|
||||||
extern "C" void NO_RETURN
|
extern "C" void NO_RETURN
|
||||||
vmJump(void* address, void* base);
|
vmJump(void* address, void* base, void* stack);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -141,7 +141,8 @@ class MyThread: public Thread {
|
|||||||
inline void*
|
inline void*
|
||||||
frameBase(void* frame)
|
frameBase(void* frame)
|
||||||
{
|
{
|
||||||
return static_cast<void**>(frame)[(-FrameFootprint / BytesPerWord) - 2];
|
return static_cast<void**>(frame)
|
||||||
|
[static_cast<int>(- (FrameFootprint / BytesPerWord) - 2)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -165,7 +166,8 @@ frameMethod(void* frame)
|
|||||||
inline void*
|
inline void*
|
||||||
frameAddress(void* frame)
|
frameAddress(void* frame)
|
||||||
{
|
{
|
||||||
return static_cast<void**>(frame)[(-FrameFootprint / BytesPerWord) - 1];
|
return static_cast<void**>(frame)
|
||||||
|
[static_cast<int>(- (FrameFootprint / BytesPerWord) - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void*
|
inline void*
|
||||||
@ -180,25 +182,38 @@ compiledCode(Compiled* code)
|
|||||||
return compiledBody(code);
|
return compiledBody(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
compiledLineNumberCount(Thread*, Compiled* code)
|
||||||
|
{
|
||||||
|
return compiledLineNumberTableLength(code) / sizeof(NativeLineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
inline NativeLineNumber*
|
inline NativeLineNumber*
|
||||||
compiledLineNumber(Thread* t, Compiled* code, unsigned index)
|
compiledLineNumber(Thread* t, Compiled* code, unsigned index)
|
||||||
{
|
{
|
||||||
assert(t, index < compiledLineNumberTableLength(code));
|
assert(t, index < compiledLineNumberCount(t, code));
|
||||||
return reinterpret_cast<NativeLineNumber*>
|
return reinterpret_cast<NativeLineNumber*>
|
||||||
(compiledBody(code) + pad(compiledCodeLength(code)));
|
(compiledBody(code) + pad(compiledCodeLength(code))) + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
compiledExceptionHandlerCount(Thread*, Compiled* code)
|
||||||
|
{
|
||||||
|
return compiledExceptionHandlerTableLength(code)
|
||||||
|
/ sizeof(NativeExceptionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline NativeExceptionHandler*
|
inline NativeExceptionHandler*
|
||||||
compiledExceptionHandler(Thread* t, Compiled* code, unsigned index)
|
compiledExceptionHandler(Thread* t, Compiled* code, unsigned index)
|
||||||
{
|
{
|
||||||
assert(t, index < compiledExceptionHandlerTableLength(code));
|
assert(t, index < compiledExceptionHandlerCount(t, code));
|
||||||
return reinterpret_cast<NativeExceptionHandler*>
|
return reinterpret_cast<NativeExceptionHandler*>
|
||||||
(compiledBody(code) + pad(compiledCodeLength(code))
|
(compiledBody(code) + pad(compiledCodeLength(code))
|
||||||
+ pad(compiledLineNumberTableLength(code)));
|
+ pad(compiledLineNumberTableLength(code))) + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Compiled*
|
inline Compiled*
|
||||||
makeCompiled(Thread* t, Buffer* code, Buffer* lineNumbers,
|
makeCompiled(Thread* t, object method, Buffer* code, Buffer* lineNumbers,
|
||||||
Buffer* exceptionHandlers)
|
Buffer* exceptionHandlers)
|
||||||
{
|
{
|
||||||
Compiled* c = static_cast<Compiled*>
|
Compiled* c = static_cast<Compiled*>
|
||||||
@ -207,6 +222,13 @@ makeCompiled(Thread* t, Buffer* code, Buffer* lineNumbers,
|
|||||||
+ pad(lineNumbers->length())
|
+ pad(lineNumbers->length())
|
||||||
+ pad(exceptionHandlers->length())));
|
+ pad(exceptionHandlers->length())));
|
||||||
|
|
||||||
|
if (method) {
|
||||||
|
compiledMaxLocals(c) = codeMaxLocals(t, methodCode(t, method));
|
||||||
|
compiledMaxStack(c) = codeMaxStack(t, methodCode(t, method));
|
||||||
|
} else {
|
||||||
|
compiledMaxLocals(c) = 0;
|
||||||
|
compiledMaxStack(c) = 0;
|
||||||
|
}
|
||||||
compiledCodeLength(c) = code->length();
|
compiledCodeLength(c) = code->length();
|
||||||
compiledLineNumberTableLength(c) = lineNumbers->length();
|
compiledLineNumberTableLength(c) = lineNumbers->length();
|
||||||
compiledExceptionHandlerTableLength(c) = exceptionHandlers->length();
|
compiledExceptionHandlerTableLength(c) = exceptionHandlers->length();
|
||||||
@ -237,7 +259,7 @@ findExceptionHandler(Thread* t, void* frame)
|
|||||||
object method = frameMethod(frame);
|
object method = frameMethod(frame);
|
||||||
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||||
|
|
||||||
for (unsigned i = 0; i < compiledExceptionHandlerTableLength(code); ++i) {
|
for (unsigned i = 0; i < compiledExceptionHandlerCount(t, code); ++i) {
|
||||||
NativeExceptionHandler* handler = compiledExceptionHandler(t, code, i);
|
NativeExceptionHandler* handler = compiledExceptionHandler(t, code, i);
|
||||||
unsigned offset = addressOffset(t, method, frameAddress(frame));
|
unsigned offset = addressOffset(t, method, frameAddress(frame));
|
||||||
|
|
||||||
@ -254,6 +276,14 @@ findExceptionHandler(Thread* t, void* frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
||||||
|
fprintf(stderr, "exception handler match for %d in %s: "
|
||||||
|
"start: %d; end: %d; ip: %d\n",
|
||||||
|
offset,
|
||||||
|
&byteArrayBody(t, methodName(t, frameMethod(frame)), 0),
|
||||||
|
nativeExceptionHandlerStart(handler),
|
||||||
|
nativeExceptionHandlerEnd(handler),
|
||||||
|
nativeExceptionHandlerIp(handler));
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,21 +296,40 @@ void NO_RETURN
|
|||||||
unwind(MyThread* t)
|
unwind(MyThread* t)
|
||||||
{
|
{
|
||||||
for (void* frame = t->frame; frameValid(frame); frame = frameNext(frame)) {
|
for (void* frame = t->frame; frameValid(frame); frame = frameNext(frame)) {
|
||||||
|
if ((methodFlags(t, frameMethod(frame)) & ACC_NATIVE) == 0) {
|
||||||
|
NativeExceptionHandler* eh = findExceptionHandler(t, frame);
|
||||||
|
if (eh) {
|
||||||
|
object method = frameMethod(frame);
|
||||||
|
Compiled* code = reinterpret_cast<Compiled*>
|
||||||
|
(methodCompiled(t, method));
|
||||||
|
t->frame = frame;
|
||||||
|
|
||||||
|
void** stack = static_cast<void**>(frameBase(frame));
|
||||||
|
|
||||||
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
|
unsigned localFootprint = compiledMaxLocals(code);
|
||||||
|
|
||||||
|
if (localFootprint > parameterFootprint) {
|
||||||
|
stack -= (localFootprint - parameterFootprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(--stack) = t->exception;
|
||||||
|
t->exception = 0;
|
||||||
|
|
||||||
|
vmJump(compiledCode(code) + nativeExceptionHandlerIp(eh),
|
||||||
|
frameBase(frame),
|
||||||
|
stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void* next = frameNext(frame);
|
void* next = frameNext(frame);
|
||||||
if (not frameValid(next)
|
if (not frameValid(next)
|
||||||
or methodFlags(t, frameMethod(next)) & ACC_NATIVE)
|
or methodFlags(t, frameMethod(next)) & ACC_NATIVE)
|
||||||
{
|
{
|
||||||
t->frame = next;
|
t->frame = next;
|
||||||
vmJump(frameReturnAddress(frame), frameBase(frame));
|
vmJump(frameReturnAddress(frame),
|
||||||
} else if ((methodFlags(t, frameMethod(frame)) & ACC_NATIVE) == 0) {
|
*static_cast<void**>(frameBase(frame)),
|
||||||
NativeExceptionHandler* eh = findExceptionHandler(t, frame);
|
static_cast<void**>(frameBase(frame)) + 2);
|
||||||
if (eh) {
|
|
||||||
Compiled* code = reinterpret_cast<Compiled*>
|
|
||||||
(methodCompiled(t, frameMethod(frame)));
|
|
||||||
t->frame = frame;
|
|
||||||
vmJump(compiledCode(code) + nativeExceptionHandlerIp(eh),
|
|
||||||
frameBase(frame));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
abort(t);
|
abort(t);
|
||||||
@ -1563,6 +1612,10 @@ class Compiler: public Assembler {
|
|||||||
mov(rax, rsp, 0);
|
mov(rax, rsp, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case i2l:
|
||||||
|
push(0);
|
||||||
|
break;
|
||||||
|
|
||||||
case iadd:
|
case iadd:
|
||||||
pop(rax);
|
pop(rax);
|
||||||
pop(rcx);
|
pop(rcx);
|
||||||
@ -1819,9 +1872,7 @@ class Compiler: public Assembler {
|
|||||||
if (instruction == ldc) {
|
if (instruction == ldc) {
|
||||||
index = codeBody(t, code, ip++);
|
index = codeBody(t, code, ip++);
|
||||||
} else {
|
} else {
|
||||||
uint8_t index1 = codeBody(t, code, ip++);
|
index = codeReadInt16(t, code, ip);
|
||||||
uint8_t index2 = codeBody(t, code, ip++);
|
|
||||||
index = (index1 << 8) | index2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object v = arrayBody(t, codePool(t, code), index - 1);
|
object v = arrayBody(t, codePool(t, code), index - 1);
|
||||||
@ -1843,6 +1894,99 @@ class Compiler: public Assembler {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case ldc2_w: {
|
||||||
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
|
object v = arrayBody(t, codePool(t, code), index - 1);
|
||||||
|
|
||||||
|
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType))
|
||||||
|
{
|
||||||
|
push((longValue(t, v) ) & 0xFFFFFFFF);
|
||||||
|
push((longValue(t, v) >> 32) & 0xFFFFFFFF);
|
||||||
|
} else if (objectClass(t, v)
|
||||||
|
== arrayBody(t, t->m->types, Machine::DoubleType))
|
||||||
|
{
|
||||||
|
push((doubleValue(t, v) ) & 0xFFFFFFFF);
|
||||||
|
push((doubleValue(t, v) >> 32) & 0xFFFFFFFF);
|
||||||
|
} else {
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lconst_0:
|
||||||
|
push(0);
|
||||||
|
push(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case lconst_1:
|
||||||
|
push(0);
|
||||||
|
push(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// todo:
|
||||||
|
// case lcmp: {
|
||||||
|
// pop(rax);
|
||||||
|
// pop(rdx);
|
||||||
|
|
||||||
|
// if (BytesPerWord == 8) {
|
||||||
|
// shl(32, rax);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pushInt(t, a > b ? 1 : a == b ? 0 : -1);
|
||||||
|
// } goto loop;
|
||||||
|
|
||||||
|
case lload: {
|
||||||
|
unsigned index = codeBody(t, code, ip++);
|
||||||
|
push(rbp, localOffset(index, parameterFootprint));
|
||||||
|
push(rbp, localOffset(index + 1, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lload_0: {
|
||||||
|
push(rbp, localOffset(0, parameterFootprint));
|
||||||
|
push(rbp, localOffset(1, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lload_1: {
|
||||||
|
push(rbp, localOffset(1, parameterFootprint));
|
||||||
|
push(rbp, localOffset(2, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lload_2: {
|
||||||
|
push(rbp, localOffset(2, parameterFootprint));
|
||||||
|
push(rbp, localOffset(3, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lload_3: {
|
||||||
|
push(rbp, localOffset(3, parameterFootprint));
|
||||||
|
push(rbp, localOffset(4, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lstore: {
|
||||||
|
unsigned index = codeBody(t, code, ip++);
|
||||||
|
pop(rbp, localOffset(index + 1, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(index, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lstore_0: {
|
||||||
|
pop(rbp, localOffset(1, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(0, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lstore_1: {
|
||||||
|
pop(rbp, localOffset(2, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(1, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lstore_2: {
|
||||||
|
pop(rbp, localOffset(3, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(2, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case lstore_3: {
|
||||||
|
pop(rbp, localOffset(4, parameterFootprint));
|
||||||
|
pop(rbp, localOffset(3, parameterFootprint));
|
||||||
|
} break;
|
||||||
|
|
||||||
case new_: {
|
case new_: {
|
||||||
uint16_t index = codeReadInt16(t, code, ip);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
|
|
||||||
@ -2038,7 +2182,7 @@ class Compiler: public Assembler {
|
|||||||
resolveJumps();
|
resolveJumps();
|
||||||
buildExceptionHandlerTable(code);
|
buildExceptionHandlerTable(code);
|
||||||
|
|
||||||
return finish();
|
return finish(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t machineIpForJavaIp(uint16_t javaIP) {
|
uint32_t machineIpForJavaIp(uint16_t javaIP) {
|
||||||
@ -2135,7 +2279,7 @@ class Compiler: public Assembler {
|
|||||||
add(CompiledBody, rax);
|
add(CompiledBody, rax);
|
||||||
jmp(rax); // call compiled code
|
jmp(rax); // call compiled code
|
||||||
|
|
||||||
return finish();
|
return finish(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiled* compileNativeInvoker() {
|
Compiled* compileNativeInvoker() {
|
||||||
@ -2161,7 +2305,7 @@ class Compiler: public Assembler {
|
|||||||
pop(rbp);
|
pop(rbp);
|
||||||
ret();
|
ret();
|
||||||
|
|
||||||
return finish();
|
return finish(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiled* compileCaller() {
|
Compiled* compileCaller() {
|
||||||
@ -2171,11 +2315,11 @@ class Compiler: public Assembler {
|
|||||||
|
|
||||||
jmp(rbx);
|
jmp(rbx);
|
||||||
|
|
||||||
return finish();
|
return finish(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiled* finish() {
|
Compiled* finish(object method) {
|
||||||
return makeCompiled(t, &code, &lineNumbers, &exceptionHandlers);
|
return makeCompiled(t, method, &code, &lineNumbers, &exceptionHandlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
object makePool() {
|
object makePool() {
|
||||||
@ -2273,7 +2417,8 @@ updateCaller(MyThread* t, object method)
|
|||||||
|
|
||||||
a.call(rax);
|
a.call(rax);
|
||||||
|
|
||||||
uint8_t* caller = static_cast<uint8_t**>(t->frame)[1] - a.code.length();
|
uint8_t* caller = static_cast<uint8_t*>(frameAddress(t->frame))
|
||||||
|
- a.code.length();
|
||||||
if (memcmp(a.code.data, caller, a.code.length()) == 0) {
|
if (memcmp(a.code.data, caller, a.code.length()) == 0) {
|
||||||
// it's a direct call - update caller to point to new code
|
// it's a direct call - update caller to point to new code
|
||||||
|
|
||||||
@ -2587,9 +2732,7 @@ class MyProcessor: public Processor {
|
|||||||
case 'J':
|
case 'J':
|
||||||
case 'D':
|
case 'D':
|
||||||
++ s;
|
++ s;
|
||||||
if (BytesPerWord == 4) {
|
++ footprint;
|
||||||
++ footprint;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2662,6 +2805,40 @@ class MyProcessor: public Processor {
|
|||||||
return addressOffset(t, ::frameMethod(f), ::frameAddress(f));
|
return addressOffset(t, ::frameMethod(f), ::frameAddress(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int
|
||||||
|
lineNumber(Thread* t, object method, unsigned ip)
|
||||||
|
{
|
||||||
|
if (methodFlags(t, method) & ACC_NATIVE) {
|
||||||
|
return NativeLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, method));
|
||||||
|
if (compiledLineNumberCount(t, code)) {
|
||||||
|
unsigned bottom = 0;
|
||||||
|
unsigned top = compiledLineNumberCount(t, code);
|
||||||
|
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||||
|
unsigned middle = bottom + (span / 2);
|
||||||
|
NativeLineNumber* ln = compiledLineNumber(t, code, middle);
|
||||||
|
|
||||||
|
if (ip >= nativeLineNumberIp(ln)
|
||||||
|
and (middle + 1 == compiledLineNumberCount(t, code)
|
||||||
|
or ip < nativeLineNumberIp
|
||||||
|
(compiledLineNumber(t, code, middle + 1))))
|
||||||
|
{
|
||||||
|
return nativeLineNumberLine(ln);
|
||||||
|
} else if (ip < nativeLineNumberIp(ln)) {
|
||||||
|
top = middle;
|
||||||
|
} else if (ip > nativeLineNumberIp(ln)) {
|
||||||
|
bottom = middle + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(t);
|
||||||
|
} else {
|
||||||
|
return UnknownLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual object*
|
virtual object*
|
||||||
makeLocalReference(Thread* vmt, object o)
|
makeLocalReference(Thread* vmt, object o)
|
||||||
{
|
{
|
||||||
|
@ -1936,22 +1936,17 @@ interpret(Thread* t)
|
|||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case jsr: {
|
case jsr: {
|
||||||
uint8_t offset1 = codeBody(t, code, ip++);
|
uint16_t offset = codeReadInt16(t, code, ip);
|
||||||
uint8_t offset2 = codeBody(t, code, ip++);
|
|
||||||
|
|
||||||
pushInt(t, ip);
|
pushInt(t, ip);
|
||||||
ip = (ip - 3) + static_cast<int16_t>(((offset1 << 8) | offset2));
|
ip = (ip - 3) + static_cast<int16_t>(offset);
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case jsr_w: {
|
case jsr_w: {
|
||||||
uint8_t offset1 = codeBody(t, code, ip++);
|
uint32_t offset = codeReadInt32(t, code, ip);
|
||||||
uint8_t offset2 = codeBody(t, code, ip++);
|
|
||||||
uint8_t offset3 = codeBody(t, code, ip++);
|
|
||||||
uint8_t offset4 = codeBody(t, code, ip++);
|
|
||||||
|
|
||||||
pushInt(t, ip);
|
pushInt(t, ip);
|
||||||
ip = (ip - 3) + static_cast<int32_t>
|
ip = (ip - 3) + static_cast<int32_t>(offset);
|
||||||
((offset1 << 24) | (offset2 << 16) | (offset3 << 8) | offset4);
|
|
||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case l2i: {
|
case l2i: {
|
||||||
@ -2037,9 +2032,7 @@ interpret(Thread* t)
|
|||||||
if (instruction == ldc) {
|
if (instruction == ldc) {
|
||||||
index = codeBody(t, code, ip++);
|
index = codeBody(t, code, ip++);
|
||||||
} else {
|
} else {
|
||||||
uint8_t index1 = codeBody(t, code, ip++);
|
index = codeReadInt16(t, code, ip);
|
||||||
uint8_t index2 = codeBody(t, code, ip++);
|
|
||||||
index = (index1 << 8) | index2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object v = arrayBody(t, codePool(t, code), index - 1);
|
object v = arrayBody(t, codePool(t, code), index - 1);
|
||||||
@ -2063,10 +2056,9 @@ interpret(Thread* t)
|
|||||||
} goto loop;
|
} goto loop;
|
||||||
|
|
||||||
case ldc2_w: {
|
case ldc2_w: {
|
||||||
uint8_t index1 = codeBody(t, code, ip++);
|
uint16_t index = codeReadInt16(t, code, ip);
|
||||||
uint8_t index2 = codeBody(t, code, ip++);
|
|
||||||
|
|
||||||
object v = arrayBody(t, codePool(t, code), ((index1 << 8) | index2) - 1);
|
object v = arrayBody(t, codePool(t, code), index - 1);
|
||||||
|
|
||||||
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType)) {
|
if (objectClass(t, v) == arrayBody(t, t->m->types, Machine::LongType)) {
|
||||||
pushLong(t, longValue(t, v));
|
pushLong(t, longValue(t, v));
|
||||||
@ -2987,6 +2979,30 @@ class MyProcessor: public Processor {
|
|||||||
return ::frameIp(t, frame);
|
return ::frameIp(t, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual int
|
||||||
|
lineNumber(Thread* t, object method, unsigned ip)
|
||||||
|
{
|
||||||
|
if (methodFlags(t, method) & ACC_NATIVE) {
|
||||||
|
return NativeLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
object table = codeLineNumberTable(t, methodCode(t, method));
|
||||||
|
if (table) {
|
||||||
|
// todo: do a binary search:
|
||||||
|
int last = UnknownLine;
|
||||||
|
for (unsigned i = 0; i < lineNumberTableLength(t, table); ++i) {
|
||||||
|
if (ip <= lineNumberIp(lineNumberTableBody(t, table, i))) {
|
||||||
|
return last;
|
||||||
|
} else {
|
||||||
|
last = lineNumberLine(lineNumberTableBody(t, table, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return last;
|
||||||
|
} else {
|
||||||
|
return UnknownLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual object*
|
virtual object*
|
||||||
makeLocalReference(vm::Thread* vmt, object o)
|
makeLocalReference(vm::Thread* vmt, object o)
|
||||||
{
|
{
|
||||||
|
@ -2366,30 +2366,6 @@ findInHierarchy(Thread* t, object class_, object name, object spec,
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
lineNumber(Thread* t, object method, unsigned ip)
|
|
||||||
{
|
|
||||||
if (methodFlags(t, method) & ACC_NATIVE) {
|
|
||||||
return NativeLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
object table = codeLineNumberTable(t, methodCode(t, method));
|
|
||||||
if (table) {
|
|
||||||
// todo: do a binary search:
|
|
||||||
int last = UnknownLine;
|
|
||||||
for (unsigned i = 0; i < lineNumberTableLength(t, table); ++i) {
|
|
||||||
if (ip <= lineNumberIp(lineNumberTableBody(t, table, i))) {
|
|
||||||
return last;
|
|
||||||
} else {
|
|
||||||
last = lineNumberLine(lineNumberTableBody(t, table, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return last;
|
|
||||||
} else {
|
|
||||||
return UnknownLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
|
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
|
||||||
{
|
{
|
||||||
@ -2649,7 +2625,8 @@ printTrace(Thread* t, object exception)
|
|||||||
(t, className(t, methodClass(t, traceElementMethod(t, e))), 0);
|
(t, className(t, methodClass(t, traceElementMethod(t, e))), 0);
|
||||||
const int8_t* method = &byteArrayBody
|
const int8_t* method = &byteArrayBody
|
||||||
(t, methodName(t, traceElementMethod(t, e)), 0);
|
(t, methodName(t, traceElementMethod(t, e)), 0);
|
||||||
int line = lineNumber(t, traceElementMethod(t, e), traceElementIp(t, e));
|
int line = t->m->processor->lineNumber
|
||||||
|
(t, traceElementMethod(t, e), traceElementIp(t, e));
|
||||||
|
|
||||||
fprintf(stderr, " at %s.%s ", class_, method);
|
fprintf(stderr, " at %s.%s ", class_, method);
|
||||||
|
|
||||||
|
@ -2008,9 +2008,6 @@ objectArrayBody(Thread* t UNUSED, object array, unsigned index)
|
|||||||
return cast<object>(array, (2 + index) * BytesPerWord);
|
return cast<object>(array, (2 + index) * BytesPerWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
lineNumber(Thread* t, object method, unsigned ip);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
|
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ class Processor {
|
|||||||
virtual unsigned
|
virtual unsigned
|
||||||
frameIp(Thread* t, uintptr_t frame) = 0;
|
frameIp(Thread* t, uintptr_t frame) = 0;
|
||||||
|
|
||||||
|
virtual int
|
||||||
|
lineNumber(Thread* t, object method, unsigned ip) = 0;
|
||||||
|
|
||||||
virtual object*
|
virtual object*
|
||||||
makeLocalReference(Thread* t, object o) = 0;
|
makeLocalReference(Thread* t, object o) = 0;
|
||||||
|
|
||||||
|
@ -39,9 +39,11 @@
|
|||||||
(object class))
|
(object class))
|
||||||
|
|
||||||
(pod compiled
|
(pod compiled
|
||||||
|
(uint16_t maxLocals)
|
||||||
|
(uint16_t maxStack)
|
||||||
(uint32_t codeLength)
|
(uint32_t codeLength)
|
||||||
(uint16_t lineNumberTableLength)
|
(uint32_t lineNumberTableLength)
|
||||||
(uint16_t exceptionHandlerTableLength)
|
(uint32_t exceptionHandlerTableLength)
|
||||||
(uint8_t[0] body))
|
(uint8_t[0] body))
|
||||||
|
|
||||||
(type method java/lang/reflect/Method
|
(type method java/lang/reflect/Method
|
||||||
|
Loading…
Reference in New Issue
Block a user