| Index: tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py
|
| diff --git a/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e392cb0b060bfd06a9b039ab4b8be0c517770a4c
|
| --- /dev/null
|
| +++ b/tools/telemetry/telemetry/core/platform/profiler/tcmalloc_heap_profiler.py
|
| @@ -0,0 +1,117 @@
|
| +# Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +import logging
|
| +import os
|
| +import sys
|
| +
|
| +from telemetry.core.platform import profiler
|
| +
|
| +# Enviroment variables to (android properties, default value) mapping.
|
| +_ENV_VARIABLES = {
|
| + 'HEAP_PROFILE_TIME_INTERVAL': ('heapprof.time_interval', 20),
|
| + 'HEAP_PROFILE_MMAP': ('heapprof.mmap', 1),
|
| + 'DEEP_HEAP_PROFILE': ('heapprof.deep_heap_profile', 1),
|
| +}
|
| +
|
| +
|
| +class _TCMallocHeapProfilerAndroid(object):
|
| + """An internal class to set android properties and fetch dumps from device."""
|
| +
|
| + _DEFAULT_DEVICE_DIR = '/data/local/tmp/heap'
|
| +
|
| + def __init__(self, browser_backend, output_path):
|
| + self._browser_backend = browser_backend
|
| + self._output_path = output_path
|
| +
|
| + _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof',
|
| + os.path.join(self._DEFAULT_DEVICE_DIR, 'dmprof'))
|
| +
|
| + self._SetDeviceProperties(_ENV_VARIABLES)
|
| +
|
| + def _SetDeviceProperties(self, properties):
|
| + device_configured = False
|
| + for values in properties.itervalues():
|
| + device_property = self._browser_backend.adb.RunShellCommand(
|
| + 'getprop ' + values[0])
|
| + if (not device_property or len(device_property) != 1 or
|
| + not device_property[0].strip()):
|
| + print 'Setting device property ', values[0], values[1]
|
| + self._browser_backend.adb.RunShellCommand(
|
| + 'setprop ' + values[0] + ' ' + str(values[1]))
|
| + device_configured = True
|
| + if not self._browser_backend.adb.Adb().FileExistsOnDevice(
|
| + self._DEFAULT_DEVICE_DIR):
|
| + self._browser_backend.adb.RunShellCommand(
|
| + 'mkdir -p ' + self._DEFAULT_DEVICE_DIR)
|
| + self._browser_backend.adb.RunShellCommand(
|
| + 'chmod 777 ' + self._DEFAULT_DEVICE_DIR)
|
| + device_configured = True
|
| + if device_configured:
|
| + raise Exception('Device required special config, run again.')
|
| +
|
| + def CollectProfile(self):
|
| + self._browser_backend.adb.Adb().Adb().Pull(
|
| + self._DEFAULT_DEVICE_DIR, self._output_path)
|
| + self._browser_backend.adb.RunShellCommand(
|
| + 'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'))
|
| + if os.path.exists(self._output_path):
|
| + logging.info('TCMalloc dumps pulled to %s', self._output_path)
|
| + with file(os.path.join(self._output_path,
|
| + 'browser.pid'), 'w') as pid_file:
|
| + pid_file.write(str(self._browser_backend.pid).rjust(5, '0'))
|
| +
|
| +
|
| +class _TCMallocHeapProfilerLinux(object):
|
| + """An internal class to set environment variables and fetch dumps."""
|
| +
|
| + _DEFAULT_DIR = '/tmp/tcmalloc/'
|
| +
|
| + def __init__(self, browser_backend):
|
| + self._browser_backend = browser_backend
|
| + _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof', self._DEFAULT_DIR + 'dmprof')
|
| + self._CheckEnvironmentVariables(_ENV_VARIABLES)
|
| +
|
| + def _CheckEnvironmentVariables(self, env_vars):
|
| + msg = ''
|
| + for key, values in env_vars.iteritems():
|
| + if key not in os.environ:
|
| + msg += '%s=%s ' % (key, str(values[1]))
|
| + if msg:
|
| + raise Exception('Need enviroment variables, try again with:\n %s' % msg)
|
| + if not os.path.exists(os.environ['HEAPPROFILE']):
|
| + os.makedirs(os.environ['HEAPPROFILE'])
|
| + assert os.path.isdir(os.environ['HEAPPROFILE']), 'HEAPPROFILE is not a dir'
|
| +
|
| + def CollectProfile(self):
|
| + with file(os.path.join(os.path.dirname(os.environ['HEAPPROFILE']),
|
| + 'browser.pid'), 'w') as pid_file:
|
| + pid_file.write(str(self._browser_backend.pid))
|
| + print 'TCMalloc dumps available ', os.environ['HEAPPROFILE']
|
| +
|
| +
|
| +class TCMallocHeapProfiler(profiler.Profiler):
|
| + """A Factory to instantiate the platform-specific profiler."""
|
| + def __init__(self, browser_backend, platform_backend, output_path):
|
| + super(TCMallocHeapProfiler, self).__init__(
|
| + browser_backend, platform_backend, output_path)
|
| + if self._browser_backend.options.browser_type.startswith('android'):
|
| + self._platform_profiler = _TCMallocHeapProfilerAndroid(
|
| + browser_backend, output_path)
|
| + else:
|
| + self._platform_profiler = _TCMallocHeapProfilerLinux(browser_backend)
|
| +
|
| + @classmethod
|
| + def name(cls):
|
| + return 'tcmalloc-heap'
|
| +
|
| + @classmethod
|
| + def is_supported(cls, options):
|
| + if (not sys.platform.startswith('linux') or
|
| + options.browser_type.startswith('cros')):
|
| + return False
|
| + return True
|
| +
|
| + def CollectProfile(self):
|
| + self._platform_profiler.CollectProfile()
|
|
|