Tools/scripts/dump_bytecode.py (49 lines of code) (raw):

# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) import argparse import dis import types from typing import Dict, List, Tuple CountAssocs = List[Tuple[str, int]] Histogram = Dict[str, int] def count_bytecode(func: types.FunctionType, histo: Histogram) -> None: """Return a distribution of bytecode in func""" for instr in dis.get_instructions(func): if instr.opname in histo: histo[instr.opname] += 1 else: histo[instr.opname] = 1 def summarize(obj: object, histo: Histogram) -> None: """Compute the bytecode histogram of all functions reachable from obj""" if isinstance(obj, types.FunctionType): count_bytecode(obj, histo) elif isinstance(obj, type): for child in obj.__dict__.values(): summarize(child, histo) SORT_ALPHA = "alpha" SORT_COUNT = "count" SORT_OPTIONS = (SORT_ALPHA, SORT_COUNT) def sort_alpha(histo: Histogram) -> CountAssocs: ordered = sorted(histo.items(), key=lambda p: p[0]) return list(ordered) def sort_count(histo: Histogram) -> CountAssocs: ordered = sorted(histo.items(), key=lambda p: p[1], reverse=True) return list(ordered) SORT_FUNCS = { SORT_ALPHA: sort_alpha, SORT_COUNT: sort_count, } if __name__ == "__main__": parser = argparse.ArgumentParser( description= """ Read and exec the contents of path and dump the distribution of bytecode for every function that was created. """ ) parser.add_argument("path", help="path to file to exec") parser.add_argument("--sort", help="how to sort the output", default=SORT_COUNT, choices=SORT_OPTIONS) args = parser.parse_args() with open(args.path) as f: data = f.read() globals = {} exec(data, globals, globals) histo = {} for obj in globals.values(): summarize(obj, histo) ordered = SORT_FUNCS[args.sort](histo) for name, count in ordered: print("%-20s %d" % (name, count))