17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# found in the LICENSE file. 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport logging 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport os 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochLOGGER = logging.getLogger('dmprof') 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass Dump(object): 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """Represents a heap profile dump.""" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def __init__(self): 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pass 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def path(self): 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def count(self): 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def time(self): 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def iter_map(self): 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def iter_stacktrace(self): 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def global_stat(self, name): 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def run_id(self): 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def pagesize(self): 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def pageframe_length(self): 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def pageframe_encoding(self): 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @property 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def has_pagecount(self): 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch raise NotImplementedError 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @staticmethod 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def load(path, log_header='Loading a heap profile dump: '): 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """Loads a heap profile dump. 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Args: 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch path: A file path string to load. 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch log_header: A preceding string for log messages. 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Returns: 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch A loaded Dump object. 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Raises: 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ParsingException for invalid heap profile dumps. 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch """ 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch from lib.deep_dump import DeepDump 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch dump = DeepDump(path, os.stat(path).st_mtime) 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch with open(path, 'r') as f: 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dump.load_file(f, log_header) 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return dump 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass DumpList(object): 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Represents a sequence of heap profile dumps. 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Individual dumps are loaded into memory lazily as the sequence is accessed, 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) either while being iterated through or randomly accessed. Loaded dumps are 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) not cached, meaning a newly loaded Dump object is returned every time an 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) element in the list is accessed. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, dump_path_list): 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._dump_path_list = dump_path_list 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch @staticmethod 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def load(path_list): 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return DumpList(path_list) 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __len__(self): 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return len(self._dump_path_list) 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __iter__(self): 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for dump in self._dump_path_list: 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) yield Dump.load(dump) 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch def __getitem__(self, index): 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Dump.load(self._dump_path_list[index]) 106