aboutsummaryrefslogtreecommitdiff
path: root/heatmaps/heat_map.py
diff options
context:
space:
mode:
Diffstat (limited to 'heatmaps/heat_map.py')
-rwxr-xr-xheatmaps/heat_map.py206
1 files changed, 0 insertions, 206 deletions
diff --git a/heatmaps/heat_map.py b/heatmaps/heat_map.py
deleted file mode 100755
index a3c52369..00000000
--- a/heatmaps/heat_map.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2015 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Wrapper to generate heat maps for chrome."""
-
-
-import argparse
-import os
-import shutil
-import sys
-import tempfile
-
-from cros_utils import command_executer
-from heatmaps import heatmap_generator
-
-
-def IsARepoRoot(directory):
- """Returns True if directory is the root of a repo checkout."""
- return os.path.exists(
- os.path.join(os.path.realpath(os.path.expanduser(directory)), ".repo")
- )
-
-
-class HeatMapProducer(object):
- """Class to produce heat map."""
-
- def __init__(
- self, chromeos_root, perf_data, hugepage, binary, title, logger=None
- ):
- self.chromeos_root = os.path.realpath(os.path.expanduser(chromeos_root))
- self.perf_data = os.path.realpath(os.path.expanduser(perf_data))
- self.hugepage = hugepage
- self.dir = os.path.dirname(os.path.realpath(__file__))
- self.binary = binary
- self.ce = command_executer.GetCommandExecuter()
- self.temp_dir = ""
- self.temp_perf_inchroot = ""
- self.temp_dir_created = False
- self.perf_report = ""
- self.title = title
- self.logger = logger
-
- def _EnsureFileInChroot(self):
- chroot_prefix = os.path.join(self.chromeos_root, "chroot")
- if self.perf_data.startswith(chroot_prefix):
- # If the path to perf_data starts with the same chromeos_root, assume
- # it's in the chromeos_root so no need for temporary directory and copy.
- self.temp_dir = self.perf_data.replace("perf.data", "")
- self.temp_perf_inchroot = self.temp_dir.replace(chroot_prefix, "")
-
- else:
- # Otherwise, create a temporary directory and copy perf.data into chroot.
- self.temp_dir = tempfile.mkdtemp(
- prefix=os.path.join(self.chromeos_root, "src/")
- )
- temp_perf = os.path.join(self.temp_dir, "perf.data")
- shutil.copy2(self.perf_data, temp_perf)
- self.temp_perf_inchroot = os.path.join(
- "~/trunk/src", os.path.basename(self.temp_dir)
- )
- self.temp_dir_created = True
-
- def _GeneratePerfReport(self):
- cmd = (
- "cd %s && perf report -D -i perf.data > perf_report.txt"
- % self.temp_perf_inchroot
- )
- retval = self.ce.ChrootRunCommand(self.chromeos_root, cmd)
- if retval:
- raise RuntimeError("Failed to generate perf report")
- self.perf_report = os.path.join(self.temp_dir, "perf_report.txt")
-
- def _GetHeatMap(self, top_n_pages):
- generator = heatmap_generator.HeatmapGenerator(
- perf_report=self.perf_report,
- page_size=4096,
- hugepage=self.hugepage,
- title=self.title,
- )
- generator.draw()
- # Analyze top N hottest symbols with the binary, if provided
- if self.binary:
- generator.analyze(self.binary, top_n_pages)
-
- def _RemoveFiles(self):
- files = [
- "out.txt",
- "inst-histo.txt",
- "inst-histo-hp.txt",
- "inst-histo-sp.txt",
- ]
- for f in files:
- if os.path.exists(f):
- os.remove(f)
-
- def Run(self, top_n_pages):
- try:
- self._EnsureFileInChroot()
- self._GeneratePerfReport()
- self._GetHeatMap(top_n_pages)
- finally:
- self._RemoveFiles()
- msg = (
- "heat map and time histogram genereated in the current "
- "directory with name heat_map.png and timeline.png "
- "accordingly."
- )
- if self.binary:
- msg += (
- "\nThe hottest %d pages inside and outside hugepage "
- "is symbolized and saved to addr2symbol.txt" % top_n_pages
- )
- if self.logger:
- self.logger.LogOutput(msg)
- else:
- print(msg)
-
-
-def main(argv):
- """Parse the options.
-
- Args:
- argv: The options with which this script was invoked.
-
- Returns:
- 0 unless an exception is raised.
- """
- parser = argparse.ArgumentParser()
-
- parser.add_argument(
- "--chromeos_root",
- dest="chromeos_root",
- required=True,
- help="ChromeOS root to use for generate heatmaps.",
- )
- parser.add_argument(
- "--perf_data",
- dest="perf_data",
- required=True,
- help="The raw perf data. Must be collected with -e instructions while "
- "disabling ASLR.",
- )
- parser.add_argument(
- "--binary",
- dest="binary",
- help="The path to the Chrome binary. Only useful if want to print "
- "symbols on hottest pages",
- default=None,
- )
- parser.add_argument(
- "--top_n",
- dest="top_n",
- type=int,
- default=10,
- help="Print out top N hottest pages within/outside huge page range. "
- "Must be used with --hugepage and --binary. (Default: %(default)s)",
- )
- parser.add_argument(
- "--title", dest="title", help="Title of the heatmap", default=""
- )
- parser.add_argument(
- "--hugepage",
- dest="hugepage",
- help="A range of addresses (start,end) where huge page starts and ends"
- " in text section, separated by a comma."
- " Used to differentiate regions in heatmap."
- " Example: --hugepage=0,4096"
- " If not specified, no effect on the heatmap.",
- default=None,
- )
-
- options = parser.parse_args(argv)
-
- if not IsARepoRoot(options.chromeos_root):
- parser.error("%s does not contain .repo dir." % options.chromeos_root)
-
- if not os.path.isfile(options.perf_data):
- parser.error("Cannot find perf_data: %s." % options.perf_data)
-
- hugepage_range = None
- if options.hugepage:
- hugepage_range = options.hugepage.split(",")
- if len(hugepage_range) != 2 or int(hugepage_range[0]) > int(
- hugepage_range[1]
- ):
- parser.error(
- "Wrong format of hugepage range: %s" % options.hugepage
- )
- hugepage_range = [int(x) for x in hugepage_range]
-
- heatmap_producer = HeatMapProducer(
- options.chromeos_root,
- options.perf_data,
- hugepage_range,
- options.binary,
- options.title,
- )
-
- heatmap_producer.Run(options.top_n)
-
-
-if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))