mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
fix ARM stack unwinding (part 2)
My previous attempt at this was incomplete; it did not address Java->native->Java->native call sequences, nor did it address continuations. This commit takes care of both.
This commit is contained in:
parent
98e74f66e9
commit
20f4510122
@ -81,12 +81,18 @@ isVmInvokeUnsafeStack(void* ip)
|
|||||||
< reinterpret_cast<uintptr_t> (voidPointer(vmInvoke_safeStack));
|
< reinterpret_cast<uintptr_t> (voidPointer(vmInvoke_safeStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyThread;
|
||||||
|
|
||||||
|
void*
|
||||||
|
getIp(MyThread*);
|
||||||
|
|
||||||
class MyThread: public Thread {
|
class MyThread: public Thread {
|
||||||
public:
|
public:
|
||||||
class CallTrace {
|
class CallTrace {
|
||||||
public:
|
public:
|
||||||
CallTrace(MyThread* t, object method):
|
CallTrace(MyThread* t, object method):
|
||||||
t(t),
|
t(t),
|
||||||
|
ip(getIp(t)),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
scratch(t->scratch),
|
scratch(t->scratch),
|
||||||
continuation(t->continuation),
|
continuation(t->continuation),
|
||||||
@ -107,6 +113,7 @@ class MyThread: public Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MyThread* t;
|
MyThread* t;
|
||||||
|
void* ip;
|
||||||
void* stack;
|
void* stack;
|
||||||
void* scratch;
|
void* scratch;
|
||||||
object continuation;
|
object continuation;
|
||||||
@ -436,15 +443,20 @@ nextFrame(MyThread* t, void** ip, void** sp, object method, object target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
getIp(MyThread* t)
|
getIp(MyThread* t, void* ip, void* stack)
|
||||||
{
|
{
|
||||||
// Here we use the convention that, if the return address is neither
|
// Here we use the convention that, if the return address is neither
|
||||||
// pushed on to the stack automatically as part of the call nor
|
// pushed on to the stack automatically as part of the call nor
|
||||||
// stored in the caller's frame, it will be saved in MyThread::ip
|
// stored in the caller's frame, it will be saved in MyThread::ip
|
||||||
// instead of on the stack. See the various implementations of
|
// instead of on the stack. See the various implementations of
|
||||||
// Assembler::saveFrame for details on how this is done.
|
// Assembler::saveFrame for details on how this is done.
|
||||||
return t->arch->returnAddressOffset() < 0
|
return t->arch->returnAddressOffset() < 0 ? ip : t->arch->frameIp(stack);
|
||||||
? t->ip : t->arch->frameIp(t->stack);
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
getIp(MyThread* t)
|
||||||
|
{
|
||||||
|
return getIp(t, t->ip, t->stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyStackWalker: public Processor::StackWalker {
|
class MyStackWalker: public Processor::StackWalker {
|
||||||
@ -521,10 +533,6 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
// fprintf(stderr, "state: %d\n", state);
|
// fprintf(stderr, "state: %d\n", state);
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case Start:
|
case Start:
|
||||||
if (ip_ == 0) {
|
|
||||||
ip_ = t->arch->frameIp(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trace and trace->nativeMethod) {
|
if (trace and trace->nativeMethod) {
|
||||||
method_ = trace->nativeMethod;
|
method_ = trace->nativeMethod;
|
||||||
state = NativeMethod;
|
state = NativeMethod;
|
||||||
@ -554,7 +562,7 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
if (trace) {
|
if (trace) {
|
||||||
continuation = trace->continuation;
|
continuation = trace->continuation;
|
||||||
stack = trace->stack;
|
stack = trace->stack;
|
||||||
ip_ = t->arch->frameIp(stack);
|
ip_ = trace->ip;
|
||||||
trace = trace->next;
|
trace = trace->next;
|
||||||
|
|
||||||
state = Start;
|
state = Start;
|
||||||
@ -1998,10 +2006,6 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
continuation = t->continuation;
|
continuation = t->continuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip == 0) {
|
|
||||||
ip = t->arch->frameIp(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
object target = t->trace->targetMethod;
|
object target = t->trace->targetMethod;
|
||||||
|
|
||||||
*targetIp = 0;
|
*targetIp = 0;
|
||||||
@ -2080,7 +2084,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetFrame,
|
|||||||
object
|
object
|
||||||
makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
makeCurrentContinuation(MyThread* t, void** targetIp, void** targetStack)
|
||||||
{
|
{
|
||||||
void* ip = t->arch->frameIp(t->stack);
|
void* ip = getIp(t);
|
||||||
void* stack = t->stack;
|
void* stack = t->stack;
|
||||||
|
|
||||||
object context = t->continuation
|
object context = t->continuation
|
||||||
@ -6219,7 +6223,7 @@ compileMethod(MyThread* t)
|
|||||||
ip = t->tailAddress;
|
ip = t->tailAddress;
|
||||||
t->tailAddress = 0;
|
t->tailAddress = 0;
|
||||||
} else {
|
} else {
|
||||||
ip = t->arch->frameIp(t->stack);
|
ip = getIp(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reinterpret_cast<uintptr_t>(compileMethod2(t, ip));
|
return reinterpret_cast<uintptr_t>(compileMethod2(t, ip));
|
||||||
@ -6470,7 +6474,7 @@ invokeNative(MyThread* t)
|
|||||||
ip = t->tailAddress;
|
ip = t->tailAddress;
|
||||||
t->tailAddress = 0;
|
t->tailAddress = 0;
|
||||||
} else {
|
} else {
|
||||||
ip = t->arch->frameIp(t->stack);
|
ip = getIp(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
object node = findCallNode(t, ip);
|
object node = findCallNode(t, ip);
|
||||||
@ -6511,7 +6515,7 @@ invokeNative(MyThread* t)
|
|||||||
|
|
||||||
stack += t->arch->frameReturnAddressSize();
|
stack += t->arch->frameReturnAddressSize();
|
||||||
|
|
||||||
transition(t, t->arch->frameIp(t->stack), stack, t->continuation, t->trace);
|
transition(t, getIp(t), stack, t->continuation, t->trace);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -6708,7 +6712,7 @@ visitStack(MyThread* t, Heap::Visitor* v)
|
|||||||
target = method;
|
target = method;
|
||||||
} else if (trace) {
|
} else if (trace) {
|
||||||
stack = trace->stack;
|
stack = trace->stack;
|
||||||
ip = t->arch->frameIp(stack);
|
ip = trace->ip;
|
||||||
trace = trace->next;
|
trace = trace->next;
|
||||||
|
|
||||||
if (trace) {
|
if (trace) {
|
||||||
@ -7697,12 +7701,12 @@ class MyProcessor: public Processor {
|
|||||||
// we caught the thread in a thunk or native code, and the
|
// we caught the thread in a thunk or native code, and the
|
||||||
// saved stack pointer indicates the most recent Java frame
|
// saved stack pointer indicates the most recent Java frame
|
||||||
// on the stack
|
// on the stack
|
||||||
c.ip = t->arch->frameIp(target->stack);
|
c.ip = getIp(target);
|
||||||
c.stack = target->stack;
|
c.stack = target->stack;
|
||||||
} else if (isThunk(t, ip) or isVirtualThunk(t, ip)) {
|
} else if (isThunk(t, ip) or isVirtualThunk(t, ip)) {
|
||||||
// we caught the thread in a thunk where the stack register
|
// we caught the thread in a thunk where the stack register
|
||||||
// indicates the most recent Java frame on the stack
|
// indicates the most recent Java frame on the stack
|
||||||
c.ip = t->arch->frameIp(stack);
|
c.ip = getIp(t, link, stack);
|
||||||
c.stack = stack;
|
c.stack = stack;
|
||||||
} else {
|
} else {
|
||||||
// we caught the thread in native code, and the most recent
|
// we caught the thread in native code, and the most recent
|
||||||
|
24
test/Initializers.java
Normal file
24
test/Initializers.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
public class Initializers {
|
||||||
|
private static class Static2 {
|
||||||
|
public static String foo = "Static2.foo";
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.gc();
|
||||||
|
new Exception().printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Static1 {
|
||||||
|
public static String foo = "Static1.foo";
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.out.println(Static2.foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Object x = new Object();
|
||||||
|
System.out.println(Static1.foo);
|
||||||
|
x.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user