[pypy-svn] r30700 - in pypy/dist/pypy/translator/stackless: . test
mwh at codespeak.net
mwh at codespeak.net
Fri Jul 28 18:07:15 CEST 2006
Author: mwh
Date: Fri Jul 28 18:07:13 2006
New Revision: 30700
Modified:
pypy/dist/pypy/translator/stackless/test/test_transform.py
pypy/dist/pypy/translator/stackless/transform.py
Log:
move a few more operations inside the stackless 'state saving' functions.
might make a stackless build a little smaller.
Modified: pypy/dist/pypy/translator/stackless/test/test_transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/test/test_transform.py (original)
+++ pypy/dist/pypy/translator/stackless/test/test_transform.py Fri Jul 28 18:07:13 2006
@@ -13,7 +13,10 @@
from pypy import conftest
def test_frame_typer():
- ft = FrameTyper()
+ class TestFrameTyper(FrameTyper):
+ def saving_function_for_type(self, frame_type):
+ return None
+ ft = TestFrameTyper()
ft4vars = lambda types:ft.frame_type_for_vars(types)[0]
signed = varoftype(lltype.Signed)
Modified: pypy/dist/pypy/translator/stackless/transform.py
==============================================================================
--- pypy/dist/pypy/translator/stackless/transform.py (original)
+++ pypy/dist/pypy/translator/stackless/transform.py Fri Jul 28 18:07:13 2006
@@ -20,6 +20,38 @@
from pypy.translator.stackless.frame import STATE_HEADER, null_state
from pypy.translator.stackless.frame import storage_type
+SAVE_STATISTICS = True
+
+if SAVE_STATISTICS:
+ import cStringIO
+
+ class StacklessStats:
+ def __init__(self):
+ self.rp_count = 0
+ self.rp_type_counts = {}
+ self.rp_per_graph = {}
+ self.rp_per_graph_type_counts = {}
+ self.saveops = self.resumeops = 0
+ self.pot_exact_saves = {}
+ self.total_pot_exact_saves = 0
+ self.pot_erased_saves = {}
+ self.total_pot_erased_saves = 0
+ def __repr__(self):
+ s = cStringIO.StringIO()
+ print >> s, self.__class__.__name__
+ for k in sorted(self.__dict__.keys()):
+ r = repr(self.__dict__[k])
+ if len(r) > 60:
+ r = r[:50] + '...'
+ print >>s, ' '+k, r
+ return s.getvalue()
+
+ def inc(d, key):
+ d[key] = d.get(key, 0) + 1
+
+ def gkey(graph):
+ return (graph.name, id(graph))
+
# a simple example of what the stackless transform does
#
# def func(x):
@@ -71,10 +103,12 @@
class FrameTyper:
# this class only exists independently to ease testing
- def __init__(self, stackless_gc=False):
+ def __init__(self, stackless_gc=False, transformer=None):
self.frametypes = {}
self.stackless_gc = stackless_gc
self.c_gc_nocollect = model.Constant("gc_nocollect", lltype.Void)
+ self.transformer = transformer
+
def _key_for_types(self, types):
counts = {}
@@ -87,7 +121,11 @@
return key
def saving_function_for_type(self, FRAME_TYPE):
- save_block = model.Block([])
+ v_restart = varoftype(lltype.Signed)
+ v_exception = varoftype(self.transformer.unwind_exception_type)
+
+ save_block = model.Block([v_restart, v_exception])
+
llops = LowLevelOpList()
if self.stackless_gc:
v_state = llops.genop(
@@ -108,14 +146,21 @@
[v_state, model.Constant(fieldname, lltype.Void), var],
resulttype=lltype.Void)
+ v_header = gen_cast(llops, lltype.Ptr(STATE_HEADER), v_state)
+ llops.genop('direct_call',
+ [self.transformer.add_frame_state_ptr, v_exception, v_header],
+ resulttype=lltype.Void)
+ llops.genop("setfield",
+ [v_header, self.transformer.c_f_restart_name, v_restart],
+ resulttype=lltype.Void)
+
save_state_graph = model.FunctionGraph('save_' + FRAME_TYPE._name, save_block,
- unsimplify.copyvar(None, v_state))
+ varoftype(lltype.Void))
save_block.operations = llops
- save_block.closeblock(model.Link([v_state], save_state_graph.returnblock))
-
+ save_block.closeblock(model.Link([v_header], save_state_graph.returnblock))
FUNC_TYPE = lltype.FuncType([v.concretetype for v in save_block.inputargs],
- v_state.concretetype)
+ lltype.Void)
return lltype.functionptr(FUNC_TYPE, save_state_graph.name,
graph=save_state_graph)
@@ -125,13 +170,17 @@
if key not in self.frametypes:
fields = []
fieldsbytype = {}
+ tcounts = []
for t in STORAGE_TYPES:
- for j in range(key.get(t, 0)):
+ tcount = key.get(t, 0)
+ tcounts.append(str(tcount))
+ for j in range(tcount):
fname = 'state_%s_%d' % (STORAGE_FIELDS[t], j)
fields.append((fname, t))
fieldsbytype.setdefault(t, []).append(fname)
- FRAME_TYPE = frame.make_state_header_type("FrameState", *fields)
+ FRAME_TYPE = frame.make_state_header_type(
+ "FrameState_"+'_'.join(tcounts), *fields)
self.frametypes[key] = (FRAME_TYPE,
self.saving_function_for_type(FRAME_TYPE),
fieldsbytype)
@@ -214,7 +263,7 @@
self.translator = translator
self.stackless_gc = stackless_gc
- self.frametyper = FrameTyper(stackless_gc)
+ self.frametyper = FrameTyper(stackless_gc, self)
self.masterarray1 = []
self.curr_graph = None
@@ -388,6 +437,9 @@
self.frametyper.ensure_frame_type_for_types(frame_type)
self.register_restart_info(restartinfo)
+ if SAVE_STATISTICS:
+ translator.stackless_stats = self.stats = StacklessStats()
+
def transform_all(self):
for graph in self.translator.graphs:
self.transform_graph(graph)
@@ -407,6 +459,10 @@
assert self.curr_graph is None
self.curr_graph = graph
+ if SAVE_STATISTICS:
+ self.stats.cur_rp_exact_types = {}
+ self.stats.cur_rp_erased_types = {}
+
for block in list(graph.iterblocks()):
assert block not in self.seen_blocks
@@ -419,6 +475,23 @@
model.checkgraph(graph)
+ if SAVE_STATISTICS:
+ pot_exact_save_count = 0
+ for t, count in self.stats.cur_rp_exact_types.items():
+ pot_exact_save_count += count - 1
+ del self.stats.cur_rp_exact_types
+ self.stats.pot_exact_saves[gkey(self.curr_graph)] = pot_exact_save_count
+ self.stats.total_pot_exact_saves += pot_exact_save_count
+
+ pot_erased_save_count = 0
+ for t, count in self.stats.cur_rp_erased_types.items():
+ pot_erased_save_count += count - 1
+ del self.stats.cur_rp_erased_types
+ self.stats.pot_erased_saves[gkey(self.curr_graph)] = pot_erased_save_count
+ self.stats.total_pot_erased_saves += pot_erased_save_count
+
+
+
self.curr_graph = None
def ops_read_global_state_field(self, targetvar, fieldname):
@@ -752,6 +825,18 @@
def generate_save_and_resume_blocks(self, varstosave, var_exception,
var_result, links_to_resumption):
frame_type, fieldnames, varsforcall, saver = self.frametyper.frame_type_for_vars(varstosave)
+ if SAVE_STATISTICS:
+ self.stats.rp_count += 1
+ inc(self.stats.rp_type_counts, frame_type)
+ inc(self.stats.rp_per_graph, gkey(self.curr_graph))
+ inc(self.stats.rp_per_graph_type_counts.setdefault(gkey(self.curr_graph), {}), frame_type)
+ exact_key = [v.concretetype for v in varstosave]
+ exact_key.sort()
+ exact_key = (tuple(exact_key), var_result.concretetype)
+ inc(self.stats.cur_rp_exact_types, exact_key)
+ inc(self.stats.cur_rp_erased_types, frame_type)
+
+
return (self._generate_save_block(varsforcall, var_exception,
frame_type, fieldnames, saver),
self._generate_resume_block(varstosave, frame_type, fieldnames,
@@ -770,26 +855,17 @@
save_state_block = model.Block(inputargs + [var_unwind_exception])
saveops = LowLevelOpList()
- realvarsforcall = []
+ var_exc = gen_cast(saveops, self.unwind_exception_type, var_unwind_exception)
+
+ c_restart = model.Constant(len(self.masterarray1) + len(self.resume_blocks), lltype.Signed)
+
+ realvarsforcall = [c_restart, var_exc]
for v in inputargs:
realvarsforcall.append(gen_cast(saveops, storage_type(v.concretetype), v))
- frame_state_var = saveops.genop('direct_call',
- [model.Constant(saver, lltype.typeOf(saver))] + realvarsforcall,
- resulttype=lltype.Ptr(frame_type))
-
- var_exc = gen_cast(saveops, self.unwind_exception_type, var_unwind_exception)
- var_header = gen_cast(saveops, lltype.Ptr(STATE_HEADER), frame_state_var)
-
- saveops.genop('direct_call', [self.add_frame_state_ptr, var_exc, var_header],
+ saveops.genop('direct_call',
+ [model.Constant(saver, lltype.typeOf(saver))] + realvarsforcall,
resulttype=lltype.Void)
-
- f_restart = len(self.masterarray1) + len(self.resume_blocks)
-
- saveops.genop("setfield",
- [var_header, self.c_f_restart_name, model.Constant(f_restart, lltype.Signed)],
- resulttype=lltype.Void)
-
save_state_block.operations = saveops
type_repr = rclass.get_type_repr(rtyper)
@@ -804,6 +880,8 @@
self.curr_graph.exceptblock))
self.translator.rtyper._convert_link(
save_state_block, save_state_block.exits[0])
+ if SAVE_STATISTICS:
+ self.stats.saveops += len(save_state_block.operations)
return save_state_block
def _generate_resume_block(self, varstosave, frame_type, fieldnames,
@@ -867,6 +945,8 @@
self.insert_return_conversion(
newblock.exits[0], var_result.concretetype, retval)
+ if SAVE_STATISTICS:
+ self.stats.resumeops += len(newblock.operations)
return newblock
def generate_saveops(self, frame_state_var, varstosave, fieldnames):
@@ -894,6 +974,10 @@
def finish(self):
# compute the final masterarray by copying over the masterarray1,
# which is a list of dicts of attributes
+ if SAVE_STATISTICS:
+ import cPickle
+ cPickle.dump(self.stats, open('stackless-stats.pickle', 'wb'))
+
self.is_finished = True
masterarray = lltype.malloc(frame.FRAME_INFO_ARRAY,
len(self.masterarray1),
More information about the Pypy-commit
mailing list