win32kprof: Convert tabs to spaces.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Mon, 21 Jul 2008 04:02:07 +0000 (13:02 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Tue, 22 Jul 2008 00:45:33 +0000 (09:45 +0900)
bin/win32kprof.py

index 1876fbc0670c474a18b9804c559cbe061431dc3d..c1aabc48c912062555efc715d2d9a2cff2c91ea7 100755 (executable)
@@ -37,262 +37,262 @@ __version__ = '0.1'
 
 
 class ParseError(Exception):
-       pass
+    pass
 
 
 class MsvcDemangler:
-       # http://www.kegel.com/mangle.html
-
-       def __init__(self, symbol):
-               self._symbol = symbol
-               self._pos = 0
-
-       def lookahead(self):
-               return self._symbol[self._pos]
-
-       def consume(self):
-               ret = self.lookahead()
-               self._pos += 1
-               return ret
-       
-       def match(self, c):
-               if self.lookahead() != c:
-                       raise ParseError
-               self.consume()
-
-       def parse(self):
-               self.match('?')
-               name = self.parse_name()
-               qualifications = self.parse_qualifications()
-               return '::'.join(qualifications + [name])
-
-       def parse_name(self):
-               if self.lookahead() == '?':
-                       return self.consume() + self.consume()
-               else:
-                       name = self.parse_id()
-                       self.match('@')
-                       return name
-
-       def parse_qualifications(self):
-               qualifications = []
-               while self.lookahead() != '@':
-                       name = self.parse_id()
-                       qualifications.append(name)
-                       self.match('@')
-               return qualifications
-
-       def parse_id(self):
-               s = ''
-               while True:
-                       c = self.lookahead()
-                       if c.isalnum() or c in '_':
-                               s += c
-                               self.consume()
-                       else:
-                               break
-               return s
+    # http://www.kegel.com/mangle.html
+
+    def __init__(self, symbol):
+        self._symbol = symbol
+        self._pos = 0
+
+    def lookahead(self):
+        return self._symbol[self._pos]
+
+    def consume(self):
+        ret = self.lookahead()
+        self._pos += 1
+        return ret
+    
+    def match(self, c):
+        if self.lookahead() != c:
+            raise ParseError
+        self.consume()
+
+    def parse(self):
+        self.match('?')
+        name = self.parse_name()
+        qualifications = self.parse_qualifications()
+        return '::'.join(qualifications + [name])
+
+    def parse_name(self):
+        if self.lookahead() == '?':
+            return self.consume() + self.consume()
+        else:
+            name = self.parse_id()
+            self.match('@')
+            return name
+
+    def parse_qualifications(self):
+        qualifications = []
+        while self.lookahead() != '@':
+            name = self.parse_id()
+            qualifications.append(name)
+            self.match('@')
+        return qualifications
+
+    def parse_id(self):
+        s = ''
+        while True:
+            c = self.lookahead()
+            if c.isalnum() or c in '_':
+                s += c
+                self.consume()
+            else:
+                break
+        return s
 
 
 def demangle(name):
-       if name.startswith('_'):
-               name = name[1:]
-               idx = name.rfind('@')
-               if idx != -1 and name[idx+1:].isdigit():
-                       name = name[:idx]
-               return name
-       if name.startswith('?'):
-               demangler = MsvcDemangler(name)
-               return demangler.parse()
+    if name.startswith('_'):
+        name = name[1:]
+        idx = name.rfind('@')
+        if idx != -1 and name[idx+1:].isdigit():
+            name = name[:idx]
+        return name
+    if name.startswith('?'):
+        demangler = MsvcDemangler(name)
+        return demangler.parse()
 
-               return name
-       return name
+        return name
+    return name
 
 
 class Profile:
 
-       def __init__(self):
-               self.symbols = []
-               self.symbol_cache = {}
-               self.base_addr = None
-               self.functions = {}
-               self.last_stamp = 0
-               self.stamp_base = 0
-       
-       def unwrap_stamp(self, stamp):
-               if stamp < self.last_stamp:
-                       self.stamp_base += 1 << 32
-               self.last_stamp = stamp
-               return self.stamp_base + stamp
-
-       def read_map(self, mapfile):
-               # See http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx
-               last_addr = 0
-               last_name = 0
-               for line in file(mapfile, "rt"):
-                       fields = line.split()
-                       try:
-                               section_offset, name, addr, type, lib_object = fields
-                       except ValueError:
-                               continue
-                       if type != 'f':
-                               continue
-                       section, offset = section_offset.split(':')
-                       addr = int(offset, 16)
-                       name = demangle(name)
-                       if last_addr == addr:
-                               # TODO: handle collapsed functions
-                               #assert last_name == name
-                               continue
-                       self.symbols.append((addr, name))
-                       last_addr = addr
-                       last_name = name
-
-               # sort symbols
-               self.symbols.sort(key = lambda (addr, name): addr)
-
-       def lookup_addr(self, addr):
-               try:
-                       return self.symbol_cache[addr]
-               except KeyError:
-                       pass
-
-               tolerance = 4196
-               s, e = 0, len(self.symbols)
-               while s != e:
-                       i = (s + e)//2
-                       start_addr, name = self.symbols[i]
-                       try:
-                               end_addr, next_name = self.symbols[i + 1]
-                       except IndexError:
-                               end_addr = start_addr + tolerance
-                       if addr < start_addr:
-                               e = i
-                               continue
-                       if addr == end_addr:
-                               return next_name
-                       if addr > end_addr:
-                               s = i
-                               continue
-                       return name
-               return "0x%08x" % addr
-
-       def lookup_symbol(self, name):
-               for symbol_addr, symbol_name in self.symbols:
-                       if name == symbol_name:
-                               return symbol_addr
-               return 0
-
-       def read_data(self, data):
-               # TODO: compute these automatically
-               caller_overhead = 672 - 2*144 # __debug_profile_reference2 - 2*__debug_profile_reference1
-               callee_overhead = 144 # __debug_profile_reference1
-               callee_overhead -= 48 # tolerance
-               caller_overhead = callee_overhead
-
-               fp = file(data, "rb")
-               entry_format = "II"
-               entry_size = struct.calcsize(entry_format)
-               stack = []
-               last_stamp = 0
-               delta = 0
-               while True:
-                       entry = fp.read(entry_size)
-                       if len(entry) < entry_size:
-                               break
-                       addr_exit, stamp = struct.unpack(entry_format, entry)
-                       if addr_exit == 0 and stamp == 0:
-                               break
-                       addr = addr_exit & 0xfffffffe
-                       exit = addr_exit & 0x00000001
-
-                       if self.base_addr is None:
-                               ref_addr = self.lookup_symbol('__debug_profile_reference2')
-                               if ref_addr:
-                                       self.base_addr = (addr - ref_addr) & ~(options.align - 1)
-                               else:
-                                       self.base_addr = 0
-                               #print hex(self.base_addr)
-                       rel_addr = addr - self.base_addr
-                       #print hex(addr - self.base_addr)
-
-                       name = self.lookup_addr(rel_addr)
-                       stamp = self.unwrap_stamp(stamp)
-
-                       delta += stamp - last_stamp
-
-                       if not exit:
-                               if options.verbose >= 2:
-                                       print "%10u >> 0x%08x" % (stamp, addr)
-                               if options.verbose:
-                                       print "%10u >> %s" % (stamp, name)
-                               delta -= caller_overhead
-                               stack.append((name, stamp, delta))
-                               delta = 0
-                       else:
-                               if options.verbose >= 2:
-                                       print "%10u << 0x%08x" % (stamp, addr)
-                               if len(stack):
-                                       self_time = delta - callee_overhead
-                                       entry_name, entry_stamp, delta = stack.pop()
-                                       if entry_name != name:
-                                               if options.verbose:
-                                                       print "%10u << %s" % (stamp, name)
-                                               #assert entry_name == name
-                                               break
-                                       total_time = stamp - entry_stamp
-                                       self.functions[entry_name] = self.functions.get(entry_name, 0) + self_time
-                                       if options.verbose:
-                                               print "%10u << %s %+u" % (stamp, name, self_time)
-                               else:
-                                       delta = 0
-
-                       last_stamp = stamp
-
-       def write_report(self):
-               total = sum(self.functions.values())
-               results = self.functions.items()
-               results.sort(key = lambda (name, time): -time)
-               for name, time in results:
-                       perc = float(time)/float(total)*100.0
-                       print "%6.03f %s" % (perc, name)
+    def __init__(self):
+        self.symbols = []
+        self.symbol_cache = {}
+        self.base_addr = None
+        self.functions = {}
+        self.last_stamp = 0
+        self.stamp_base = 0
+    
+    def unwrap_stamp(self, stamp):
+        if stamp < self.last_stamp:
+            self.stamp_base += 1 << 32
+        self.last_stamp = stamp
+        return self.stamp_base + stamp
+
+    def read_map(self, mapfile):
+        # See http://msdn.microsoft.com/en-us/library/k7xkk3e2.aspx
+        last_addr = 0
+        last_name = 0
+        for line in file(mapfile, "rt"):
+            fields = line.split()
+            try:
+                section_offset, name, addr, type, lib_object = fields
+            except ValueError:
+                continue
+            if type != 'f':
+                continue
+            section, offset = section_offset.split(':')
+            addr = int(offset, 16)
+            name = demangle(name)
+            if last_addr == addr:
+                # TODO: handle collapsed functions
+                #assert last_name == name
+                continue
+            self.symbols.append((addr, name))
+            last_addr = addr
+            last_name = name
+
+        # sort symbols
+        self.symbols.sort(key = lambda (addr, name): addr)
+
+    def lookup_addr(self, addr):
+        try:
+            return self.symbol_cache[addr]
+        except KeyError:
+            pass
+
+        tolerance = 4196
+        s, e = 0, len(self.symbols)
+        while s != e:
+            i = (s + e)//2
+            start_addr, name = self.symbols[i]
+            try:
+                end_addr, next_name = self.symbols[i + 1]
+            except IndexError:
+                end_addr = start_addr + tolerance
+            if addr < start_addr:
+                e = i
+                continue
+            if addr == end_addr:
+                return next_name
+            if addr > end_addr:
+                s = i
+                continue
+            return name
+        return "0x%08x" % addr
+
+    def lookup_symbol(self, name):
+        for symbol_addr, symbol_name in self.symbols:
+            if name == symbol_name:
+                return symbol_addr
+        return 0
+
+    def read_data(self, data):
+        # TODO: compute these automatically
+        caller_overhead = 672 - 2*144 # __debug_profile_reference2 - 2*__debug_profile_reference1
+        callee_overhead = 144 # __debug_profile_reference1
+        callee_overhead -= 48 # tolerance
+        caller_overhead = callee_overhead
+
+        fp = file(data, "rb")
+        entry_format = "II"
+        entry_size = struct.calcsize(entry_format)
+        stack = []
+        last_stamp = 0
+        delta = 0
+        while True:
+            entry = fp.read(entry_size)
+            if len(entry) < entry_size:
+                break
+            addr_exit, stamp = struct.unpack(entry_format, entry)
+            if addr_exit == 0 and stamp == 0:
+                break
+            addr = addr_exit & 0xfffffffe
+            exit = addr_exit & 0x00000001
+
+            if self.base_addr is None:
+                ref_addr = self.lookup_symbol('__debug_profile_reference2')
+                if ref_addr:
+                    self.base_addr = (addr - ref_addr) & ~(options.align - 1)
+                else:
+                    self.base_addr = 0
+                #print hex(self.base_addr)
+            rel_addr = addr - self.base_addr
+            #print hex(addr - self.base_addr)
+
+            name = self.lookup_addr(rel_addr)
+            stamp = self.unwrap_stamp(stamp)
+
+            delta += stamp - last_stamp
+
+            if not exit:
+                if options.verbose >= 2:
+                    print "%10u >> 0x%08x" % (stamp, addr)
+                if options.verbose:
+                    print "%10u >> %s" % (stamp, name)
+                delta -= caller_overhead
+                stack.append((name, stamp, delta))
+                delta = 0
+            else:
+                if options.verbose >= 2:
+                    print "%10u << 0x%08x" % (stamp, addr)
+                if len(stack):
+                    self_time = delta - callee_overhead
+                    entry_name, entry_stamp, delta = stack.pop()
+                    if entry_name != name:
+                        if options.verbose:
+                            print "%10u << %s" % (stamp, name)
+                        #assert entry_name == name
+                        break
+                    total_time = stamp - entry_stamp
+                    self.functions[entry_name] = self.functions.get(entry_name, 0) + self_time
+                    if options.verbose:
+                        print "%10u << %s %+u" % (stamp, name, self_time)
+                else:
+                    delta = 0
+
+            last_stamp = stamp
+
+    def write_report(self):
+        total = sum(self.functions.values())
+        results = self.functions.items()
+        results.sort(key = lambda (name, time): -time)
+        for name, time in results:
+            perc = float(time)/float(total)*100.0
+            print "%6.03f %s" % (perc, name)
 
 
 def main():
-               parser = optparse.OptionParser(
-                       usage="\n\t%prog [options] [file] ...",
-                       version="%%prog %s" % __version__)
-               parser.add_option(
-                       '-a', '--align', metavar='NUMBER',
-                       type="int", dest="align", default=16,
-                       help="section alignment")
-               parser.add_option(
-                       '-m', '--map', metavar='FILE',
-                       type="string", dest="map",
-                       help="map file")
-               parser.add_option(
-                       '-b', '--base', metavar='FILE',
-                       type="string", dest="base",
-                       help="base addr")
-               parser.add_option(
-                       '-v', '--verbose',
-                       action="count",
-                       dest="verbose", default=0,
-                       help="verbose output")
-
-               global options
-               (options, args) = parser.parse_args(sys.argv[1:])
-
-               profile = Profile()
-               if options.base is not None:
-                       profile.base_addr = int(options.base, 16)
-               if options.map is not None:
-                       profile.read_map(options.map)
-               for arg in args:
-                       profile.read_data(arg)
-               profile.write_report()
+    parser = optparse.OptionParser(
+        usage="\n\t%prog [options] [file] ...",
+        version="%%prog %s" % __version__)
+    parser.add_option(
+        '-a', '--align', metavar='NUMBER',
+        type="int", dest="align", default=16,
+        help="section alignment")
+    parser.add_option(
+        '-m', '--map', metavar='FILE',
+        type="string", dest="map",
+        help="map file")
+    parser.add_option(
+        '-b', '--base', metavar='FILE',
+        type="string", dest="base",
+        help="base addr")
+    parser.add_option(
+        '-v', '--verbose',
+        action="count",
+        dest="verbose", default=0,
+        help="verbose output")
+
+    global options
+    (options, args) = parser.parse_args(sys.argv[1:])
+
+    profile = Profile()
+    if options.base is not None:
+        profile.base_addr = int(options.base, 16)
+    if options.map is not None:
+        profile.read_map(options.map)
+    for arg in args:
+        profile.read_data(arg)
+    profile.write_report()
 
 
 if __name__ == '__main__':
-       main()
+    main()