Coverage for /Syzygy/simulate/heat_map_simulation.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
39.0%30770.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    :  #include "syzygy/simulate/heat_map_simulation.h"
  16    :  
  17    :  #include <functional>
  18    :  
  19    :  namespace simulate {
  20    :  
  21    :  HeatMapSimulation::HeatMapSimulation()
  22    :      : time_slice_usecs_(kDefaultTimeSliceSize),
  23    :        memory_slice_bytes_(kDefaultMemorySliceSize),
  24    :        max_time_slice_usecs_(0),
  25    :        max_memory_slice_bytes_(0),
  26  E :        output_individual_functions_(false) {
  27  E :  }
  28    :  
  29    :  bool HeatMapSimulation::TimeSlice::PrintJSONFunctions(
  30    :      core::JSONFileWriter& json_file,
  31  i :      const HeatMapSimulation::TimeSlice::FunctionMap& functions) {
  32    :    typedef std::pair<uint32, base::StringPiece> QtyNamePair;
  33  i :    std::vector<QtyNamePair> ordered_functions(functions.size());
  34    :  
  35  i :    FunctionMap::const_iterator functions_iter = functions.begin();
  36  i :    uint32 i = 0;
  37  i :    for (; functions_iter != functions.end(); ++functions_iter, ++i) {
  38    :      ordered_functions[i] = QtyNamePair(functions_iter->second,
  39  i :                                         functions_iter->first);
  40  i :    }
  41    :    std::sort(ordered_functions.begin(),
  42    :              ordered_functions.end(),
  43  i :              std::greater<QtyNamePair>());
  44    :  
  45    :    if (!json_file.OutputKey("functions") ||
  46  i :        !json_file.OpenList())
  47  i :      return false;
  48    :  
  49  i :    for (uint32 i = 0; i < ordered_functions.size(); ++i) {
  50    :      if (!json_file.OpenDict() ||
  51    :          !json_file.OutputKey("name") ||
  52    :          !json_file.OutputString(ordered_functions[i].second.data()) ||
  53    :          !json_file.OutputKey("quantity") ||
  54    :          !json_file.OutputInteger(ordered_functions[i].first) ||
  55  i :          !json_file.CloseDict())
  56  i :        return false;
  57  i :    }
  58    :  
  59  i :    if (!json_file.CloseList())
  60  i :      return false;
  61    :  
  62  i :    return true;
  63  i :  }
  64    :  
  65  i :  bool HeatMapSimulation::SerializeToJSON(FILE* output, bool pretty_print) {
  66    :    typedef TimeSlice::FunctionMap FunctionMap;
  67    :  
  68  i :    DCHECK(output != NULL);
  69    :  
  70  i :    core::JSONFileWriter json_file(output, pretty_print);
  71    :  
  72    :    if (!json_file.OpenDict() ||
  73    :        !json_file.OutputKey("time_slice_usecs") ||
  74    :        !json_file.OutputInteger(time_slice_usecs_) ||
  75    :        !json_file.OutputKey("memory_slice_bytes") ||
  76    :        !json_file.OutputInteger(memory_slice_bytes_) ||
  77    :        !json_file.OutputKey("max_time_slice_usecs") ||
  78    :        !json_file.OutputInteger(max_time_slice_usecs_) ||
  79    :        !json_file.OutputKey("max_memory_slice_bytes") ||
  80    :        !json_file.OutputInteger(max_memory_slice_bytes_) ||
  81    :        !json_file.OutputKey("time_slice_list") ||
  82  i :        !json_file.OpenList()) {
  83  i :      return false;
  84    :    }
  85    :  
  86  i :    TimeMemoryMap::const_iterator time_memory_iter = time_memory_map_.begin();
  87  i :    for (; time_memory_iter != time_memory_map_.end(); ++time_memory_iter) {
  88  i :      time_t time = time_memory_iter->first;
  89  i :      uint32 total = time_memory_iter->second.total();
  90  i :      const TimeSlice& time_slice = time_memory_iter->second;
  91    :  
  92    :      if (!json_file.OpenDict() ||
  93    :          !json_file.OutputKey("timestamp") ||
  94    :          !json_file.OutputInteger(time) ||
  95    :          !json_file.OutputKey("total_memory_slices") ||
  96    :          !json_file.OutputInteger(total) ||
  97    :          !json_file.OutputKey("memory_slice_list") ||
  98  i :          !json_file.OpenList()) {
  99  i :        return false;
 100    :      }
 101    :  
 102    :      TimeSlice::MemorySliceMap::const_iterator slices_iter =
 103  i :          time_slice.slices().begin();
 104    :  
 105  i :      for (; slices_iter != time_slice.slices().end(); ++slices_iter) {
 106    :        if (!json_file.OpenDict() ||
 107    :            !json_file.OutputKey("memory_slice") ||
 108    :            !json_file.OutputInteger(slices_iter->first) ||
 109    :            !json_file.OutputKey("quantity") ||
 110  i :            !json_file.OutputInteger(slices_iter->second.total))
 111  i :          return false;
 112    :  
 113  i :        if (output_individual_functions_) {
 114    :          if (!TimeSlice::PrintJSONFunctions(json_file,
 115  i :                                             slices_iter->second.functions))
 116  i :            return false;
 117    :        }
 118    :  
 119  i :        if (!json_file.CloseDict())
 120  i :          return false;
 121  i :      }
 122    :  
 123    :      if (!json_file.CloseList() ||
 124  i :          !json_file.CloseDict())
 125  i :        return false;
 126  i :    }
 127    :  
 128    :    if (!json_file.CloseList() ||
 129  i :        !json_file.CloseDict())
 130  i :      return false;
 131    :  
 132  i :    return json_file.Finished();
 133  i :  }
 134    :  
 135    :  void HeatMapSimulation::OnProcessStarted(base::Time time,
 136  E :                                           size_t /*default_page_size*/) {
 137    :    // Set the entry time of this process.
 138  E :    process_start_time_ = time;
 139  E :  }
 140    :  
 141    :  void HeatMapSimulation::OnFunctionEntry(base::Time time,
 142  E :                                          const Block* block) {
 143    :    // Get the time when this function was called since the process start.
 144  E :    time_t relative_time = (time - process_start_time_).InMicroseconds();
 145    :  
 146    :    // Since we will insert to a map many TimeSlices with the same entry time,
 147    :    // we can pass RegisterFunction a reference to the TimeSlice in the map.
 148    :    // This way, RegisterFunction doesn't have to search for that position
 149    :    // every time it gets called and the time complexity gets reduced
 150    :    // in a logarithmic scale.
 151  E :    TimeSliceId time_slice = relative_time / time_slice_usecs_;
 152  E :    TimeSlice& slice = time_memory_map_[time_slice];
 153    :  
 154  E :    max_time_slice_usecs_ = std::max(max_time_slice_usecs_, time_slice);
 155    :  
 156  E :    DCHECK(block != NULL);
 157  E :    DCHECK(memory_slice_bytes_ != 0);
 158  E :    const uint32 block_start = block->addr().value();
 159  E :    const uint32 size = block->size();
 160  E :    const std::string& name = block->name();
 161    :  
 162  E :    const uint32 first_slice = block_start / memory_slice_bytes_;
 163  E :    const uint32 last_slice = (block_start + size - 1) / memory_slice_bytes_;
 164  E :    if (first_slice == last_slice) {
 165    :      // This function fits in a single memory slice. Add it to our time slice.
 166  E :      slice.AddSlice(first_slice, name, size);
 167  E :    } else {
 168    :      // This function takes several memory slices. Add the first and last
 169    :      // slices to our time slice only with the part of the slice they use,
 170    :      // and then loop through the rest and add the whole slices.
 171    :      const uint32 leading_bytes =
 172  E :          memory_slice_bytes_ - block_start % memory_slice_bytes_;
 173    :  
 174    :      const uint32 trailing_bytes =
 175    :          ((block_start + size - 1 + memory_slice_bytes_) %
 176  E :              memory_slice_bytes_) + 1;
 177    :  
 178  E :      slice.AddSlice(first_slice, name, leading_bytes);
 179  E :      slice.AddSlice(last_slice, name, trailing_bytes);
 180    :  
 181  E :      const uint32 kStartIndex = block_start / memory_slice_bytes_ + 1;
 182  E :      const uint32 kEndIndex = (block_start + size - 1) / memory_slice_bytes_;
 183    :  
 184  E :      for (uint32 i = kStartIndex; i < kEndIndex; i++)
 185  E :        slice.AddSlice(i, name, memory_slice_bytes_);
 186    :    }
 187    :  
 188  E :    max_memory_slice_bytes_ = std::max(max_memory_slice_bytes_, last_slice);
 189  E :  }
 190    :  
 191    :  }  // namespace simulate

Coverage information generated Thu Jan 14 17:40:38 2016.