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