OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 # TODO(bashi): DO-NOT-FOR-COMMIT. Just for local measurements. |
| 6 |
| 7 import collections |
| 8 import logging |
| 9 |
| 10 from telemetry.page import action_runner |
| 11 from telemetry.page import page_test |
| 12 from telemetry.timeline import tracing_category_filter |
| 13 from telemetry.timeline import tracing_options |
| 14 from telemetry.timeline.model import TimelineModel |
| 15 from telemetry.value import scalar |
| 16 |
| 17 |
| 18 class BlinkPartitionAlloc(page_test.PageTest): |
| 19 def __init__(self): |
| 20 super(BlinkPartitionAlloc, self).__init__() |
| 21 |
| 22 def WillNavigateToPage(self, page, tab): |
| 23 category_filter = tracing_category_filter.TracingCategoryFilter( |
| 24 'disabled-by-default-memory-infra') |
| 25 options = tracing_options.TracingOptions() |
| 26 options.enable_chrome_trace = True |
| 27 tab.browser.platform.tracing_controller.Start(options, category_filter, |
| 28 10) |
| 29 def CustomizeBrowserOptions(self, options): |
| 30 options.AppendExtraBrowserArgs(['--no-sandbox']) |
| 31 |
| 32 def DidNavigateToPage(self, page, tab): |
| 33 runner = action_runner.ActionRunner(tab) |
| 34 runner.Wait(10) |
| 35 |
| 36 def ValidateAndMeasurePage(self, page, tab, results): |
| 37 timeline_data = tab.browser.platform.tracing_controller.Stop() |
| 38 timeline_model = TimelineModel(timeline_data) |
| 39 renderer_process = timeline_model.GetRendererProcessFromTabId(tab.id) |
| 40 stats = self._GetPerPartitionStats(timeline_model, renderer_process.pid) |
| 41 self._AddResults(stats, results) |
| 42 |
| 43 def CleanUpAfterPage(self, page, tab): |
| 44 if tab.browser.platform.tracing_controller.is_tracing_running: |
| 45 tab.browser.platform.tracing_controller.Stop() |
| 46 |
| 47 def _FindLatestRendererDump(self, timeline_model, pid): |
| 48 """Returns the latest ProcessMemoryDumpEvent which is associated with |
| 49 the renderer process and its |has_mmaps| is true. |
| 50 """ |
| 51 latest = None |
| 52 for memory_event in timeline_model.IterGlobalMemoryDumps(): |
| 53 renderer_events = filter(lambda event: event.process.pid == pid, |
| 54 memory_event._process_dumps) |
| 55 if len(renderer_events) == 0: |
| 56 continue |
| 57 assert(len(renderer_events) == 1) |
| 58 current = renderer_events[0] |
| 59 if current.has_mmaps and (not latest or latest.start < current.start): |
| 60 latest = current |
| 61 assert(latest != None) |
| 62 return latest |
| 63 |
| 64 def _GetPerPartitionStats(self, timeline_model, pid): |
| 65 latest = self._FindLatestRendererDump(timeline_model, pid) |
| 66 stats = collections.defaultdict(int) |
| 67 allocators = latest._event['args']['dumps']['allocators'] |
| 68 for allocator_name, value in allocators.iteritems(): |
| 69 name_parts = allocator_name.split('/') |
| 70 if name_parts[0] == 'partition_alloc': |
| 71 if name_parts[-1] != 'allocated_objects': |
| 72 # We don't count 'allocated_objects' since the outer includes the |
| 73 # value. |
| 74 continue |
| 75 partition = name_parts[2] |
| 76 stats[partition] += int(value['attrs']['size']['value'], 16) |
| 77 return stats |
| 78 |
| 79 def _AddResults(self, stats, results): |
| 80 total = 0.0 |
| 81 for category, value in stats.iteritems(): |
| 82 total += value |
| 83 results.AddValue(scalar.ScalarValue( |
| 84 results.current_page, category, 'MiB', |
| 85 float(value) / 1024**2, |
| 86 description=category)) |
| 87 results.AddValue(scalar.ScalarValue( |
| 88 results.current_page, 'total', 'MiB', |
| 89 float(total) / 1024**2, |
| 90 description='total')) |
OLD | NEW |