diff options
Diffstat (limited to 'openjdkjvmti/ti_stack.cc')
| -rw-r--r-- | openjdkjvmti/ti_stack.cc | 90 |
1 files changed, 58 insertions, 32 deletions
diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc index 4a3eac8a15..5de4a81f5e 100644 --- a/openjdkjvmti/ti_stack.cc +++ b/openjdkjvmti/ti_stack.cc @@ -673,24 +673,34 @@ jvmtiError StackUtil::GetThreadListStackTraces(jvmtiEnv* env, return ERR(NONE); } +// Walks up the stack counting Java frames. This is not StackVisitor::ComputeNumFrames, as +// runtime methods and transitions must not be counted. +struct GetFrameCountVisitor : public art::StackVisitor { + explicit GetFrameCountVisitor(art::Thread* thread) + : art::StackVisitor(thread, nullptr, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames), + count(0) {} + + bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) { + art::ArtMethod* m = GetMethod(); + const bool do_count = !(m == nullptr || m->IsRuntimeMethod()); + if (do_count) { + count++; + } + return true; + } + + size_t count; +}; + struct GetFrameCountClosure : public art::Closure { public: GetFrameCountClosure() : count(0) {} void Run(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) { - // This is not StackVisitor::ComputeNumFrames, as runtime methods and transitions must not be - // counted. - art::StackVisitor::WalkStack( - [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(art::Locks::mutator_lock_) { - art::ArtMethod* m = stack_visitor->GetMethod(); - if (m != nullptr && !m->IsRuntimeMethod()) { - count++; - } - return true; - }, - self, - /* context= */ nullptr, - art::StackVisitor::StackWalkKind::kIncludeInlinedFrames); + GetFrameCountVisitor visitor(self); + visitor.WalkStack(false); + + count = visitor.count; } size_t count; @@ -733,30 +743,46 @@ jvmtiError StackUtil::GetFrameCount(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } +// Walks up the stack 'n' callers, when used with Thread::WalkStack. +struct GetLocationVisitor : public art::StackVisitor { + GetLocationVisitor(art::Thread* thread, size_t n_in) + : art::StackVisitor(thread, nullptr, art::StackVisitor::StackWalkKind::kIncludeInlinedFrames), + n(n_in), + count(0), + caller(nullptr), + caller_dex_pc(0) {} + + bool VisitFrame() override REQUIRES_SHARED(art::Locks::mutator_lock_) { + art::ArtMethod* m = GetMethod(); + const bool do_count = !(m == nullptr || m->IsRuntimeMethod()); + if (do_count) { + DCHECK(caller == nullptr); + if (count == n) { + caller = m; + caller_dex_pc = GetDexPc(false); + return false; + } + count++; + } + return true; + } + + const size_t n; + size_t count; + art::ArtMethod* caller; + uint32_t caller_dex_pc; +}; + struct GetLocationClosure : public art::Closure { public: explicit GetLocationClosure(size_t n_in) : n(n_in), method(nullptr), dex_pc(0) {} void Run(art::Thread* self) override REQUIRES_SHARED(art::Locks::mutator_lock_) { - // Walks up the stack 'n' callers. - size_t count = 0u; - art::StackVisitor::WalkStack( - [&](const art::StackVisitor* stack_visitor) REQUIRES_SHARED(art::Locks::mutator_lock_) { - art::ArtMethod* m = stack_visitor->GetMethod(); - if (m != nullptr && !m->IsRuntimeMethod()) { - DCHECK(method == nullptr); - if (count == n) { - method = m; - dex_pc = stack_visitor->GetDexPc(/*abort_on_failure=*/false); - return false; - } - count++; - } - return true; - }, - self, - /* context= */ nullptr, - art::StackVisitor::StackWalkKind::kIncludeInlinedFrames); + GetLocationVisitor visitor(self, n); + visitor.WalkStack(false); + + method = visitor.caller; + dex_pc = visitor.caller_dex_pc; } const size_t n; |