From d072b71c396412ba5cf4cae4aea50d047234443b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 23 Apr 2008 10:33:31 -0600 Subject: [PATCH] nth attempt to clean up MyStackWalker --- src/compile.cpp | 188 +++++++++++++++++++++++++++++++----------------- src/machine.cpp | 1 + 2 files changed, 122 insertions(+), 67 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index ca61548ad6..7bfcb1190c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -40,14 +40,12 @@ class MyThread: public Thread { public: CallTrace(MyThread* t): t(t), - ip(t->ip), base(t->base), stack(t->stack), nativeMethod(0), next(t->trace) { t->trace = this; - t->ip = 0; t->base = 0; t->stack = 0; } @@ -55,7 +53,6 @@ class MyThread: public Thread { ~CallTrace() { t->stack = stack; t->base = base; - t->ip = ip; t->trace = next; } @@ -152,6 +149,14 @@ methodForIp(MyThread* t, void* ip) class MyStackWalker: public Processor::StackWalker { public: + enum State { + Start, + Next, + Method, + NativeMethod, + Finish + }; + class MyProtector: public Thread::Protector { public: MyProtector(MyStackWalker* walker): @@ -160,7 +165,6 @@ class MyStackWalker: public Processor::StackWalker { virtual void visit(Heap::Visitor* v) { v->visit(&(walker->method_)); - v->visit(&(walker->nativeMethod)); } MyStackWalker* walker; @@ -168,114 +172,156 @@ class MyStackWalker: public Processor::StackWalker { MyStackWalker(MyThread* t): t(t), - ip_(t->ip ? t->ip : (t->stack ? *static_cast(t->stack) : 0)), + state(Start), + ip_(t->ip), base(t->base), stack(t->stack), trace(t->trace), - nativeMethod(trace ? trace->nativeMethod : 0), - method_(ip_ ? methodForIp(t, ip_) : 0), + method_(0), protector(this) { } MyStackWalker(MyStackWalker* w): t(w->t), + state(w->state), ip_(w->ip_), base(w->base), stack(w->stack), trace(w->trace), - nativeMethod(w->nativeMethod), method_(w->method_), protector(this) { } virtual void walk(Processor::StackVisitor* v) { - if (stack == 0) { - return; - } - - if (not v->visit(this)) { - return; - } - - for (MyStackWalker it(this); it.next();) { + for (MyStackWalker it(this); it.valid();) { MyStackWalker walker(it); if (not v->visit(&walker)) { break; } + it.next(); } } - bool next() { - if (nativeMethod) { - nativeMethod = 0; - } else if (stack) { - stack = static_cast(base) + 1; - base = *static_cast(base); - ip_ = *static_cast(stack); - method_ = methodForIp(t, *static_cast(stack)); - } else { - return false; + bool valid() { + while (true) { +// fprintf(stderr, "state: %d\n", state); + switch (state) { + case Start: + if (ip_ == 0 and stack) { + ip_ = *static_cast(stack); + } + + 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(trace->stack); + ip_ = (stack ? *static_cast(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); + } } + } + + void next() { + switch (state) { + case Method: + stack = static_cast(base) + 1; + ip_ = (stack ? *static_cast(stack) : 0); + base = *static_cast(base); + state = Next; + break; - if (method_ or nativeMethod) { - return true; - } else if (trace and trace->stack) { - base = trace->base; - stack = static_cast(trace->stack); - ip_ = *static_cast(stack); - method_ = methodForIp(t, *static_cast(stack)); - nativeMethod = trace->nativeMethod; + case NativeMethod: trace = trace->next; - - expect(t, method_ or nativeMethod); - return true; - } else { - return false; + state = Next; + break; + + default: + abort(t); } } virtual object method() { - if (nativeMethod) { - return nativeMethod; - } else { + switch (state) { + case Method: return method_; + + case NativeMethod: + return trace->nativeMethod; + + default: + abort(t); } } virtual int ip() { - if (nativeMethod) { - return 0; - } else { + switch (state) { + case Method: return reinterpret_cast(ip_) - reinterpret_cast (&singletonValue(t, methodCompiled(t, method_), 0)); + + case NativeMethod: + return 0; + + default: + abort(t); } } virtual unsigned count() { - class Visitor: public Processor::StackVisitor { - public: - Visitor(): count(0) { } + unsigned count = 0; - virtual bool visit(Processor::StackWalker*) { - ++ count; - return true; - } - - unsigned count; - } v; - - MyStackWalker walker(this); - walker.walk(&v); + for (MyStackWalker walker(this); walker.valid();) { + walker.next(); + ++ count; + } - return v.count; + return count; } MyThread* t; + State state; void* ip_; void* base; void* stack; MyThread::CallTrace* trace; - object nativeMethod; object method_; MyProtector protector; }; @@ -1196,9 +1242,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase, void* ip = t->ip; void* base = t->base; void** stack = static_cast(t->stack); - if (ip) { - t->ip = 0; - } else { + if (ip == 0) { ip = *stack; } @@ -4302,11 +4346,11 @@ invokeNative(MyThread* t) { if (t->trace->nativeMethod == 0) { object node = findCallNode(t, *static_cast(t->stack)); - t->trace->nativeMethod = callNodeTarget(t, node); + object target = callNodeTarget(t, node); if (callNodeVirtualCall(t, node)) { - t->trace->nativeMethod = resolveTarget - (t, t->stack, t->trace->nativeMethod); + target = resolveTarget(t, t->stack, target); } + t->trace->nativeMethod = target; } uint64_t result = 0; @@ -4671,6 +4715,10 @@ class SegFaultHandler: public System::SignalHandler { if (t->state == Thread::ActiveState) { object node = methodForIp(t, *ip); if (node) { + void* oldIp = t->ip; + void* oldBase = t->base; + void* oldStack = t->stack; + t->ip = *ip; t->base = *base; t->stack = *stack; @@ -4682,6 +4730,11 @@ class SegFaultHandler: public System::SignalHandler { t->tracing = false; findUnwindTarget(t, ip, base, stack); + + t->ip = oldIp; + t->base = oldBase; + t->stack = oldStack; + *thread = t; return true; } @@ -5047,6 +5100,7 @@ class MyProcessor: public Processor { or (static_cast(ip) >= native and static_cast(ip) < native + nativeSize)) { + target->ip = *static_cast(stack); target->base = base; target->stack = stack; } diff --git a/src/machine.cpp b/src/machine.cpp index 88220c9a62..7c596c9bf9 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2832,6 +2832,7 @@ makeTrace(Thread* t, Processor::StackWalker* walker) } object e = makeTraceElement(t, walker->method(), walker->ip()); + assert(t, index < arrayLength(t, trace)); set(t, trace, ArrayBody + (index * BytesPerWord), e); ++ index; return true;