[pypy-svn] r29740 - pypy/dist/pypy/translator/stackless
mwh at codespeak.net
mwh at codespeak.net
Fri Jul 7 15:37:07 CEST 2006
Author: mwh
Date: Fri Jul 7 15:37:05 2006
New Revision: 29740
Modified:
pypy/dist/pypy/translator/stackless/transform.py
Log:
(misto, mwh)
Use a function to save the required state rather than having the saving
operations inline all the time.
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 7 15:37:05 2006
@@ -71,8 +71,9 @@
class FrameTyper:
# this class only exists independently to ease testing
- def __init__(self):
+ def __init__(self, stackless_gc=False):
self.frametypes = {}
+ self.stackless_gc = stackless_gc
def _key_for_types(self, types):
counts = {}
@@ -84,6 +85,40 @@
key = lltype.frozendict(counts)
return key
+ def saving_function_for_type(self, FRAME_TYPE):
+ save_block = model.Block([])
+ llops = LowLevelOpList()
+ if self.stackless_gc:
+ v_state = llops.genop(
+ 'flavored_malloc',
+ [self.c_gc_nocollect, model.Constant(FRAME_TYPE, lltype.Void)],
+ resulttype=lltype.Ptr(FRAME_TYPE))
+ else:
+ v_state = llops.genop(
+ 'malloc',
+ [model.Constant(FRAME_TYPE, lltype.Void)],
+ resulttype=lltype.Ptr(FRAME_TYPE))
+
+ for fieldname in FRAME_TYPE._names[1:]: # skip the 'header' field
+ TYPE = FRAME_TYPE._flds[fieldname]
+ var = varoftype(TYPE)
+ save_block.inputargs.append(var)
+ llops.genop('setfield',
+ [v_state, model.Constant(fieldname, lltype.Void), var],
+ resulttype=lltype.Void)
+
+ save_state_graph = model.FunctionGraph('save_' + FRAME_TYPE._name, save_block,
+ unsimplify.copyvar(None, v_state))
+ save_block.operations = llops
+ save_block.closeblock(model.Link([v_state], save_state_graph.returnblock))
+
+
+ FUNC_TYPE = lltype.FuncType([v.concretetype for v in save_block.inputargs],
+ v_state.concretetype)
+ return lltype.functionptr(FUNC_TYPE, save_state_graph.name,
+ graph=save_state_graph)
+
+
def frame_type_for_vars(self, vars):
key = self._key_for_types([v.concretetype for v in vars])
if key not in self.frametypes:
@@ -94,21 +129,31 @@
fname = 'state_%s_%d' % (STORAGE_FIELDS[t], j)
fields.append((fname, t))
fieldsbytype.setdefault(t, []).append(fname)
- self.frametypes[key] = (frame.make_state_header_type("FrameState", *fields),
+
+ FRAME_TYPE = frame.make_state_header_type("FrameState", *fields)
+ self.frametypes[key] = (FRAME_TYPE,
+ self.saving_function_for_type(FRAME_TYPE),
fieldsbytype)
- T, fieldsbytype = self.frametypes[key]
+
+ T, save_state_funcptr, fieldsbytype = self.frametypes[key]
data = {}
for (k, fs) in fieldsbytype.iteritems():
data[k] = fs[:]
fieldnames = []
+ varsforcall = [[] for t in STORAGE_TYPES]
for v in vars:
if v.concretetype is lltype.Void:
fieldnames.append(None)
+ varsforcall.append([])
else:
t = storage_type(v.concretetype)
+ varsforcall[STORAGE_TYPES.index(t)].append(v)
fieldnames.append(data[t].pop(0))
+ varsforcall_ = []
+ for l in varsforcall:
+ varsforcall_.extend(l)
assert max([0] + [len(v) for v in data.itervalues()]) == 0
- return T, fieldnames
+ return T, fieldnames, varsforcall_, save_state_funcptr
def ensure_frame_type_for_types(self, frame_type):
assert len(frame_type._names[1:]) <= 1, "too lazy"
@@ -122,7 +167,9 @@
fieldsbytype = {}
if key in self.frametypes:
assert self.frametypes[key][0] is frame_type
- self.frametypes[key] = (frame_type, fieldsbytype)
+ self.frametypes[key] = (frame_type,
+ self.saving_function_for_type(frame_type),
+ fieldsbytype)
class StacklessAnalyzer(graphanalyze.GraphAnalyzer):
@@ -166,7 +213,7 @@
self.translator = translator
self.stackless_gc = stackless_gc
- self.frametyper = FrameTyper()
+ self.frametyper = FrameTyper(stackless_gc)
self.masterarray1 = []
self.curr_graph = None
@@ -457,7 +504,8 @@
res = op.result
(frame_type,
- fieldnames) = self.frametyper.frame_type_for_vars(parms[1:])
+ fieldnames,
+ varsforcall, saver) = self.frametyper.frame_type_for_vars(parms[1:])
label = op.args[0].value
@@ -488,7 +536,7 @@
# XXX we do not look at op.args[0], the prevstate, at all
label = op.args[1].value
parms = op.args[2:]
- FRAME, fieldnames = self.frametyper.frame_type_for_vars(parms)
+ FRAME, fieldnames, varsforcall, saver = self.frametyper.frame_type_for_vars(parms)
if label in self.explicit_resume_point_data:
other_type = self.explicit_resume_point_data[label]
@@ -615,12 +663,12 @@
args = vars_to_save(block)
- save_block, resume_block = self.generate_save_and_resume_blocks(
+ save_block, resume_block, varsforcall = self.generate_save_and_resume_blocks(
args, var_unwind_exception, op.result, block.exits)
self.resume_blocks.append(resume_block)
- newlink = model.Link(args + [var_unwind_exception],
+ newlink = model.Link(varsforcall + [var_unwind_exception],
save_block, code.UnwindException)
newlink.last_exception = model.Constant(code.UnwindException,
etype)
@@ -696,59 +744,46 @@
def generate_save_and_resume_blocks(self, varstosave, var_exception,
var_result, links_to_resumption):
- frame_type, fieldnames = self.frametyper.frame_type_for_vars(varstosave)
- return (self._generate_save_block(varstosave, var_exception, frame_type, fieldnames),
+ frame_type, fieldnames, varsforcall, saver = self.frametyper.frame_type_for_vars(varstosave)
+ return (self._generate_save_block(varsforcall, var_exception,
+ frame_type, fieldnames, saver),
self._generate_resume_block(varstosave, frame_type, fieldnames,
- var_result, links_to_resumption))
+ var_result, links_to_resumption),
+ varsforcall)
- def _generate_save_block(self, varstosave, var_unwind_exception, frame_type, fieldnames):
+ def _generate_save_block(self, varsforcall, var_unwind_exception,
+ frame_type, fieldnames, saver):
rtyper = self.translator.rtyper
edata = rtyper.getexceptiondata()
etype = edata.lltype_of_exception_type
evalue = edata.lltype_of_exception_value
- inputargs = [unsimplify.copyvar(None, v) for v in varstosave]
+ inputargs = [unsimplify.copyvar(None, v) for v in varsforcall]
var_unwind_exception = unsimplify.copyvar(None, var_unwind_exception)
-
- save_state_block = model.Block(inputargs + [var_unwind_exception])
- saveops = save_state_block.operations
- frame_state_var = varoftype(lltype.Ptr(frame_type))
- if self.stackless_gc:
- saveops.append(model.SpaceOperation(
- 'flavored_malloc',
- [self.c_gc_nocollect, model.Constant(frame_type, lltype.Void)],
- frame_state_var))
- else:
- saveops.append(model.SpaceOperation(
- 'malloc',
- [model.Constant(frame_type, lltype.Void)],
- frame_state_var))
+ save_state_block = model.Block(inputargs + [var_unwind_exception])
+ saveops = LowLevelOpList()
+
+ realvarsforcall = []
+ 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))
- saveops.extend(self.generate_saveops(frame_state_var, inputargs,
- fieldnames))
+ var_exc = gen_cast(saveops, self.unwind_exception_type, var_unwind_exception)
+ var_header = gen_cast(saveops, lltype.Ptr(STATE_HEADER), frame_state_var)
- var_exc = varoftype(self.unwind_exception_type)
- saveops.append(model.SpaceOperation(
- "cast_pointer",
- [var_unwind_exception],
- var_exc))
-
- var_header = varoftype(lltype.Ptr(STATE_HEADER))
-
- saveops.append(model.SpaceOperation(
- "cast_pointer", [frame_state_var], var_header))
-
- saveops.append(model.SpaceOperation(
- "direct_call",
- [self.add_frame_state_ptr, var_exc, var_header],
- varoftype(lltype.Void)))
+ saveops.genop('direct_call', [self.add_frame_state_ptr, var_exc, var_header],
+ resulttype=lltype.Void)
f_restart = len(self.masterarray1) + len(self.resume_blocks)
- saveops.append(model.SpaceOperation(
- "setfield",
- [var_header, self.c_f_restart_name,
- model.Constant(f_restart, lltype.Signed)],
- varoftype(lltype.Void)))
+
+ 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)
c_unwindexception = model.Constant(
More information about the Pypy-commit
mailing list