mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
nth attempt to clean up MyStackWalker
This commit is contained in:
parent
9e8e4b3de7
commit
d072b71c39
186
src/compile.cpp
186
src/compile.cpp
@ -40,14 +40,12 @@ class MyThread: public Thread {
|
|||||||
public:
|
public:
|
||||||
CallTrace(MyThread* t):
|
CallTrace(MyThread* t):
|
||||||
t(t),
|
t(t),
|
||||||
ip(t->ip),
|
|
||||||
base(t->base),
|
base(t->base),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
nativeMethod(0),
|
nativeMethod(0),
|
||||||
next(t->trace)
|
next(t->trace)
|
||||||
{
|
{
|
||||||
t->trace = this;
|
t->trace = this;
|
||||||
t->ip = 0;
|
|
||||||
t->base = 0;
|
t->base = 0;
|
||||||
t->stack = 0;
|
t->stack = 0;
|
||||||
}
|
}
|
||||||
@ -55,7 +53,6 @@ class MyThread: public Thread {
|
|||||||
~CallTrace() {
|
~CallTrace() {
|
||||||
t->stack = stack;
|
t->stack = stack;
|
||||||
t->base = base;
|
t->base = base;
|
||||||
t->ip = ip;
|
|
||||||
t->trace = next;
|
t->trace = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +149,14 @@ methodForIp(MyThread* t, void* ip)
|
|||||||
|
|
||||||
class MyStackWalker: public Processor::StackWalker {
|
class MyStackWalker: public Processor::StackWalker {
|
||||||
public:
|
public:
|
||||||
|
enum State {
|
||||||
|
Start,
|
||||||
|
Next,
|
||||||
|
Method,
|
||||||
|
NativeMethod,
|
||||||
|
Finish
|
||||||
|
};
|
||||||
|
|
||||||
class MyProtector: public Thread::Protector {
|
class MyProtector: public Thread::Protector {
|
||||||
public:
|
public:
|
||||||
MyProtector(MyStackWalker* walker):
|
MyProtector(MyStackWalker* walker):
|
||||||
@ -160,7 +165,6 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
|
|
||||||
virtual void visit(Heap::Visitor* v) {
|
virtual void visit(Heap::Visitor* v) {
|
||||||
v->visit(&(walker->method_));
|
v->visit(&(walker->method_));
|
||||||
v->visit(&(walker->nativeMethod));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyStackWalker* walker;
|
MyStackWalker* walker;
|
||||||
@ -168,114 +172,156 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
|
|
||||||
MyStackWalker(MyThread* t):
|
MyStackWalker(MyThread* t):
|
||||||
t(t),
|
t(t),
|
||||||
ip_(t->ip ? t->ip : (t->stack ? *static_cast<void**>(t->stack) : 0)),
|
state(Start),
|
||||||
|
ip_(t->ip),
|
||||||
base(t->base),
|
base(t->base),
|
||||||
stack(t->stack),
|
stack(t->stack),
|
||||||
trace(t->trace),
|
trace(t->trace),
|
||||||
nativeMethod(trace ? trace->nativeMethod : 0),
|
method_(0),
|
||||||
method_(ip_ ? methodForIp(t, ip_) : 0),
|
|
||||||
protector(this)
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
MyStackWalker(MyStackWalker* w):
|
MyStackWalker(MyStackWalker* w):
|
||||||
t(w->t),
|
t(w->t),
|
||||||
|
state(w->state),
|
||||||
ip_(w->ip_),
|
ip_(w->ip_),
|
||||||
base(w->base),
|
base(w->base),
|
||||||
stack(w->stack),
|
stack(w->stack),
|
||||||
trace(w->trace),
|
trace(w->trace),
|
||||||
nativeMethod(w->nativeMethod),
|
|
||||||
method_(w->method_),
|
method_(w->method_),
|
||||||
protector(this)
|
protector(this)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void walk(Processor::StackVisitor* v) {
|
virtual void walk(Processor::StackVisitor* v) {
|
||||||
if (stack == 0) {
|
for (MyStackWalker it(this); it.valid();) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not v->visit(this)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MyStackWalker it(this); it.next();) {
|
|
||||||
MyStackWalker walker(it);
|
MyStackWalker walker(it);
|
||||||
if (not v->visit(&walker)) {
|
if (not v->visit(&walker)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
it.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool next() {
|
bool valid() {
|
||||||
if (nativeMethod) {
|
while (true) {
|
||||||
nativeMethod = 0;
|
// fprintf(stderr, "state: %d\n", state);
|
||||||
} else if (stack) {
|
switch (state) {
|
||||||
stack = static_cast<void**>(base) + 1;
|
case Start:
|
||||||
base = *static_cast<void**>(base);
|
if (ip_ == 0 and stack) {
|
||||||
ip_ = *static_cast<void**>(stack);
|
ip_ = *static_cast<void**>(stack);
|
||||||
method_ = methodForIp(t, *static_cast<void**>(stack));
|
}
|
||||||
} else {
|
|
||||||
return false;
|
if (trace and trace->nativeMethod) {
|
||||||
|
method_ = trace->nativeMethod;
|
||||||
|
state = NativeMethod;
|
||||||
|
} else if (ip_) {
|
||||||
|
state = Next;
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Next:
|
||||||
|
if (stack) {
|
||||||
|
method_ = methodForIp(t, ip_);
|
||||||
|
if (method_) {
|
||||||
|
state = Method;
|
||||||
|
} else if (trace) {
|
||||||
|
base = trace->base;
|
||||||
|
stack = static_cast<void**>(trace->stack);
|
||||||
|
ip_ = (stack ? *static_cast<void**>(stack) : 0);
|
||||||
|
|
||||||
|
if (trace->nativeMethod) {
|
||||||
|
method_ = trace->nativeMethod;
|
||||||
|
state = NativeMethod;
|
||||||
|
} else {
|
||||||
|
trace = trace->next;
|
||||||
|
state = Next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state = Finish;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Method:
|
||||||
|
case NativeMethod:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Finish:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (method_ or nativeMethod) {
|
void next() {
|
||||||
return true;
|
switch (state) {
|
||||||
} else if (trace and trace->stack) {
|
case Method:
|
||||||
base = trace->base;
|
stack = static_cast<void**>(base) + 1;
|
||||||
stack = static_cast<void**>(trace->stack);
|
ip_ = (stack ? *static_cast<void**>(stack) : 0);
|
||||||
ip_ = *static_cast<void**>(stack);
|
base = *static_cast<void**>(base);
|
||||||
method_ = methodForIp(t, *static_cast<void**>(stack));
|
state = Next;
|
||||||
nativeMethod = trace->nativeMethod;
|
break;
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
trace = trace->next;
|
trace = trace->next;
|
||||||
|
state = Next;
|
||||||
|
break;
|
||||||
|
|
||||||
expect(t, method_ or nativeMethod);
|
default:
|
||||||
return true;
|
abort(t);
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object method() {
|
virtual object method() {
|
||||||
if (nativeMethod) {
|
switch (state) {
|
||||||
return nativeMethod;
|
case Method:
|
||||||
} else {
|
|
||||||
return method_;
|
return method_;
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
|
return trace->nativeMethod;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int ip() {
|
virtual int ip() {
|
||||||
if (nativeMethod) {
|
switch (state) {
|
||||||
return 0;
|
case Method:
|
||||||
} else {
|
|
||||||
return reinterpret_cast<intptr_t>(ip_) - reinterpret_cast<intptr_t>
|
return reinterpret_cast<intptr_t>(ip_) - reinterpret_cast<intptr_t>
|
||||||
(&singletonValue(t, methodCompiled(t, method_), 0));
|
(&singletonValue(t, methodCompiled(t, method_), 0));
|
||||||
|
|
||||||
|
case NativeMethod:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned count() {
|
virtual unsigned count() {
|
||||||
class Visitor: public Processor::StackVisitor {
|
unsigned count = 0;
|
||||||
public:
|
|
||||||
Visitor(): count(0) { }
|
|
||||||
|
|
||||||
virtual bool visit(Processor::StackWalker*) {
|
for (MyStackWalker walker(this); walker.valid();) {
|
||||||
++ count;
|
walker.next();
|
||||||
return true;
|
++ count;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned count;
|
return count;
|
||||||
} v;
|
|
||||||
|
|
||||||
MyStackWalker walker(this);
|
|
||||||
walker.walk(&v);
|
|
||||||
|
|
||||||
return v.count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyThread* t;
|
MyThread* t;
|
||||||
|
State state;
|
||||||
void* ip_;
|
void* ip_;
|
||||||
void* base;
|
void* base;
|
||||||
void* stack;
|
void* stack;
|
||||||
MyThread::CallTrace* trace;
|
MyThread::CallTrace* trace;
|
||||||
object nativeMethod;
|
|
||||||
object method_;
|
object method_;
|
||||||
MyProtector protector;
|
MyProtector protector;
|
||||||
};
|
};
|
||||||
@ -1196,9 +1242,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
void* ip = t->ip;
|
void* ip = t->ip;
|
||||||
void* base = t->base;
|
void* base = t->base;
|
||||||
void** stack = static_cast<void**>(t->stack);
|
void** stack = static_cast<void**>(t->stack);
|
||||||
if (ip) {
|
if (ip == 0) {
|
||||||
t->ip = 0;
|
|
||||||
} else {
|
|
||||||
ip = *stack;
|
ip = *stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4302,11 +4346,11 @@ invokeNative(MyThread* t)
|
|||||||
{
|
{
|
||||||
if (t->trace->nativeMethod == 0) {
|
if (t->trace->nativeMethod == 0) {
|
||||||
object node = findCallNode(t, *static_cast<void**>(t->stack));
|
object node = findCallNode(t, *static_cast<void**>(t->stack));
|
||||||
t->trace->nativeMethod = callNodeTarget(t, node);
|
object target = callNodeTarget(t, node);
|
||||||
if (callNodeVirtualCall(t, node)) {
|
if (callNodeVirtualCall(t, node)) {
|
||||||
t->trace->nativeMethod = resolveTarget
|
target = resolveTarget(t, t->stack, target);
|
||||||
(t, t->stack, t->trace->nativeMethod);
|
|
||||||
}
|
}
|
||||||
|
t->trace->nativeMethod = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t result = 0;
|
uint64_t result = 0;
|
||||||
@ -4671,6 +4715,10 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
if (t->state == Thread::ActiveState) {
|
if (t->state == Thread::ActiveState) {
|
||||||
object node = methodForIp(t, *ip);
|
object node = methodForIp(t, *ip);
|
||||||
if (node) {
|
if (node) {
|
||||||
|
void* oldIp = t->ip;
|
||||||
|
void* oldBase = t->base;
|
||||||
|
void* oldStack = t->stack;
|
||||||
|
|
||||||
t->ip = *ip;
|
t->ip = *ip;
|
||||||
t->base = *base;
|
t->base = *base;
|
||||||
t->stack = *stack;
|
t->stack = *stack;
|
||||||
@ -4682,6 +4730,11 @@ class SegFaultHandler: public System::SignalHandler {
|
|||||||
t->tracing = false;
|
t->tracing = false;
|
||||||
|
|
||||||
findUnwindTarget(t, ip, base, stack);
|
findUnwindTarget(t, ip, base, stack);
|
||||||
|
|
||||||
|
t->ip = oldIp;
|
||||||
|
t->base = oldBase;
|
||||||
|
t->stack = oldStack;
|
||||||
|
|
||||||
*thread = t;
|
*thread = t;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5047,6 +5100,7 @@ class MyProcessor: public Processor {
|
|||||||
or (static_cast<uint8_t*>(ip) >= native
|
or (static_cast<uint8_t*>(ip) >= native
|
||||||
and static_cast<uint8_t*>(ip) < native + nativeSize))
|
and static_cast<uint8_t*>(ip) < native + nativeSize))
|
||||||
{
|
{
|
||||||
|
target->ip = *static_cast<void**>(stack);
|
||||||
target->base = base;
|
target->base = base;
|
||||||
target->stack = stack;
|
target->stack = stack;
|
||||||
}
|
}
|
||||||
|
@ -2832,6 +2832,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker)
|
|||||||
}
|
}
|
||||||
|
|
||||||
object e = makeTraceElement(t, walker->method(), walker->ip());
|
object e = makeTraceElement(t, walker->method(), walker->ip());
|
||||||
|
assert(t, index < arrayLength(t, trace));
|
||||||
set(t, trace, ArrayBody + (index * BytesPerWord), e);
|
set(t, trace, ArrayBody + (index * BytesPerWord), e);
|
||||||
++ index;
|
++ index;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user