summaryrefslogtreecommitdiffstats
path: root/runtime/profiler.h
diff options
context:
space:
mode:
authorWei Jin <wejin@google.com>2014-06-20 15:56:53 -0700
committerCalin Juravle <calin@google.com>2014-06-27 15:40:06 +0100
commit445220d4fe5bd9f0616d6da2322a7b6e9466595e (patch)
treec90c4014739e12d29f7801368bbb67a44aa63357 /runtime/profiler.h
parent6c22b193fb5fe71124846fa2c1d73f1670419476 (diff)
downloadart-445220d4fe5bd9f0616d6da2322a7b6e9466595e.tar.gz
art-445220d4fe5bd9f0616d6da2322a7b6e9466595e.tar.bz2
art-445220d4fe5bd9f0616d6da2322a7b6e9466595e.zip
Add a new type of profile data in ART profiler
This CL allows the ART profiler to collect bounded stack information that contains only method signature and dex pc on the current stack frames to a bounded depth. The type of the profile data is by default disabled, and can be enabled by setting the option "-Xprofile-type:stack". The bound is controlled by the option "-Xprofile-max-stack-depth:integervalue". Change-Id: Ieab789951018b2263c4d140b40b6c73bffc6a549
Diffstat (limited to 'runtime/profiler.h')
-rw-r--r--runtime/profiler.h78
1 files changed, 68 insertions, 10 deletions
diff --git a/runtime/profiler.h b/runtime/profiler.h
index 396dd23fe3..ae51c87ce9 100644
--- a/runtime/profiler.h
+++ b/runtime/profiler.h
@@ -31,6 +31,7 @@
#include "profiler_options.h"
#include "os.h"
#include "safe_map.h"
+#include "method_reference.h"
namespace art {
@@ -40,6 +41,57 @@ namespace mirror {
} // namespace mirror
class Thread;
+typedef std::pair<mirror::ArtMethod*, uint32_t> InstructionLocation;
+
+// This class stores the sampled bounded stacks in a trie structure. A path of the trie represents
+// a particular context with the method on top of the stack being a leaf or an internal node of the
+// trie rather than the root.
+class StackTrieNode {
+ public:
+ StackTrieNode(MethodReference method, uint32_t dex_pc, uint32_t method_size,
+ StackTrieNode* parent) :
+ parent_(parent), method_(method), dex_pc_(dex_pc),
+ count_(0), method_size_(method_size) {
+ }
+ StackTrieNode() : parent_(nullptr), method_(nullptr, 0),
+ dex_pc_(0), count_(0), method_size_(0) {
+ }
+ StackTrieNode* GetParent() { return parent_; }
+ MethodReference GetMethod() { return method_; }
+ uint32_t GetCount() { return count_; }
+ uint32_t GetDexPC() { return dex_pc_; }
+ uint32_t GetMethodSize() { return method_size_; }
+ void AppendChild(StackTrieNode* child) { children_.insert(child); }
+ StackTrieNode* FindChild(MethodReference method, uint32_t dex_pc);
+ void DeleteChildren();
+ void IncreaseCount() { ++count_; }
+
+ private:
+ // Comparator for stack trie node.
+ struct StackTrieNodeComparator {
+ bool operator()(StackTrieNode* node1, StackTrieNode* node2) const {
+ MethodReference mr1 = node1->GetMethod();
+ MethodReference mr2 = node2->GetMethod();
+ if (mr1.dex_file == mr2.dex_file) {
+ if (mr1.dex_method_index == mr2.dex_method_index) {
+ return node1->GetDexPC() < node2->GetDexPC();
+ } else {
+ return mr1.dex_method_index < mr2.dex_method_index;
+ }
+ } else {
+ return mr1.dex_file < mr2.dex_file;
+ }
+ }
+ };
+
+ std::set<StackTrieNode*, StackTrieNodeComparator> children_;
+ StackTrieNode* parent_;
+ MethodReference method_;
+ uint32_t dex_pc_;
+ uint32_t count_;
+ uint32_t method_size_;
+};
+
//
// This class holds all the results for all runs of the profiler. It also
// counts the number of null methods (where we can't determine the method) and
@@ -53,7 +105,7 @@ class ProfileSampleResults {
~ProfileSampleResults();
void Put(mirror::ArtMethod* method);
- void PutDexPC(mirror::ArtMethod* method, uint32_t pc);
+ void PutStack(const std::vector<InstructionLocation>& stack_dump);
uint32_t Write(std::ostream &os, ProfileDataType type);
void ReadPrevious(int fd, ProfileDataType type);
void Clear();
@@ -72,18 +124,21 @@ class ProfileSampleResults {
typedef std::map<mirror::ArtMethod*, uint32_t> Map; // Map of method vs its count.
Map *table[kHashSize];
- typedef std::map<uint32_t, uint32_t> DexPCCountMap; // Map of dex pc vs its count
- // Map of method vs dex pc counts in the method.
- typedef std::map<mirror::ArtMethod*, DexPCCountMap*> MethodDexPCMap;
- MethodDexPCMap *dex_table[kHashSize];
+ typedef std::set<StackTrieNode*> TrieNodeSet;
+ // Map of method hit by profiler vs the set of stack trie nodes for this method.
+ typedef std::map<MethodReference, TrieNodeSet*, MethodReferenceComparator> MethodContextMap;
+ MethodContextMap *method_context_table;
+ StackTrieNode* stack_trie_root_; // Root of the trie that stores sampled stack information.
+ // Map from <pc, context> to counts.
+ typedef std::map<std::pair<uint32_t, std::string>, uint32_t> PreviousContextMap;
struct PreviousValue {
- PreviousValue() : count_(0), method_size_(0), dex_pc_map_(nullptr) {}
- PreviousValue(uint32_t count, uint32_t method_size, DexPCCountMap* dex_pc_map)
- : count_(count), method_size_(method_size), dex_pc_map_(dex_pc_map) {}
+ PreviousValue() : count_(0), method_size_(0), context_map_(nullptr) {}
+ PreviousValue(uint32_t count, uint32_t method_size, PreviousContextMap* context_map)
+ : count_(count), method_size_(method_size), context_map_(context_map) {}
uint32_t count_;
uint32_t method_size_;
- DexPCCountMap* dex_pc_map_;
+ PreviousContextMap* context_map_;
};
typedef std::map<std::string, PreviousValue> PreviousProfile;
@@ -121,7 +176,10 @@ class BackgroundMethodSamplingProfiler {
static void Stop() LOCKS_EXCLUDED(Locks::profiler_lock_, wait_lock_);
static void Shutdown() LOCKS_EXCLUDED(Locks::profiler_lock_);
- void RecordMethod(mirror::ArtMethod *method, uint32_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void RecordMethod(mirror::ArtMethod *method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void RecordStack(const std::vector<InstructionLocation>& stack) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool ProcessMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const ProfilerOptions& GetProfilerOptions() const { return options_; }
Barrier& GetBarrier() {
return *profiler_barrier_;