Home | History | Annotate | Download | only in src
      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:
     34     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:
     53     Mapping() {}
     54   };
     55 
     56   struct Location {
     57     Location() : ip(0), mapping(nullptr) {}
     58 
     59     uint64 ip;
     60     const Mapping* mapping;
     61   };
     62 
     63   struct BranchStackPair {
     64     BranchStackPair() : mispredicted(false) {}
     65 
     66     Location from;
     67     Location to;
     68     bool mispredicted;
     69   };
     70 
     71   struct SampleContext {
     72     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 
    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