]> git.cworth.org Git - apitrace/blobdiff - scripts/unpickle.py
d3dretrace: Use DirectXTex for d3d10 state too.
[apitrace] / scripts / unpickle.py
index 3f0bc42fc34ce6c1b01a9128ddaddeda754d9ab1..50d8480aac948143f78c091bb5198d2a04ec4773 100755 (executable)
@@ -56,40 +56,44 @@ class Visitor:
         self.dispatch[dict] = self.visitDict
         self.dispatch[bytearray] = self.visitByteArray
 
-    def visit(self, obj, *args, **kwargs):
-        return self.dispatch[type(obj)](obj, *args, **kwargs)
+    def visit(self, obj):
+        method = self.dispatch.get(type(obj), self.visitObj)
+        return method(obj)
 
-    def visitAtom(self, obj, *args, **kwargs):
+    def visitObj(self, obj):
         raise NotImplementedError
 
-    def visitNone(self, obj, *args, **kwargs):
-        return self.visitAtom(obj, *args, **kwargs)
+    def visitAtom(self, obj):
+        return self.visitObj(obj)
 
-    def visitBool(self, obj, *args, **kwargs):
-        return self.visitAtom(obj, *args, **kwargs)
+    def visitNone(self, obj):
+        return self.visitAtom(obj)
 
-    def visitInt(self, obj, *args, **kwargs):
-        return self.visitAtom(obj, *args, **kwargs)
+    def visitBool(self, obj):
+        return self.visitAtom(obj)
 
-    def visitFloat(self, obj, *args, **kwargs):
-        return self.visitAtom(obj, *args, **kwargs)
+    def visitInt(self, obj):
+        return self.visitAtom(obj)
 
-    def visitStr(self, obj, *args, **kwargs):
-        return self.visitAtom(obj, *args, **kwargs)
+    def visitFloat(self, obj):
+        return self.visitAtom(obj)
 
-    def visitIterable(self, obj, *args, **kwargs):
-        raise NotImplementedError
+    def visitStr(self, obj):
+        return self.visitAtom(obj)
+
+    def visitIterable(self, obj):
+        return self.visitObj(obj)
 
-    def visitTuple(self, obj, *args, **kwargs):
-        return self.visitIterable(obj, *args, **kwargs)
+    def visitTuple(self, obj):
+        return self.visitIterable(obj)
 
-    def visitList(self, obj, *args, **kwargs):
-        return self.visitIterable(obj, *args, **kwargs)
+    def visitList(self, obj):
+        return self.visitIterable(obj)
 
-    def visitDict(self, obj, *args, **kwargs):
+    def visitDict(self, obj):
         raise NotImplementedError
 
-    def visitByteArray(self, obj, *args, **kwargs):
+    def visitByteArray(self, obj):
         raise NotImplementedError
 
 
@@ -97,38 +101,65 @@ class Dumper(Visitor):
 
     id_re = re.compile('^[_A-Za-z][_A-Za-z0-9]*$')
 
-    def visitAtom(self, obj, *args, **kwargs):
+    def visitObj(self, obj):
         return repr(obj)
 
-    def visitStr(self, obj, *args, **kwargs):
+    def visitStr(self, obj):
         if self.id_re.match(obj):
             return obj
         else:
             return repr(obj)
 
-    def visitTuple(self, obj, *args, **kwargs):
+    def visitTuple(self, obj):
         return '[' + ', '.join(itertools.imap(self.visit, obj)) + ']'
 
-    def visitList(self, obj, *args, **kwargs):
+    def visitList(self, obj):
         return '(' + ', '.join(itertools.imap(self.visit, obj)) + ')'
 
-    def visitByteArray(self, obj, *args, **kwargs):
+    def visitByteArray(self, obj):
         return 'blob(%u)' % len(obj)
 
 
 class Hasher(Visitor):
     '''Returns a hashable version of the objtree.'''
 
-    def visitAtom(self, obj, *args, **kwargs):
+    def visitObj(self, obj):
         return obj
 
-    def visitIterable(self, obj, *args, **kwargs):
+    def visitAtom(self, obj):
+        return obj
+
+    def visitIterable(self, obj):
         return tuple(itertools.imap(self.visit, obj))
 
-    def visitByteArray(self, obj, *args, **kwargs):
+    def visitByteArray(self, obj):
         return str(obj)
 
 
+class Rebuilder(Visitor):
+    '''Returns a hashable version of the objtree.'''
+
+    def visitAtom(self, obj):
+        return obj
+
+    def visitIterable(self, obj):
+        changed = False
+        newItems = []
+        for oldItem in obj:
+            newItem = self.visit(oldItem)
+            if newItem is not oldItem:
+                changed = True
+            newItems.append(newItem)
+        if changed:
+            klass = type(obj)
+            return klass(newItems)
+        else:
+            return obj
+
+    def visitByteArray(self, obj):
+        return obj
+
+
 class Call:
 
     def __init__(self, callTuple):
@@ -187,25 +218,42 @@ class Unpickler:
 
 class Counter(Unpickler):
 
-    def __init__(self, stream, quiet):
+    def __init__(self, stream, verbose = False):
         Unpickler.__init__(self, stream)
-        self.quiet = quiet
-        self.calls = 0
+        self.verbose = verbose
+        self.numCalls = 0
+        self.functionFrequencies = {}
+
+    def parse(self):
+        Unpickler.parse(self)
+
+        functionFrequencies = self.functionFrequencies.items()
+        functionFrequencies.sort(lambda (name1, freq1), (name2, freq2): cmp(freq1, freq2))
+        for name, frequency in functionFrequencies:
+            sys.stdout.write('%8u %s\n' % (frequency, name))
 
     def handleCall(self, call):
-        if not self.quiet:
+        if self.verbose:
             sys.stdout.write(str(call))
             sys.stdout.write('\n')
-        self.calls += 1
+        self.numCalls += 1
+        try:
+            self.functionFrequencies[call.functionName] += 1
+        except KeyError:
+            self.functionFrequencies[call.functionName] = 1
 
 
 def main():
     optparser = optparse.OptionParser(
-        usage="\n\tapitrace pickle trace. %prog [options]")
+        usage="\n\tapitrace pickle <trace> | %prog [options]")
     optparser.add_option(
-        '--quiet',
-        action="store_true", dest="quiet", default=False,
-        help="don't dump calls to stdout")
+        '-p', '--profile',
+        action="store_true", dest="profile", default=False,
+        help="profile call parsing")
+    optparser.add_option(
+        '-v', '--verbose',
+        action="store_true", dest="verbose", default=False,
+        help="dump calls to stdout")
 
     (options, args) = optparser.parse_args(sys.argv[1:])
 
@@ -222,11 +270,13 @@ def main():
         msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
 
     startTime = time.time()
-    parser = Counter(sys.stdin, options.quiet)
+    parser = Counter(sys.stdin, options.verbose)
     parser.parse()
     stopTime = time.time()
     duration = stopTime - startTime
-    sys.stderr.write('%u calls, %.03f secs, %u calls/sec\n' % (parser.calls, duration, parser.calls/duration))
+
+    if options.profile:
+        sys.stderr.write('Processed %u calls in %.03f secs, at %u calls/sec\n' % (parser.numCalls, duration, parser.numCalls/duration))
 
 
 if __name__ == '__main__':