[pypy-svn] r58822 - in pypy/dist/pypy: bin config translator translator/tool
antocuni at codespeak.net
antocuni at codespeak.net
Wed Oct 8 15:28:36 CEST 2008
Author: antocuni
Date: Wed Oct 8 15:28:35 2008
New Revision: 58822
Added:
pypy/dist/pypy/bin/reportstaticdata.py (contents, props changed)
Modified:
pypy/dist/pypy/config/translationoption.py
pypy/dist/pypy/translator/driver.py
pypy/dist/pypy/translator/tool/staticsizereport.py
Log:
(antocuni, xoraxax)
- add an option to translate.py to save the info about static data
- add a script to produce report using that data
Added: pypy/dist/pypy/bin/reportstaticdata.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/bin/reportstaticdata.py Wed Oct 8 15:28:35 2008
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+"""
+Usage: reportstaticdata.py [-m1|-m2|-t] [OPTION]... FILENAME
+Print a report for the static data informations contained in FILENAME
+
+The static data informations are saved in the file staticdata.info when
+passing --dump_static_data_info to translate.py.
+
+Options:
+
+ -m1 Print a report for each module, counting constants that are
+ reacheable from more than one module multiple times (default)
+
+ -m2 Print a report for each module, counting constants that are
+ reacheable from more than one module only in the first module
+ seen
+
+ -t Print a global report for all the constants
+
+ -h Print sizes in human readable formats (e.g., 1K 234M)
+
+ -s Print only the total size for each module
+
+ -u Print the list of graphs which belongs to unknown modules
+
+ --help Show this help message
+"""
+
+import autopath
+from pypy.translator.tool.staticsizereport import print_report
+
+def parse_options(argv):
+ kwds = {}
+ for arg in argv:
+ if arg.startswith('-'):
+ if arg == '-m1':
+ assert 'kind' not in kwds
+ kwds['kind'] = 'by_module_with_duplicates'
+ elif arg == '-m2':
+ assert 'kind' not in kwds
+ kwds['kind'] = 'by_module_without_duplicates'
+ elif arg == '-t':
+ assert 'kind' not in kwds
+ kwds['kind'] = 'by_type'
+ elif arg == '-h':
+ kwds['human_readable'] = True
+ elif arg == '-s':
+ kwds['summary'] = True
+ elif arg == '-u':
+ kwds['show_unknown_graphs'] = True
+ elif arg == '--help':
+ raise AssertionError
+ else:
+ assert 'filename' not in kwds
+ kwds['filename'] = arg
+
+ assert 'filename' in kwds
+ return kwds
+
+
+def main():
+ import sys
+ try:
+ kwds = parse_options(sys.argv[1:])
+ except AssertionError:
+ print >> sys.stderr, __doc__
+ sys.exit(1)
+ print_report(**kwds)
+
+if __name__ == '__main__':
+ main()
Modified: pypy/dist/pypy/config/translationoption.py
==============================================================================
--- pypy/dist/pypy/config/translationoption.py (original)
+++ pypy/dist/pypy/config/translationoption.py Wed Oct 8 15:28:35 2008
@@ -122,6 +122,10 @@
default=None),
StrOption("output", "Output file name", cmdline="--output"),
+ BoolOption("dump_static_data_info", "Dump static data info",
+ cmdline="--dump_static_data_info",
+ default=False, requires=[("translation.backend", "c")]),
+
# portability options
BoolOption("vanilla",
"Try to be as portable as possible, which is not much",
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Wed Oct 8 15:28:35 2008
@@ -491,6 +491,11 @@
database = self.database
c_source_filename = cbuilder.generate_source(database)
self.log.info("written: %s" % (c_source_filename,))
+ if self.config.translation.dump_static_data_info:
+ from pypy.translator.tool.staticsizereport import dump_static_data_info
+ targetdir = cbuilder.targetdir
+ dump_static_data_info(self.log, database, targetdir)
+
#
task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source")
Modified: pypy/dist/pypy/translator/tool/staticsizereport.py
==============================================================================
--- pypy/dist/pypy/translator/tool/staticsizereport.py (original)
+++ pypy/dist/pypy/translator/tool/staticsizereport.py Wed Oct 8 15:28:35 2008
@@ -1,10 +1,40 @@
from __future__ import division
+import cPickle as pickle
+from pypy.tool.ansicolor import red, yellow, green
from pypy.rpython.lltypesystem.lltype import typeOf, _ptr, Ptr, ContainerType
from pypy.rpython.lltypesystem import llmemory
from pypy.rpython.memory.lltypelayout import convert_offset_to_int
+class Info:
+ pass
+class ModuleReport:
+ def __init__(self, modulename, totalsize, typereports):
+ self.modulename = modulename
+ self.totalsize = totalsize
+ self.typereports = typereports
+
+ def __repr__(self):
+ return 'ModuleReport(%s, %d, ...)' % (self.modulename, self.totalsize)
+
+ def __cmp__(self, other):
+ return cmp((self.totalsize, self.modulename), (other.totalsize, other.modulename))
+
+class TypeReport:
+ def __init__(self, typename, size, numobjects):
+ self.typename = typename
+ self.size = size
+ self.numobjects = numobjects
+
+ def __repr__(self):
+ return 'TypeReport(%s, %d, %d)' % (self.typename, self.size, self.numobjects)
+
+ def __cmp__(self, other):
+ return cmp((self.size, self.typename), (other.size, other.typename))
+
+
+## Functions used by translate.py
def guess_module(graph):
func = getattr(graph, 'func', None)
name = None
@@ -60,7 +90,7 @@
def by_lltype(obj):
- return typeOf(obj)
+ return repr(typeOf(obj))
def group_static_size(database, nodes, grouper=by_lltype, recursive=None):
totalsize = {}
@@ -78,22 +108,11 @@
l.sort()
l.reverse()
sizesum = 0
- report = []
+ typereports = []
for size, key in l:
sizesum += size
- report.append((key, size, numobjects[key], size / numobjects[key]))
- return sizesum, report
-
-def format_report_line(line):
- return str(line[0])[:50] + " " + " ".join([str(x) for x in line[1:]])
-
-
-def print_report_static_size(database, grouper=by_lltype):
- " Reports all objects with a specified grouper. "
- _, report = make_report_static_size(database.globalcontainers(), grouper)
- for line in report:
- print format_report_line(line)
-
+ typereports.append(TypeReport(key, size, numobjects[key]))
+ return sizesum, typereports
def get_unknown_graphs(database):
funcnodes = [node for node in database.globalcontainers() if node.nodekind == "func"]
@@ -104,7 +123,14 @@
if not guess_module(graph):
yield graph
-def print_aggregated_values_by_module_and_type(database, count_modules_separately=False, verbose=False):
+def get_unknown_graphs_names(database):
+ return [getattr(graph, 'name', '???') for graph in get_unknown_graphs(database)]
+
+def aggregate_values_by_type(database):
+ size, typereports = make_report_static_size(database, database.globalcontainers(), by_lltype)
+ return [ModuleReport('<global>', size, typereports)]
+
+def aggregate_values_by_module_and_type(database, count_modules_separately=False):
" Reports all objects by module and by lltype. "
modules = {}
reports = []
@@ -133,18 +159,69 @@
seen = set()
if not nodes:
continue
- size, report = make_report_static_size(database, nodes, by_lltype, seen)
- reports.append((size, modulename, report))
+ size, typereports = make_report_static_size(database, nodes, by_lltype, seen)
+ reports.append(ModuleReport(modulename, size, typereports))
reports.sort()
reports.reverse()
- for size, modulename, report in reports:
- if not size:
+ return reports
+
+def dump_static_data_info(log, database, targetdir):
+ info = Info()
+ info.by_module_with_duplicates = aggregate_values_by_module_and_type(database, False)
+ info.by_module_without_duplicates = aggregate_values_by_module_and_type(database, True)
+ info.by_type = aggregate_values_by_type(database)
+ info.unknown_graphs = get_unknown_graphs_names(database)
+ infofile = targetdir.join('staticdata.info')
+ f = infofile.open('w')
+ pickle.dump(info, f)
+ f.close()
+ log.info('static data informations dumped to %s' % infofile)
+
+
+## Functions used by the reportstaticdata.py script
+def format_typereport(rep, human_readable=True):
+ size = format_size(rep.size, human_readable)
+ return format_line(rep.typename[:50], size, rep.numobjects)
+
+def format_line(a, b, c):
+ return ' %50s %10s %6s' % (a, b, c)
+
+def format_size(size, human_readable=False):
+ KB = 1024.0
+ MB = KB*KB
+ if human_readable:
+ if size >= MB:
+ return '%.2fM' % (size/MB)
+ if size >= KB:
+ return '%.2fK' % (size/KB)
+ return '%d' % size
+ return size
+
+def print_report(filename,
+ kind='by_module_with_duplicates',
+ summary=False,
+ show_unknown_graphs=False,
+ human_readable=True):
+ f = open(filename)
+ info = pickle.load(f)
+ f.close()
+ reports = getattr(info, kind)
+
+ for report in reports:
+ if report.totalsize == 0:
continue
- if verbose:
- print "########### %i %s ####################################" % (size, modulename)
- for line in report:
- print " " * 4 + format_report_line(line)
- print
+ size = format_size(report.totalsize, human_readable)
+ if summary:
+ print "%d\t%s" % (size, report.modulename)
else:
- print "%i\%s" % (size, modulename)
+ print '%s: %s' % (red(report.modulename), yellow(size))
+ print green(format_line('Typename', 'Size', 'Num'))
+ for typereport in report.typereports:
+ print format_typereport(typereport, human_readable)
+ print
+ if show_unknown_graphs:
+ print
+ print green('Unknown graphs:')
+ for graphname in info.unknown_graphs:
+ print graphname
More information about the Pypy-commit
mailing list