• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016, Google Inc.
3  * All rights reserved.
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef PERFTOOLS_PERF_DATA_HANDLER_H_
9 #define PERFTOOLS_PERF_DATA_HANDLER_H_
10 
11 #include <vector>
12 
13 #include "int_compat.h"
14 #include "string_compat.h"
15 #include "quipper/perf_data.pb.h"
16 
17 namespace perftools {
18 
19 // PerfDataHandler defines an interface for processing PerfDataProto
20 // with normalized sample fields (i.e., materializing mappings,
21 // filenames, and build-ids).
22 //
23 // To use, subclass PerfDataHandler and implement the required
24 // methods, then call Process() and handler will be called for every
25 // SAMPLE event.
26 //
27 // Context events' pointers to Mappings will be constant for the lifetime of a
28 // process, so subclasses may use the pointer values as a key to various caches
29 // they may want to maintain as part of the output data creation.
30 class PerfDataHandler {
31  public:
32   struct Mapping {
33    public:
MappingMapping34     Mapping(const string* filename, const string* build_id, uint64 start,
35             uint64 limit, uint64 file_offset, uint64 filename_md5_prefix)
36         : filename(filename),
37           build_id(build_id),
38           start(start),
39           limit(limit),
40           file_offset(file_offset),
41           filename_md5_prefix(filename_md5_prefix) {}
42 
43     // filename and build_id are pointers into the provided
44     // PerfDataProto and may be nullptr.
45     const string* filename;
46     const string* build_id;
47     uint64 start;
48     uint64 limit;  // limit=ceiling.
49     uint64 file_offset;
50     uint64 filename_md5_prefix;
51 
52    private:
MappingMapping53     Mapping() {}
54   };
55 
56   struct Location {
LocationLocation57     Location() : ip(0), mapping(nullptr) {}
58 
59     uint64 ip;
60     const Mapping* mapping;
61   };
62 
63   struct BranchStackPair {
BranchStackPairBranchStackPair64     BranchStackPair() : mispredicted(false) {}
65 
66     Location from;
67     Location to;
68     bool mispredicted;
69   };
70 
71   struct SampleContext {
SampleContextSampleContext72     SampleContext(const quipper::PerfDataProto::EventHeader &h,
73                   const quipper::PerfDataProto::SampleEvent &s)
74         : header(h),
75           sample(s),
76           main_mapping(nullptr),
77           sample_mapping(nullptr),
78           file_attrs_index(-1) {}
79 
80     // The event's header.
81     const quipper::PerfDataProto::EventHeader &header;
82     // An event.
83     const quipper::PerfDataProto::SampleEvent &sample;
84     // The mapping for the main binary for this program.
85     const Mapping* main_mapping;
86     // The mapping in which event.ip is found.
87     const Mapping* sample_mapping;
88     // Locations corresponding to event.callchain.
89     std::vector<Location> callchain;
90     // Locations corresponding to entries in event.branch_stack.
91     std::vector<BranchStackPair> branch_stack;
92     // An index into PerfDataProto.file_attrs or -1 if
93     // unavailable.
94     int64 file_attrs_index;
95   };
96 
97   struct CommContext {
98     // A comm event.
99     const quipper::PerfDataProto::CommEvent* comm;
100   };
101 
102   struct MMapContext {
103     // A memory mapping to be passed to the subclass. Should be the same mapping
104     // that gets added to pid_to_mmaps_.
105     const PerfDataHandler::Mapping* mapping;
106     // The process id used as a key to pid_to_mmaps_.
107     uint32 pid;
108   };
109 
110   PerfDataHandler(const PerfDataHandler&) = delete;
111   PerfDataHandler& operator=(const PerfDataHandler&) = delete;
112 
113   // Process initiates processing of perf_proto.  handler.Sample will
114   // be called for every event in the profile.
115   static void Process(const quipper::PerfDataProto& perf_data,
116                       PerfDataHandler* handler);
117 
~PerfDataHandler()118   virtual ~PerfDataHandler() {}
119 
120   // Implement these callbacks:
121   // Called for every sample.
122   virtual void Sample(const SampleContext& sample) = 0;
123   // When comm.pid()==comm.tid() it indicates an exec() happened.
124   virtual void Comm(const CommContext& comm) = 0;
125   // Called for every mmap event.
126   virtual void MMap(const MMapContext& mmap) = 0;
127 
128  protected:
129   PerfDataHandler();
130 };
131 
132 }  // namespace perftools
133 
134 #endif  // PERFTOOLS_PERF_DATA_HANDLER_H_
135