summaryrefslogtreecommitdiffstats
path: root/runtime/profiler.h
diff options
context:
space:
mode:
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 396dd23..ae51c87 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_;