summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorEli Bendersky <eliben@gmail.com>2015-04-19 06:15:22 -0700
committerEli Bendersky <eliben@gmail.com>2015-04-19 06:15:22 -0700
commitb4eed6b221a90320cbc1b37b3f7d8e4bf25ce74a (patch)
treef9831cb5f72c89d03508c7eae5d4b2f1ab73fe28 /utils
parent126492f006edad4dbffda54466e1db679b6700c9 (diff)
downloadpycparser-b4eed6b221a90320cbc1b37b3f7d8e4bf25ce74a.tar.gz
move file into utils/internal
Diffstat (limited to 'utils')
-rw-r--r--utils/internal/memprofiling.py121
1 files changed, 121 insertions, 0 deletions
diff --git a/utils/internal/memprofiling.py b/utils/internal/memprofiling.py
new file mode 100644
index 0000000..5b25120
--- /dev/null
+++ b/utils/internal/memprofiling.py
@@ -0,0 +1,121 @@
+import sys
+from pycparser import parse_file
+from pycparser.c_ast import *
+from pycparser.c_parser import CParser, Coord, ParseError
+from pycparser.c_lexer import CLexer
+
+
+def expand_decl(decl):
+ """ Converts the declaration into a nested list.
+ """
+ typ = type(decl)
+
+ if typ == TypeDecl:
+ return ['TypeDecl', expand_decl(decl.type)]
+ elif typ == IdentifierType:
+ return ['IdentifierType', decl.names]
+ elif typ == ID:
+ return ['ID', decl.name]
+ elif typ in [Struct, Union]:
+ decls = [expand_decl(d) for d in decl.decls or []]
+ return [typ.__name__, decl.name, decls]
+ else:
+ nested = expand_decl(decl.type)
+
+ if typ == Decl:
+ if decl.quals:
+ return ['Decl', decl.quals, decl.name, nested]
+ else:
+ return ['Decl', decl.name, nested]
+ elif typ == Typename: # for function parameters
+ if decl.quals:
+ return ['Typename', decl.quals, nested]
+ else:
+ return ['Typename', nested]
+ elif typ == ArrayDecl:
+ dimval = decl.dim.value if decl.dim else ''
+ return ['ArrayDecl', dimval, nested]
+ elif typ == PtrDecl:
+ return ['PtrDecl', nested]
+ elif typ == Typedef:
+ return ['Typedef', decl.name, nested]
+ elif typ == FuncDecl:
+ if decl.args:
+ params = [expand_decl(param) for param in decl.args.params]
+ else:
+ params = []
+ return ['FuncDecl', params, nested]
+
+#-----------------------------------------------------------------
+class NodeVisitor(object):
+ def __init__(self):
+ self.current_parent = None
+
+ def visit(self, node):
+ """ Visit a node.
+ """
+ method = 'visit_' + node.__class__.__name__
+ visitor = getattr(self, method, self.generic_visit)
+ return visitor(node)
+
+ def visit_FuncCall(self, node):
+ print("Visiting FuncCall")
+ print(node.show())
+ print('---- parent ----')
+ print(self.current_parent.show())
+
+ def generic_visit(self, node):
+ """ Called if no explicit visitor function exists for a
+ node. Implements preorder visiting of the node.
+ """
+ oldparent = self.current_parent
+ self.current_parent = node
+ for c in node.children():
+ self.visit(c)
+ self.current_parent = oldparent
+
+
+def heapyprofile():
+ # pip install guppy
+ # [works on python 2.7, AFAIK]
+ from guppy import hpy
+ import gc
+
+ hp = hpy()
+ ast = parse_file('/tmp/197.c')
+ gc.collect()
+ h = hp.heap()
+ print(h)
+
+
+def memprofile():
+ import resource
+ import tracemalloc
+
+ tracemalloc.start()
+
+ ast = parse_file('/tmp/197.c')
+
+ print('Memory usage: %s (kb)' %
+ resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
+
+ snapshot = tracemalloc.take_snapshot()
+ print("[ tracemalloc stats ]")
+ for stat in snapshot.statistics('lineno')[:20]:
+ print(stat)
+
+
+if __name__ == "__main__":
+ source_code = r'''void foo() {
+ L"hi" L"there";
+}
+ '''
+
+ memprofile()
+ #heapyprofile()
+
+ #parser = CParser()
+ #ast = parser.parse(source_code, filename='zz')
+ #ast.show(showcoord=True, attrnames=True, nodenames=True)
+
+