aboutsummaryrefslogtreecommitdiff
path: root/heatmaps/heat_map.py
diff options
context:
space:
mode:
Diffstat (limited to 'heatmaps/heat_map.py')
-rwxr-xr-xheatmaps/heat_map.py185
1 files changed, 0 insertions, 185 deletions
diff --git a/heatmaps/heat_map.py b/heatmaps/heat_map.py
deleted file mode 100755
index 2fd742d2..00000000
--- a/heatmaps/heat_map.py
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# 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."""
-
-from __future__ import print_function
-
-import argparse
-import os
-import shutil
-import sys
-import tempfile
-
-from cros_utils import command_executer
-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:]))