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

Side by Side Diff: tools/deep_memory_profiler/dmprof

Issue 10824104: Use json to describe dmprof policies. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use 'stacktrace' instead of 'pattern' Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tools/deep_memory_profiler/policies.json » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """The deep heap profiler script for Chrome.""" 6 """The deep heap profiler script for Chrome."""
7 7
8 from datetime import datetime 8 from datetime import datetime
9 import json 9 import json
10 import optparse 10 import optparse
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 # Heap Profile Policy versions 71 # Heap Profile Policy versions
72 72
73 # POLICY_DEEP_1 DOES NOT include allocation_type columns. 73 # POLICY_DEEP_1 DOES NOT include allocation_type columns.
74 # mmap regions are distincted w/ mmap frames in the pattern column. 74 # mmap regions are distincted w/ mmap frames in the pattern column.
75 POLICY_DEEP_1 = 'POLICY_DEEP_1' 75 POLICY_DEEP_1 = 'POLICY_DEEP_1'
76 76
77 # POLICY_DEEP_2 DOES include allocation_type columns. 77 # POLICY_DEEP_2 DOES include allocation_type columns.
78 # mmap regions are distincted w/ the allocation_type column. 78 # mmap regions are distincted w/ the allocation_type column.
79 POLICY_DEEP_2 = 'POLICY_DEEP_2' 79 POLICY_DEEP_2 = 'POLICY_DEEP_2'
80 80
81 # POLICY_DEEP_3 is in JSON format.
82 POLICY_DEEP_3 = 'POLICY_DEEP_3'
83
81 84
82 class EmptyDumpException(Exception): 85 class EmptyDumpException(Exception):
83 def __init__(self, value): 86 def __init__(self, value):
84 self.value = value 87 self.value = value
85 def __str__(self): 88 def __str__(self):
86 return repr(self.value) 89 return repr(self.value)
87 90
88 91
89 class ParsingException(Exception): 92 class ParsingException(Exception):
90 def __init__(self, value): 93 def __init__(self, value):
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 self.loaded_static_symbols = StaticSymbols.load(self.prepared_data_dir) 129 self.loaded_static_symbols = StaticSymbols.load(self.prepared_data_dir)
127 finally: 130 finally:
128 if not self.keep: 131 if not self.keep:
129 shutil.rmtree(self.prepared_data_dir) 132 shutil.rmtree(self.prepared_data_dir)
130 return self.loaded_static_symbols 133 return self.loaded_static_symbols
131 134
132 135
133 class Rule(object): 136 class Rule(object):
134 """Represents one matching rule in a policy file.""" 137 """Represents one matching rule in a policy file."""
135 138
136 def __init__(self, name, mmap, pattern): 139 def __init__(self, name, mmap, stacktrace_pattern):
137 self.name = name 140 self.name = name
138 self.mmap = mmap 141 self.mmap = mmap
139 self.condition = re.compile(pattern + r'\Z') 142 self.stacktrace_pattern = re.compile(stacktrace_pattern + r'\Z')
140 143
141 144
142 class Policy(object): 145 class Policy(object):
143 """Represents a policy, a content of a policy file.""" 146 """Represents a policy, a content of a policy file."""
144 147
145 def __init__(self, rules, version, components): 148 def __init__(self, rules, version, components):
146 self.rules = rules 149 self.rules = rules
147 self.version = version 150 self.version = version
148 self.components = components 151 self.components = components
149 152
(...skipping 13 matching lines...) Expand all
163 A string representing a component name. 166 A string representing a component name.
164 """ 167 """
165 if not bucket: 168 if not bucket:
166 return 'no-bucket' 169 return 'no-bucket'
167 if bucket.component_cache: 170 if bucket.component_cache:
168 return bucket.component_cache 171 return bucket.component_cache
169 172
170 stacktrace = ''.join(symbols[a] + ' ' for a in bucket.stacktrace).strip() 173 stacktrace = ''.join(symbols[a] + ' ' for a in bucket.stacktrace).strip()
171 174
172 for rule in rule_list: 175 for rule in rule_list:
173 if bucket.mmap == rule.mmap and rule.condition.match(stacktrace): 176 if bucket.mmap == rule.mmap and rule.stacktrace_pattern.match(stacktrace):
174 bucket.component_cache = rule.name 177 bucket.component_cache = rule.name
175 return rule.name 178 return rule.name
176 179
177 assert False 180 assert False
178 181
179 182
180 class Bucket(object): 183 class Bucket(object):
181 """Represents a bucket, which is a unit of memory classification.""" 184 """Represents a bucket, which is a unit of memory classification."""
182 185
183 def __init__(self, stacktrace, mmap): 186 def __init__(self, stacktrace, mmap):
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 for address, symbol in zip(unresolved_addresses, symbol_list): 649 for address, symbol in zip(unresolved_addresses, symbol_list):
647 if not symbol: 650 if not symbol:
648 symbol = '??' 651 symbol = '??'
649 stripped_symbol = symbol.strip() 652 stripped_symbol = symbol.strip()
650 symbols[address] = stripped_symbol 653 symbols[address] = stripped_symbol
651 symbol_f.write('%x %s\n' % (address, stripped_symbol)) 654 symbol_f.write('%x %s\n' % (address, stripped_symbol))
652 655
653 sys.stderr.write(' All symbols resolved.\n') 656 sys.stderr.write(' All symbols resolved.\n')
654 657
655 658
656 def parse_policy(policy_path): 659 def parse_policy_text(policy_path):
657 """Parses policy file. 660 """Parses policy file in text format.
658 661
659 A policy file contains component's names and their 662 A policy file contains component's names and their
660 stacktrace pattern written in regular expression. 663 stacktrace pattern written in regular expression.
661 Those patterns are matched against each symbols of 664 Those patterns are matched against each symbols of
662 each stacktraces in the order written in the policy file 665 each stacktraces in the order written in the policy file
663 666
667 TODO(dmikurube): Deprecate this function after a while.
668
664 Args: 669 Args:
665 policy_path: A path for a policy file. 670 policy_path: A path for a policy file.
666 Returns: 671 Returns:
667 A list containing component's name and its regex object 672 A loaded policy object.
668 """ 673 """
669 with open(policy_path, mode='r') as policy_f: 674 with open(policy_path, mode='r') as policy_f:
670 policy_lines = policy_f.readlines() 675 policy_lines = policy_f.readlines()
671 676
672 policy_version = POLICY_DEEP_1 677 policy_version = POLICY_DEEP_1
673 if policy_lines[0].startswith('heap profile policy: '): 678 if policy_lines[0].startswith('heap profile policy: '):
674 policy_version = policy_lines[0][21:].strip() 679 policy_version = policy_lines[0][21:].strip()
675 policy_lines.pop(0) 680 policy_lines.pop(0)
676 rule_list = [] 681 rule_list = []
677 components = [] 682 components = []
(...skipping 15 matching lines...) Expand all
693 698
694 if pattern != 'default': 699 if pattern != 'default':
695 rule_list.append(Rule(name, mmap, pattern)) 700 rule_list.append(Rule(name, mmap, pattern))
696 if components.count(name) == 0: 701 if components.count(name) == 0:
697 components.append(name) 702 components.append(name)
698 703
699 else: 704 else:
700 sys.stderr.write(' invalid heap profile policy version: %s\n' % ( 705 sys.stderr.write(' invalid heap profile policy version: %s\n' % (
701 policy_version)) 706 policy_version))
702 707
703 return rule_list, policy_version, components 708 return Policy(rule_list, policy_version, components)
709
710
711 def parse_policy_json(policy_path):
712 """Parses policy file in json format.
713
714 A policy file contains component's names and their
715 stacktrace pattern written in regular expression.
716 Those patterns are matched against each symbols of
717 each stacktraces in the order written in the policy file
718
719 Args:
720 policy_path: A path for a policy file.
721 Returns:
722 A loaded policy object.
723 """
724 with open(policy_path, mode='r') as f:
725 policy = json.load(f)
726
727 rules = []
728 for rule in policy['rules']:
729 rules.append(Rule(
730 rule['name'], rule['allocator'] == 'mmap', rule['stacktrace']))
731 return Policy(rules, policy['version'], policy['components'])
704 732
705 733
706 def find_prefix(path): 734 def find_prefix(path):
707 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path) 735 return re.sub('\.[0-9][0-9][0-9][0-9]\.heap', '', path)
708 736
709 737
710 def load_buckets(prefix): 738 def load_buckets(prefix):
711 # Reading buckets 739 # Reading buckets
712 sys.stderr.write('Loading bucket files.\n') 740 sys.stderr.write('Loading bucket files.\n')
713 buckets = {} 741 buckets = {}
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 821
794 822
795 def load_default_policies(): 823 def load_default_policies():
796 with open(POLICIES_JSON_PATH, mode='r') as policies_f: 824 with open(POLICIES_JSON_PATH, mode='r') as policies_f:
797 default_policies = json.load(policies_f) 825 default_policies = json.load(policies_f)
798 return default_policies 826 return default_policies
799 827
800 828
801 def load_policy(policies_dict, policy_label): 829 def load_policy(policies_dict, policy_label):
802 policy_file = policies_dict[policy_label]['file'] 830 policy_file = policies_dict[policy_label]['file']
831 policy_format = policies_dict[policy_label]['format']
803 policy_path = os.path.join(os.path.dirname(__file__), policy_file) 832 policy_path = os.path.join(os.path.dirname(__file__), policy_file)
804 rule_list, policy_version, components = parse_policy(policy_path) 833 policy = None
834 if policy_format == 'json':
835 policy = parse_policy_json(policy_path)
836 elif policy_format == 'text':
837 policy = parse_policy_text(policy_path)
805 sys.stderr.write(' %s: %s (version: %s)\n' % 838 sys.stderr.write(' %s: %s (version: %s)\n' %
806 (policy_label, policy_path, policy_version)) 839 (policy_label, policy_path, policy.version))
jochen (gone - plz use gerrit) 2012/08/08 07:36:53 this might end up accessing .version of None. What
Dai Mikurube (NOT FULLTIME) 2012/08/08 07:53:53 Done. Thanks for your good catch.
807 return Policy(rule_list, policy_version, components) 840 return policy
808 841
809 842
810 def load_policies_dict(policies_dict): 843 def load_policies_dict(policies_dict):
811 sys.stderr.write('Loading policy files.\n') 844 sys.stderr.write('Loading policy files.\n')
812 policies = {} 845 policies = {}
813 for policy_label in policies_dict: 846 for policy_label in policies_dict:
814 policies[policy_label] = load_policy(policies_dict, policy_label) 847 loaded_policy = load_policy(policies_dict, policy_label)
848 if loaded_policy:
849 policies[policy_label] = loaded_policy
815 return policies 850 return policies
816 851
817 852
818 def load_policies(options_policy): 853 def load_policies(options_policy):
819 default_policies = load_default_policies() 854 default_policies = load_default_policies()
820 if options_policy: 855 if options_policy:
821 policy_labels = options_policy.split(',') 856 policy_labels = options_policy.split(',')
822 specified_policies = {} 857 specified_policies = {}
823 for specified_policy in policy_labels: 858 for specified_policy in policy_labels:
824 if specified_policy in default_policies: 859 if specified_policy in default_policies:
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 dmprof stacktrace [--keep] <dump> 1136 dmprof stacktrace [--keep] <dump>
1102 """ % (sys.argv[0])) 1137 """ % (sys.argv[0]))
1103 sys.exit(1) 1138 sys.exit(1)
1104 action = sys.argv.pop(1) 1139 action = sys.argv.pop(1)
1105 1140
1106 return COMMANDS[action](sys.argv) 1141 return COMMANDS[action](sys.argv)
1107 1142
1108 1143
1109 if __name__ == '__main__': 1144 if __name__ == '__main__':
1110 sys.exit(main()) 1145 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | tools/deep_memory_profiler/policies.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698