Coverage for /Syzygy/simulate/heat_map_simulation.h

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
100.0%27270.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // This file declares the HeatMapSimulation class.
  16    :  
  17    :  
  18    :  #ifndef SYZYGY_SIMULATE_HEAT_MAP_SIMULATION_H_
  19    :  #define SYZYGY_SIMULATE_HEAT_MAP_SIMULATION_H_
  20    :  
  21    :  #include <map>
  22    :  
  23    :  #include "base/string_piece.h"
  24    :  #include "syzygy/core/json_file_writer.h"
  25    :  #include "syzygy/simulate/simulation_event_handler.h"
  26    :  #include "syzygy/trace/parse/parser.h"
  27    :  
  28    :  namespace simulate {
  29    :  
  30    :  // An implementation of SimulationEventHandler.
  31    :  // HeatMapSimulation parses trace events, gathers the code blocks from them,
  32    :  // and organizes those by the number of times each memory slice of a given
  33    :  // size, in bytes, was called during a time slice of a given size,
  34    :  // in microseconds.
  35    :  //
  36    :  // HeatMapSimulation simulation;
  37    :  //
  38    :  // simulation.set_time_slice_usecs(5);
  39    :  // simulation.set_memory_slice_bytes(0x4000);
  40    :  // simulation.OnProcessStarted(time, 0);
  41    :  // simulation.OnFunctionEntry(times[0], 0, 5);
  42    :  // simulation.OnFunctionEntry(times[1], 3, 200);
  43    :  // simulation.SerializeToJSON(file, pretty_print);
  44    :  //
  45    :  // If the time slice size or the memory slice size are not set, the default
  46    :  // values of 1 and 0x8000, respectively, are used.
  47    :  class HeatMapSimulation : public SimulationEventHandler {
  48    :   public:
  49    :    class TimeSlice;
  50    :  
  51    :    typedef block_graph::BlockGraph::Block Block;
  52    :    typedef time_t TimeSliceId;
  53    :    typedef std::map<TimeSliceId, TimeSlice> TimeMemoryMap;
  54    :    typedef uint32 MemorySliceId;
  55    :  
  56    :    // The default time and memory slice sizes.
  57    :    static const uint32 kDefaultTimeSliceSize = 1;
  58    :    static const uint32 kDefaultMemorySliceSize = 0x8000;
  59    :  
  60    :    // Construct a new HeatMapSimulation instance.
  61    :    HeatMapSimulation();
  62    :  
  63    :    // @name Accessors.
  64    :    // @{
  65  E :    const TimeMemoryMap& time_memory_map() const { return time_memory_map_; }
  66    :    uint32 time_slice_usecs() const { return time_slice_usecs_; }
  67    :    uint32 memory_slice_bytes() const { return memory_slice_bytes_; }
  68  E :    TimeSliceId max_time_slice_usecs() const { return max_time_slice_usecs_; }
  69  E :    MemorySliceId max_memory_slice_bytes() const {
  70  E :      return max_memory_slice_bytes_;
  71  E :    }
  72    :    // @}
  73    :  
  74    :    // @name Mutators.
  75    :    // @{
  76    :    // Set the size of time slices used in the heat map.
  77    :    // @param time_slice_usecs The size used, in microseconds.
  78  E :    void set_time_slice_usecs(uint32 time_slice_usecs) {
  79  E :      DCHECK_LT(0u, time_slice_usecs);
  80  E :      time_slice_usecs_ = time_slice_usecs;
  81  E :    }
  82    :    // Set the size of the memory slices used in the heat map.
  83    :    // @param memory_slice_bytes The size used, in bytes.
  84  E :    void set_memory_slice_bytes(uint32 memory_slice_bytes) {
  85  E :      DCHECK_LT(0u, memory_slice_bytes);
  86  E :      memory_slice_bytes_ = memory_slice_bytes;
  87  E :    }
  88    :    // Set whether SerializeToJSON outputs information about each individual
  89    :    // function in each time/memory block.
  90    :    // @param print_output_individual_functions true for saving the names of each
  91    :    //     function, false otherwise.
  92  E :    void set_output_individual_functions(bool output_individual_functions) {
  93  E :      output_individual_functions_ = output_individual_functions;
  94  E :    }
  95    :    // @}
  96    :  
  97    :    // @name SimulationEventHandler implementation
  98    :    // @{
  99    :    // Sets the entry time of the trace file.
 100    :    // @param time The startup time of the execution.
 101    :    void OnProcessStarted(base::Time time, size_t default_page_size) OVERRIDE;
 102    :  
 103    :    // Adds a group of code blocks corresponding to one function
 104    :    // to time_memory_map_.
 105    :    // @param time The entry time of the function.
 106    :    // @param block_start The start start of the function.
 107    :    // @param size The size of the function.
 108    :    void OnFunctionEntry(base::Time time, const Block* block) OVERRIDE;
 109    :  
 110    :    // Serializes the data to JSON.
 111    :    // The serialization consists of a list containing a dictionary of each
 112    :    // timestamp, and the total number of memory slices used, during that
 113    :    // time slice, and of another list with dictionaries containing each
 114    :    // separate memory slice, the number of times it was used, and a list
 115    :    // of all the used functions and the number of times they were used in that
 116    :    // memory slice in descending order. If output_individual_functions is true,
 117    :    // then the list of function for each memory slice isn't printed. Example:
 118    :    // {
 119    :    //   "time_slice_usecs": 1,
 120    :    //   "memory_slice_bytes": 32768,
 121    :    //   "time_slice_list": [
 122    :    //     {
 123    :    //       "timestamp": 31,
 124    :    //       "total_memory_slices": 1052,
 125    :    //       "memory_slice_list": [
 126    :    //         {
 127    :    //           "memory_slice": 4,
 128    :    //           "quantity": 978,
 129    :    //           "functions": [
 130    :    //             {
 131    :    //               "name": "_flush",
 132    :    //               "quantity": 561
 133    :    //             },
 134    :    //             {
 135    :    //               "name": "flsall",
 136    :    //               "quantity": 417
 137    :    //             }
 138    :    //           ]
 139    :    //         },
 140    :    //         {
 141    :    //           "memory_slice": 13,
 142    :    //           "quantity": 74,
 143    :    //           "functions": [
 144    :    //             {
 145    :    //               "name": "_RTC_Terminate",
 146    :    //               "quantity": 38
 147    :    //             },
 148    :    //             {
 149    :    //              "name": "_CrtDefaultAllocHook",
 150    :    //              "quantity": 36
 151    :    //             }
 152    :    //           ]
 153    :    //         }
 154    :    //       ]
 155    :    //     },
 156    :    //     {
 157    :    //       "timestamp": 33,
 158    :    //       "total_memory_slices": 105,
 159    :    //       "memory_slice_list": [
 160    :    //         {
 161    :    //           "memory_slice": 0,
 162    :    //           "quantity": 105,
 163    :    //           "functions": [
 164    :    //             {
 165    :    //               "name": "rand",
 166    :    //               "quantity": 105
 167    :    //             }
 168    :    //           ]
 169    :    //         }
 170    :    //       ]
 171    :    //     }
 172    :    //   ]
 173    :    // }
 174    :    // @param output the file to be written to.
 175    :    // @param pretty_print enables or disables pretty printing.
 176    :    // @returns true on success, false on failure.
 177    :    bool SerializeToJSON(FILE* output, bool pretty_print);
 178    :    // @}
 179    :  
 180    :   protected:
 181    :    // The size of each time block on the heat map, in microseconds.
 182    :    uint32 time_slice_usecs_;
 183    :  
 184    :    // The size of each memory block on the heat map, in bytes.
 185    :    uint32 memory_slice_bytes_;
 186    :  
 187    :    // A map which contains the density of each pair of time and memory slices.
 188    :    // TODO(fixman): If there aren't many possible relative times,
 189    :    // this will probably be better off as a vector.
 190    :    TimeMemoryMap time_memory_map_;
 191    :  
 192    :    // The time when the process was started. Used to convert absolute function
 193    :    // entry times to relative times since start of process.
 194    :    base::Time process_start_time_;
 195    :  
 196    :    // The number of the last time and memory slice, respectively.
 197    :    TimeSliceId max_time_slice_usecs_;
 198    :    MemorySliceId max_memory_slice_bytes_;
 199    :  
 200    :    // If set to true, SerializeToJSON outputs information about each function
 201    :    // in each time/memory block. This gives more information and is useful
 202    :    // for analysis, but may make the output files excessively big.
 203    :    bool output_individual_functions_;
 204    :  };
 205    :  
 206    :  // Stores the respective memory slices of a particular time slice in a map.
 207    :  class HeatMapSimulation::TimeSlice {
 208    :   public:
 209    :    typedef std::map<std::string, uint32> FunctionMap;
 210    :  
 211    :    struct MemorySlice {
 212    :      FunctionMap functions;
 213    :      uint32 total;
 214    :  
 215  E :      MemorySlice() : total(0) {
 216  E :      }
 217    :    };
 218    :    typedef std::map<MemorySliceId, MemorySlice> MemorySliceMap;
 219    :  
 220  E :    TimeSlice() : total_(0) {
 221  E :    }
 222    :  
 223    :    // Add a quantity of bytes to a memory slice to the counter.
 224    :    // @param slice The relative code block number.
 225    :    // @param name The name of the function which uses the memory slice.
 226    :    // @param num_bytes The value to be added, in bytes.
 227    :    void AddSlice(MemorySliceId slice,
 228    :                  const base::StringPiece& name,
 229  E :                  uint32 num_bytes) {
 230  E :      slices_[slice].functions[name.as_string()] += num_bytes;
 231  E :      slices_[slice].total += num_bytes;
 232  E :      total_ += num_bytes;
 233  E :    }
 234    :  
 235    :    // @name Accessors.
 236    :    // @{
 237  E :    const MemorySliceMap& slices() const { return slices_; }
 238  E :    uint32 total() const { return total_; }
 239    :    // @}
 240    :  
 241    :    // Serialize a FunctionMap to a JSON file, sorted by bytes occupied by
 242    :    // each function.
 243    :    // @param json_file The file where the functions will be serialized.
 244    :    // @param functions The given functions.
 245    :    // @return true on success, false on failure.
 246    :    static bool PrintJSONFunctions(core::JSONFileWriter& json_file,
 247    :                                   const FunctionMap& functions);
 248    :  
 249    :   protected:
 250    :    // The slices that were accumulated at this time, and how many times
 251    :    // they were called.
 252    :    MemorySliceMap slices_;
 253    :  
 254    :    // The total number of blocks that were called at this time.
 255    :    uint32 total_;
 256    :  };
 257    :  
 258    :  } // namespace simulate
 259    :  
 260    :  #endif  // SYZYGY_SIMULATE_HEAT_MAP_SIMULATION_H_

Coverage information generated Thu Jul 04 09:34:53 2013.