16a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes/* 26a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 36a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * 46a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 56a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * you may not use this file except in compliance with the License. 66a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * You may obtain a copy of the License at 76a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * 86a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 96a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * 106a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * Unless required by applicable law or agreed to in writing, software 116a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 126a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * See the License for the specific language governing permissions and 146a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes * limitations under the License. 156a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes */ 166a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_NTH_CALLER_VISITOR_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_NTH_CALLER_VISITOR_H_ 196a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 20e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method.h" 21719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h" 222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "stack.h" 236a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 246a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughesnamespace art { 252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Thread; 266a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 276a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes// Walks up the stack 'n' callers, when used with Thread::WalkStack. 280399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogersstruct NthCallerVisitor : public StackVisitor { 29277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe NthCallerVisitor(Thread* thread, size_t n_in, bool include_runtime_and_upcalls = false) 308e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), 318e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray n(n_in), 328e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray include_runtime_and_upcalls_(include_runtime_and_upcalls), 338e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray count(0), 348e5bd18fc665d7ec5461ea068e98740a65da754cNicolas Geoffray caller(nullptr) {} 3562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 3690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) { 37e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* m = GetMethod(); 3862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool do_count = false; 392cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (m == nullptr || m->IsRuntimeMethod()) { 4062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Upcall. 4162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers do_count = include_runtime_and_upcalls_; 4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } else { 4362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers do_count = true; 4462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 4562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (do_count) { 462cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier DCHECK(caller == nullptr); 4762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (count == n) { 4862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers caller = m; 4962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return false; 5062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 5162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers count++; 526a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes } 536a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes return true; 546a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes } 5508fc03ae5dded4adc9b45b7014a4b9dfedbe95a6Elliott Hughes 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const size_t n; 5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const bool include_runtime_and_upcalls_; 586a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes size_t count; 59e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* caller; 606a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes}; 616a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 626a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes} // namespace art 636a144338023bdc0ca6954fc71a1f9b4d94088ee4Elliott Hughes 64fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_NTH_CALLER_VISITOR_H_ 65