Lines Matching refs:self
34 def __init__(self, output_path): argument
35 self.fh = open(output_path, 'w')
36 self.tag_stack = []
38 def close(self): argument
39 self.fh.close()
41 def open_tag(self, tag, **attrs): argument
45 self.fh.write('<%s%s>' % (tag, attr_str))
46 self.tag_stack.append(tag)
47 return self
49 def close_tag(self, tag=None): argument
51 assert tag == self.tag_stack[-1]
52 self.fh.write('</%s>\n' % self.tag_stack.pop())
54 def add(self, text): argument
55 self.fh.write(text)
56 return self
58 def add_file(self, file_path): argument
61 self.add(f.read())
62 return self
69 def __init__(self, name): argument
70 self.name = name
71 self.processes = {} # map from pid to ProcessScope
72 self.sample_count = 0
73 self.event_count = 0
75 def get_process(self, pid): argument
76 process = self.processes.get(pid)
78 process = self.processes[pid] = ProcessScope(pid)
81 def get_sample_info(self, gen_addr_hit_map): argument
83 result['eventName'] = self.name
84 result['eventCount'] = self.event_count
85 processes = sorted(self.processes.values(), key=lambda a: a.event_count, reverse=True)
91 def threads(self): argument
92 for process in self.processes.values():
97 def libraries(self): argument
98 for process in self.processes.values():
106 def __init__(self, pid): argument
107 self.pid = pid
108 self.name = ''
109 self.event_count = 0
110 self.threads = {} # map from tid to ThreadScope
112 def get_thread(self, tid, thread_name): argument
113 thread = self.threads.get(tid)
115 thread = self.threads[tid] = ThreadScope(tid)
117 if self.pid == tid:
118 self.name = thread_name
121 def get_sample_info(self, gen_addr_hit_map): argument
123 result['pid'] = self.pid
124 result['eventCount'] = self.event_count
125 threads = sorted(self.threads.values(), key=lambda a: a.event_count, reverse=True)
130 def merge_by_thread_name(self, process): argument
131 self.event_count += process.event_count
132 thread_list = list(self.threads.values()) + list(process.threads.values())
140 self.threads = {}
142 self.threads[thread.tid] = thread
147 def __init__(self, tid): argument
148 self.tid = tid
149 self.name = ''
150 self.event_count = 0
151 self.sample_count = 0
152 self.libs = {} # map from lib_id to LibScope
153 self.call_graph = CallNode(-1)
154 self.reverse_call_graph = CallNode(-1)
156 def add_callstack(self, event_count, callstack, build_addr_hit_map): argument
166 lib = self.libs.get(lib_id)
168 lib = self.libs[lib_id] = LibScope(lib_id)
179 node = self.call_graph
183 node = self.reverse_call_graph
188 def update_subtree_event_count(self): argument
189 self.call_graph.update_subtree_event_count()
190 self.reverse_call_graph.update_subtree_event_count()
192 def limit_percents(self, min_func_limit, min_callchain_percent, hit_func_ids): argument
193 for lib in self.libs.values():
202 min_limit = min_callchain_percent * 0.01 * self.call_graph.subtree_event_count
203 self.call_graph.cut_edge(min_limit, hit_func_ids)
204 self.reverse_call_graph.cut_edge(min_limit, hit_func_ids)
206 def get_sample_info(self, gen_addr_hit_map): argument
208 result['tid'] = self.tid
209 result['eventCount'] = self.event_count
210 result['sampleCount'] = self.sample_count
212 for lib in self.libs.values()]
213 result['g'] = self.call_graph.gen_sample_info()
214 result['rg'] = self.reverse_call_graph.gen_sample_info()
217 def merge(self, thread): argument
218 self.event_count += thread.event_count
219 self.sample_count += thread.sample_count
221 cur_lib = self.libs.get(lib_id)
223 self.libs[lib_id] = lib
226 self.call_graph.merge(thread.call_graph)
227 self.reverse_call_graph.merge(thread.reverse_call_graph)
232 def __init__(self, lib_id): argument
233 self.lib_id = lib_id
234 self.event_count = 0
235 self.functions = {} # map from func_id to FunctionScope.
237 def get_function(self, func_id): argument
238 function = self.functions.get(func_id)
240 function = self.functions[func_id] = FunctionScope(func_id)
243 def gen_sample_info(self, gen_addr_hit_map): argument
245 result['libId'] = self.lib_id
246 result['eventCount'] = self.event_count
248 for func in self.functions.values()]
251 def merge(self, lib): argument
252 self.event_count += lib.event_count
254 cur_function = self.functions.get(func_id)
256 self.functions[func_id] = function
263 def __init__(self, func_id): argument
264 self.func_id = func_id
265 self.sample_count = 0
266 self.event_count = 0
267 self.subtree_event_count = 0
268 self.addr_hit_map = None # map from addr to [event_count, subtree_event_count].
270 self.line_hit_map = None
272 def build_addr_hit_map(self, addr, event_count, subtree_event_count): argument
273 if self.addr_hit_map is None:
274 self.addr_hit_map = {}
275 count_info = self.addr_hit_map.get(addr)
277 self.addr_hit_map[addr] = [event_count, subtree_event_count]
282 def build_line_hit_map(self, source_file_id, line, event_count, subtree_event_count): argument
283 if self.line_hit_map is None:
284 self.line_hit_map = {}
286 count_info = self.line_hit_map.get(key)
288 self.line_hit_map[key] = [event_count, subtree_event_count]
293 def gen_sample_info(self, gen_addr_hit_map): argument
295 result['f'] = self.func_id
296 result['c'] = [self.sample_count, self.event_count, self.subtree_event_count]
297 if self.line_hit_map:
299 for key in self.line_hit_map:
300 count_info = self.line_hit_map[key]
304 if gen_addr_hit_map and self.addr_hit_map:
306 for addr in sorted(self.addr_hit_map):
307 count_info = self.addr_hit_map[addr]
312 def merge(self, function): argument
313 self.sample_count += function.sample_count
314 self.event_count += function.event_count
315 self.subtree_event_count += function.subtree_event_count
316 self.addr_hit_map = self.__merge_hit_map(self.addr_hit_map, function.addr_hit_map)
317 self.line_hit_map = self.__merge_hit_map(self.line_hit_map, function.line_hit_map)
337 def __init__(self, func_id): argument
338 self.event_count = 0
339 self.subtree_event_count = 0
340 self.func_id = func_id
341 self.children = collections.OrderedDict() # map from func_id to CallNode
343 def get_child(self, func_id): argument
344 child = self.children.get(func_id)
346 child = self.children[func_id] = CallNode(func_id)
349 def update_subtree_event_count(self): argument
350 self.subtree_event_count = self.event_count
351 for child in self.children.values():
352 self.subtree_event_count += child.update_subtree_event_count()
353 return self.subtree_event_count
355 def cut_edge(self, min_limit, hit_func_ids): argument
356 hit_func_ids.add(self.func_id)
358 for key in self.children:
359 child = self.children[key]
365 del self.children[key]
367 def gen_sample_info(self): argument
369 result['e'] = self.event_count
370 result['s'] = self.subtree_event_count
371 result['f'] = self.func_id
372 result['c'] = [child.gen_sample_info() for child in self.children.values()]
375 def merge(self, node): argument
376 self.event_count += node.event_count
377 self.subtree_event_count += node.subtree_event_count
379 cur_child = self.children.get(key)
381 self.children[key] = child
388 def __init__(self): argument
389 self.lib_name_to_id = {}
390 self.lib_id_to_name = []
392 def get_lib_id(self, lib_name): argument
393 lib_id = self.lib_name_to_id.get(lib_name)
395 lib_id = len(self.lib_id_to_name)
396 self.lib_name_to_id[lib_name] = lib_id
397 self.lib_id_to_name.append(lib_name)
400 def get_lib_name(self, lib_id): argument
401 return self.lib_id_to_name[lib_id]
406 def __init__(self, lib_id, func_name, func_id, start_addr, addr_len): argument
407 self.lib_id = lib_id
408 self.func_name = func_name
409 self.func_id = func_id
410 self.start_addr = start_addr
411 self.addr_len = addr_len
412 self.source_info = None
413 self.disassembly = None
418 def __init__(self): argument
419 self.name_to_func = {}
420 self.id_to_func = {}
422 def get_func_id(self, lib_id, symbol): argument
424 function = self.name_to_func.get(key)
426 func_id = len(self.id_to_func)
429 self.name_to_func[key] = function
430 self.id_to_func[func_id] = function
433 def trim_functions(self, left_func_ids): argument
435 for function in self.name_to_func.values():
437 del self.id_to_func[function.func_id]
439 self.name_to_func = None
444 def __init__(self, file_id, abstract_path): argument
445 self.file_id = file_id
446 self.abstract_path = abstract_path # path reported by addr2line
447 self.real_path = None # file path in the file system
448 self.requested_lines = set()
449 self.line_to_code = {} # map from line to code in that line.
451 def request_lines(self, start_line, end_line): argument
452 self.requested_lines |= set(range(start_line, end_line + 1))
454 def add_source_code(self, real_path): argument
455 self.real_path = real_path
459 for line in self.requested_lines:
461 self.line_to_code[line] = source_code[line - 1]
463 self.requested_lines = None
468 def __init__(self): argument
469 self.path_to_source_files = {} # map from file path to SourceFile.
471 def get_source_file(self, file_path): argument
472 source_file = self.path_to_source_files.get(file_path)
474 source_file = SourceFile(len(self.path_to_source_files), file_path)
475 self.path_to_source_files[file_path] = source_file
478 def load_source_code(self, source_dirs): argument
480 for source_file in self.path_to_source_files.values():
567 def __init__(self, binary_cache_path, ndk_path, build_addr_hit_map): argument
568 self.binary_cache_path = binary_cache_path
569 self.ndk_path = ndk_path
570 self.build_addr_hit_map = build_addr_hit_map
571 self.meta_info = None
572 self.cmdline = None
573 self.arch = None
574 self.events = {}
575 self.libs = LibSet()
576 self.functions = FunctionSet()
577 self.total_samples = 0
578 self.source_files = SourceFileSet()
579 self.gen_addr_hit_map_in_record_info = False
581 def load_record_file(self, record_file, show_art_frames): argument
589 if self.binary_cache_path:
590 lib.SetSymfs(self.binary_cache_path)
591 self.meta_info = lib.MetaInfo()
592 self.cmdline = lib.GetRecordCmd()
593 self.arch = lib.GetArch()
602 event = self._get_event(raw_event.name)
603 self.total_samples += 1
612 lib_id = self.libs.get_lib_id(symbol.dso_name)
613 func_id = self.functions.get_func_id(lib_id, symbol)
617 lib_id = self.libs.get_lib_id(symbol.dso_name)
618 func_id = self.functions.get_func_id(lib_id, symbol)
622 thread.add_callstack(raw_sample.period, callstack, self.build_addr_hit_map)
624 for event in self.events.values():
628 def aggregate_by_thread_name(self): argument
629 for event in self.events.values():
641 def limit_percents(self, min_func_percent, min_callchain_percent): argument
643 for event in self.events.values():
659 self.functions.trim_functions(hit_func_ids)
661 def _get_event(self, event_name): argument
662 if event_name not in self.events:
663 self.events[event_name] = EventScope(event_name)
664 return self.events[event_name]
666 def add_source_code(self, source_dirs, filter_lib): argument
672 addr2line = Addr2Nearestline(self.ndk_path, self.binary_cache_path, False)
674 for function in self.functions.id_to_func.values():
677 lib_name = self.libs.get_lib_name(function.lib_id)
683 for event in self.events.values():
685 lib_name = self.libs.get_lib_name(lib.lib_id)
688 func_addr = self.functions.id_to_func[function.func_id].start_addr
694 for function in self.functions.id_to_func.values():
697 dso = addr2line.get_dso(self.libs.get_lib_name(function.lib_id))
708 source_file = self.source_files.get_source_file(start_file_path)
713 for event in self.events.values():
715 dso = addr2line.get_dso(self.libs.get_lib_name(lib.lib_id))
724 source_file = self.source_files.get_source_file(file_path)
732 self.source_files.load_source_code(source_dirs)
734 def add_disassembly(self, filter_lib): argument
739 objdump = Objdump(self.ndk_path, self.binary_cache_path)
742 for function in sorted(self.functions.id_to_func.values(), key=lambda a: a.lib_id):
745 lib_name = self.libs.get_lib_name(function.lib_id)
758 self.gen_addr_hit_map_in_record_info = True
760 def gen_record_info(self): argument
762 timestamp = self.meta_info.get('timestamp')
769 product_props = self.meta_info.get('product_props')
770 machine_type = self.arch
773 machine_type = '%s (%s) by %s, arch %s' % (model, name, manufacturer, self.arch)
775 record_info['androidVersion'] = self.meta_info.get('android_version', '')
776 record_info['recordCmdline'] = self.cmdline
777 record_info['totalSamples'] = self.total_samples
778 record_info['processNames'] = self._gen_process_names()
779 record_info['threadNames'] = self._gen_thread_names()
780 record_info['libList'] = self._gen_lib_list()
781 record_info['functionMap'] = self._gen_function_map()
782 record_info['sampleInfo'] = self._gen_sample_info()
783 record_info['sourceFiles'] = self._gen_source_files()
786 def _gen_process_names(self): argument
788 for event in self.events.values():
793 def _gen_thread_names(self): argument
795 for event in self.events.values():
801 def _gen_lib_list(self): argument
802 return [modify_text_for_html(x) for x in self.libs.lib_id_to_name]
804 def _gen_function_map(self): argument
806 for func_id in sorted(self.functions.id_to_func):
807 function = self.functions.id_to_func[func_id]
821 def _gen_sample_info(self): argument
822 return [event.get_sample_info(self.gen_addr_hit_map_in_record_info)
823 for event in self.events.values()]
825 def _gen_source_files(self): argument
826 source_files = sorted(self.source_files.path_to_source_files.values(),
857 def __init__(self, html_path): argument
858 self.hw = HtmlWriter(html_path)
859 self.hw.open_tag('html')
860 self.hw.open_tag('head')
862 self.hw.open_tag('link', rel='stylesheet', type='text/css', href=URLS[css]).close_tag()
865 self.hw.open_tag('script', src=URLS[js]).close_tag()
867 self.hw.open_tag('script').add(
869 self.hw.open_tag('style', type='text/css').add("""
875 self.hw.close_tag('head')
876 self.hw.open_tag('body')
877 self.record_info = {}
879 def write_content_div(self): argument
880 self.hw.open_tag('div', id='report_content').close_tag()
882 def write_record_data(self, record_data): argument
883 self.hw.open_tag('script', id='record_data', type='application/json')
884 self.hw.add(json.dumps(record_data))
885 self.hw.close_tag()
887 def write_script(self): argument
888 self.hw.open_tag('script').add_file('report_html.js').close_tag()
890 def finish(self): argument
891 self.hw.close_tag('body')
892 self.hw.close_tag('html')
893 self.hw.close()