memprofiling.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import sys
  2. from pycparser import parse_file
  3. from pycparser.c_ast import *
  4. from pycparser.c_parser import CParser, Coord, ParseError
  5. from pycparser.c_lexer import CLexer
  6. def expand_decl(decl):
  7. """ Converts the declaration into a nested list.
  8. """
  9. typ = type(decl)
  10. if typ == TypeDecl:
  11. return ['TypeDecl', expand_decl(decl.type)]
  12. elif typ == IdentifierType:
  13. return ['IdentifierType', decl.names]
  14. elif typ == ID:
  15. return ['ID', decl.name]
  16. elif typ in [Struct, Union]:
  17. decls = [expand_decl(d) for d in decl.decls or []]
  18. return [typ.__name__, decl.name, decls]
  19. else:
  20. nested = expand_decl(decl.type)
  21. if typ == Decl:
  22. if decl.quals:
  23. return ['Decl', decl.quals, decl.name, nested]
  24. else:
  25. return ['Decl', decl.name, nested]
  26. elif typ == Typename: # for function parameters
  27. if decl.quals:
  28. return ['Typename', decl.quals, nested]
  29. else:
  30. return ['Typename', nested]
  31. elif typ == ArrayDecl:
  32. dimval = decl.dim.value if decl.dim else ''
  33. return ['ArrayDecl', dimval, nested]
  34. elif typ == PtrDecl:
  35. return ['PtrDecl', nested]
  36. elif typ == Typedef:
  37. return ['Typedef', decl.name, nested]
  38. elif typ == FuncDecl:
  39. if decl.args:
  40. params = [expand_decl(param) for param in decl.args.params]
  41. else:
  42. params = []
  43. return ['FuncDecl', params, nested]
  44. #-----------------------------------------------------------------
  45. class NodeVisitor(object):
  46. def __init__(self):
  47. self.current_parent = None
  48. def visit(self, node):
  49. """ Visit a node.
  50. """
  51. method = 'visit_' + node.__class__.__name__
  52. visitor = getattr(self, method, self.generic_visit)
  53. return visitor(node)
  54. def visit_FuncCall(self, node):
  55. print("Visiting FuncCall")
  56. print(node.show())
  57. print('---- parent ----')
  58. print(self.current_parent.show())
  59. def generic_visit(self, node):
  60. """ Called if no explicit visitor function exists for a
  61. node. Implements preorder visiting of the node.
  62. """
  63. oldparent = self.current_parent
  64. self.current_parent = node
  65. for c in node.children():
  66. self.visit(c)
  67. self.current_parent = oldparent
  68. def heapyprofile():
  69. # pip install guppy
  70. # [works on python 2.7, AFAIK]
  71. from guppy import hpy
  72. import gc
  73. hp = hpy()
  74. ast = parse_file('/tmp/197.c')
  75. gc.collect()
  76. h = hp.heap()
  77. print(h)
  78. def memprofile():
  79. import resource
  80. import tracemalloc
  81. tracemalloc.start()
  82. ast = parse_file('/tmp/197.c')
  83. print('Memory usage: %s (kb)' %
  84. resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
  85. snapshot = tracemalloc.take_snapshot()
  86. print("[ tracemalloc stats ]")
  87. for stat in snapshot.statistics('lineno')[:20]:
  88. print(stat)
  89. if __name__ == "__main__":
  90. source_code = r'''void foo() {
  91. L"hi" L"there";
  92. }
  93. '''
  94. memprofile()
  95. #heapyprofile()
  96. #parser = CParser()
  97. #ast = parser.parse(source_code, filename='zz')
  98. #ast.show(showcoord=True, attrnames=True, nodenames=True)