Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Unified Diff: tools/telemetry/telemetry/timeline/memory_dump_event.py

Issue 1553183002: [telemetry] Add support for composable process dumps in memory-infra (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: adding test Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/timeline/memory_dump_event.py
diff --git a/tools/telemetry/telemetry/timeline/memory_dump_event.py b/tools/telemetry/telemetry/timeline/memory_dump_event.py
index fff2a677588e98427422ed09fdb16514454a119a..cf69156efeea701fec83e4836a219fcc80ccbca3 100644
--- a/tools/telemetry/telemetry/timeline/memory_dump_event.py
+++ b/tools/telemetry/telemetry/timeline/memory_dump_event.py
@@ -146,25 +146,73 @@ class ProcessMemoryDumpEvent(timeline_event.TimelineEvent):
has_mmaps: True if the memory dump has mmaps information. If False then
GetMemoryUsage will report all zeros.
"""
- def __init__(self, process, event):
- assert event['ph'] == 'v' and process.pid == event['pid']
-
- super(ProcessMemoryDumpEvent, self).__init__(
- 'memory', 'memory_dump', event['ts'] / 1000.0, 0.0)
+ def __init__(self, process, event_id, thread_start):
+ super(ProcessMemoryDumpEvent, self).__init__('memory', 'memory_dump',
+ thread_start / 1000.0, 0.0)
self.process = process
- self.dump_id = event['id']
+ self.dump_id = event_id
+ self.has_mmaps = False
+ self._allocators = None
+ self._buckets = None
+ self._raw_allocator_dumps = {}
+ self._raw_vm_regions = []
+
+ @property
+ def process_name(self):
+ return self.process.name
+
+ def _AddRegion(self, vm_region):
+ path = ''
+ category = ROOT_CATEGORY
+ while category:
+ path = posixpath.join(path, category.name)
+ self.GetMemoryBucket(path).AddRegion(vm_region['bs'])
+ mapped_file = vm_region['mf']
+ category = category.GetMatchingChild(mapped_file)
+
+ def __repr__(self):
+ values = ['pid=%d' % self.process.pid]
+ for key, value in sorted(self.GetMemoryUsage().iteritems()):
+ values.append('%s=%d' % (key, value))
+ values = ', '.join(values)
+ return '%s[%s]' % (type(self).__name__, values)
petrcermak 2016/01/07 18:59:28 idea: There's no reason to put the square brackets
ssid 2016/01/07 20:46:09 discussed offline.
+
+ def AddRawEvent(self, event):
+ """Add the raw event without processing.
petrcermak 2016/01/07 18:59:28 supernit: s/the/a/
+
+ Add the allocator dumps and vm regions from the timeline event without
+ processing."""
petrcermak 2016/01/07 18:59:28 The three quotes should be on a separate line.
+ assert event['ph'] == 'v' and self.process.pid == event['pid']
try:
- allocators_dict = event['args']['dumps']['allocators']
+ self._raw_allocator_dumps.update(event['args']['dumps']['allocators'])
+ except KeyError:
+ pass # It's ok if any of those keys are not present.
+ try:
+ vm_regions = event['args']['dumps']['process_mmaps']['vm_regions']
+ assert not self.has_mmaps
+ assert not self._raw_vm_regions
+ self._raw_vm_regions += vm_regions
+ self.has_mmaps = True
except KeyError:
- allocators_dict = {}
+ pass # It's ok if any of those keys are not present.
+
+ def ProcessAllocatorDumps(self):
+ """Process the raw memory dump data into structured stats.
+
+ Parse and aggregate the allocator dumps values and the vm regions so that
+ it is easy to retrieve and add memory usage values to telemetry results.
+ This method needs to be called before making calls to GetMemory* functions
petrcermak 2016/01/07 18:59:28 nit: s/functions/methods/
+ of this class.
+ """
self._allocators = {}
parent_path = ''
parent_has_size = False
- for allocator_name, size_values in sorted(allocators_dict.iteritems()):
- if ((allocator_name.startswith(parent_path) and parent_has_size)
- or allocator_name.startswith('global/')):
+ for allocator_name, size_values in sorted(
+ self._raw_allocator_dumps.iteritems()):
+ if ((allocator_name.startswith(parent_path) and parent_has_size) or
+ allocator_name.startswith('global/')):
continue
parent_path = allocator_name + '/'
parent_has_size = 'size' in size_values['attrs']
@@ -173,8 +221,8 @@ class ProcessMemoryDumpEvent(timeline_event.TimelineEvent):
# For 'gpu/android_memtrack/*' we want to keep track of individual
# components. E.g. 'gpu/android_memtrack/gl' will be stored as
# 'android_memtrack_gl' in the allocators dict.
- if (len(name_parts) == 3 and allocator_name == 'gpu'
- and name_parts[1] == 'android_memtrack'):
+ if (len(name_parts) == 3 and allocator_name == 'gpu' and
+ name_parts[1] == 'android_memtrack'):
allocator_name = '_'.join(name_parts[1:3])
allocator = self._allocators.setdefault(allocator_name, {})
for size_key, size_value in size_values['attrs'].iteritems():
@@ -185,36 +233,13 @@ class ProcessMemoryDumpEvent(timeline_event.TimelineEvent):
try:
self._allocators['malloc']['size'] -= self._allocators['tracing']['size']
except KeyError:
- pass # it's ok if any of those keys are not present
+ pass # It's ok if any of those keys are not present.
+ self._raw_allocator_dumps = None
self._buckets = {}
- try:
- vm_regions = event['args']['dumps']['process_mmaps']['vm_regions']
- except KeyError:
- vm_regions = []
- self.has_mmaps = bool(vm_regions)
- for vm_region in vm_regions:
+ for vm_region in self._raw_vm_regions:
self._AddRegion(vm_region)
-
- @property
- def process_name(self):
- return self.process.name
-
- def _AddRegion(self, vm_region):
- path = ''
- category = ROOT_CATEGORY
- while category:
- path = posixpath.join(path, category.name)
- self.GetMemoryBucket(path).AddRegion(vm_region['bs'])
- mapped_file = vm_region['mf']
- category = category.GetMatchingChild(mapped_file)
-
- def __repr__(self):
- values = ['pid=%d' % self.process.pid]
- for key, value in sorted(self.GetMemoryUsage().iteritems()):
- values.append('%s=%d' % (key, value))
- values = ', '.join(values)
- return '%s[%s]' % (type(self).__name__, values)
+ self._raw_vm_regions = None
def GetMemoryBucket(self, path):
"""Return the MemoryBucket associated with a category path.
@@ -259,8 +284,10 @@ class ProcessMemoryDumpEvent(timeline_event.TimelineEvent):
if 'memtrack_pss' in values:
usage[name] = values['memtrack_pss']
if self.has_mmaps:
- usage.update((key, self.GetMemoryValue(*value))
- for key, value in MMAPS_METRICS.iteritems())
+ for key, value in MMAPS_METRICS.iteritems():
+ result = self.GetMemoryValue(*value)
+ if result:
+ usage[key] = result
return usage

Powered by Google App Engine
This is Rietveld 408576698