Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / tools / deep_memory_profiler / subcommands / addr.py
blobee399e8b3ae2b2998d97067176c7788c4e626e34
1 # Copyright 2013 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.
5 import logging
6 import sys
7 import re
9 from lib.subcommand import SubCommand
12 LOGGER = logging.getLogger('dmprof')
15 class AddrCommand(SubCommand):
16 def __init__(self):
17 super(AddrCommand, self).__init__('Usage: %prog addr <dump-file>')
19 def do(self, sys_argv, out=sys.stdout):
20 _, args = self._parse_args(sys_argv, 1)
21 dump_path = args[1]
22 (bucket_set, dump) = SubCommand.load_basic_files(dump_path, False)
23 AddrCommand._output(dump, bucket_set, out)
24 return 0
26 @staticmethod
27 def _output(dump, bucket_set, out):
28 """Prints memory usage by function addresses with resolving symbols.
30 Args:
31 bucket_set: A BucketSet object.
32 out: An IO object to output.
33 """
34 sizes = {}
35 library = {}
37 _ADDR_PATTERN = re.compile(r'^0x[a-f0-9]+$', re.IGNORECASE)
38 _TCMALLOC_PATTERN = re.compile(r'.*(ProfilerMalloc|MemoryRegionMap::'
39 '|TypeProfilerMalloc|DoAllocWithArena|SbrkSysAllocator::Alloc'
40 '|MmapSysAllocator::Alloc|LowLevelAlloc::Alloc'
41 '|LowLevelAlloc::AllocWithArena).*', re.IGNORECASE)
43 for bucket_id, virtual, committed, _, _ in dump.iter_stacktrace:
44 bucket = bucket_set.get(bucket_id)
45 if not bucket:
46 AddrCommand._add_size(bucket_id, "bucket", virtual, committed, sizes)
47 continue
49 if _TCMALLOC_PATTERN.match(bucket.symbolized_joined_stackfunction):
50 AddrCommand._add_size("TCMALLOC", "TCMALLOC",
51 virtual, committed, sizes)
52 continue
54 for index, addr in enumerate(bucket.stacktrace):
55 if _ADDR_PATTERN.match(bucket.symbolized_stackfunction[index]):
56 AddrCommand._find_library(addr, dump, library)
57 AddrCommand._add_size(hex(addr), library[addr],
58 virtual, committed, sizes)
59 else:
60 AddrCommand._add_size(hex(addr),
61 bucket.symbolized_stackfunction[index]
62 + "@" + bucket.symbolized_stacksourcefile[index],
63 virtual, committed, sizes)
65 for key in sorted(sizes):
66 out.write('%s;%s;%s;%s\n' % (sizes[key]["vss"], sizes[key]["rss"],
67 key, sizes[key]["desc"]))
70 @staticmethod
71 def _add_size(key, desc, vss, rss, sizes):
72 if not key in sizes:
73 sizes[key] = {"desc":desc, "vss":0, "rss":0, "alloc":0, "free": 0}
74 if sizes[key]["desc"] == desc:
75 sizes[key]["vss"] += vss
76 sizes[key]["rss"] += rss
77 else:
78 sys.stderr.write('%s:(%s) or (%s)?\n' % (key, sizes[key]["desc"], desc))
79 sys.exit(1)
81 @staticmethod
82 def _find_library(func, dump, library):
83 if not func in library:
84 library[func] = "Unknown"
85 for addr, region in dump.iter_map:
86 if addr[0] >= func and func < addr[1]:
87 library[func] = region[1]['vma']['name']
88 break