[pypy-svn] r65964 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Jun 25 16:55:36 CEST 2009
Author: arigo
Date: Thu Jun 25 16:55:31 2009
New Revision: 65964
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
Log:
Handle correctly the situation where we access another
virtualizable (i.e. another frame) than the 'standard' one.
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/codewriter.py Thu Jun 25 16:55:31 2009
@@ -813,14 +813,16 @@
if self.is_virtualizable_getset(op):
vinfo = self.codewriter.metainterp_sd.virtualizable_info
index = vinfo.static_field_to_extra_box[op.args[1].value]
- self.emit('getfield_vable', index)
+ self.emit('getfield_vable',
+ self.var_position(v_inst),
+ index)
self.register_var(op.result)
return
except VirtualizableArrayField:
# xxx hack hack hack
vinfo = self.codewriter.metainterp_sd.virtualizable_info
- index = vinfo.array_field_counter[op.args[1].value]
- self.vable_array_vars[op.result] = index
+ arrayindex = vinfo.array_field_counter[op.args[1].value]
+ self.vable_array_vars[op.result] = (op.args[0], arrayindex)
return
# check for deepfrozen structures that force constant-folding
if deref(v_inst.concretetype)._hints.get('immutable'):
@@ -851,7 +853,10 @@
if self.is_virtualizable_getset(op):
vinfo = self.codewriter.metainterp_sd.virtualizable_info
index = vinfo.static_field_to_extra_box[op.args[1].value]
- self.emit('setfield_vable', index, self.var_position(v_value))
+ self.emit('setfield_vable',
+ self.var_position(v_inst),
+ index,
+ self.var_position(v_value))
return
argname = getattr(deref(v_inst.concretetype), '_gckind', 'gc')
self.emit('setfield_%s' % (argname,))
@@ -868,8 +873,9 @@
deref(op.args[0].concretetype)._hints.get('typeptr'))
def is_virtualizable_getset(self, op):
- # XXX check more carefully; for now assumes that every access of
- # an object of exactly the type VTYPEPTR is a virtualizable access
+ # every access of an object of exactly the type VTYPEPTR is
+ # likely to be a virtualizable access, but we still have to
+ # check it in pyjitpl.py.
vinfo = self.codewriter.metainterp_sd.virtualizable_info
if vinfo is None:
return False
@@ -896,8 +902,10 @@
if self._array_of_voids(ARRAY):
return
if op.args[0] in self.vable_array_vars: # for virtualizables
+ (v_base, arrayindex) = self.vable_array_vars[op.args[0]]
self.emit('getarrayitem_vable',
- self.vable_array_vars[op.args[0]],
+ self.var_position(v_base),
+ arrayindex,
self.var_position(op.args[1]))
self.register_var(op.result)
return
@@ -915,8 +923,10 @@
if self._array_of_voids(ARRAY):
return
if op.args[0] in self.vable_array_vars: # for virtualizables
+ (v_base, arrayindex) = self.vable_array_vars[op.args[0]]
self.emit('setarrayitem_vable',
- self.vable_array_vars[op.args[0]],
+ self.var_position(v_base),
+ arrayindex,
self.var_position(op.args[1]),
self.var_position(op.args[2]))
return
@@ -931,8 +941,10 @@
ARRAY = op.args[0].concretetype.TO
assert ARRAY._gckind == 'gc'
if op.args[0] in self.vable_array_vars: # for virtualizables
+ (v_base, arrayindex) = self.vable_array_vars[op.args[0]]
self.emit('arraylen_vable',
- self.vable_array_vars[op.args[0]])
+ self.var_position(v_base),
+ arrayindex)
self.register_var(op.result)
return
# normal case follows
@@ -1191,8 +1203,10 @@
#
if oopspec_name == 'list.setitem':
if args[0] in self.vable_array_vars: # virtualizable array
+ (v_base, arrayindex) = self.vable_array_vars[args[0]]
self.emit('setarrayitem_vable',
- self.vable_array_vars[args[0]],
+ self.var_position(v_base),
+ arrayindex,
self.var_position(args[1]),
self.var_position(args[2]))
return True
@@ -1210,8 +1224,10 @@
if (oopspec_name == 'list.len' or
oopspec_name == 'list.len_foldable'):
if args[0] in self.vable_array_vars: # virtualizable array
+ (v_base, arrayindex) = self.vable_array_vars[args[0]]
self.emit('arraylen_vable',
- self.vable_array_vars[args[0]])
+ self.var_position(v_base),
+ arrayindex)
self.register_var(op.result)
return True
self.emit('arraylen_gc')
@@ -1224,8 +1240,10 @@
def handle_list_getitem(self, op, arraydescr, args, opname):
if args[0] in self.vable_array_vars: # virtualizable array
+ (v_base, arrayindex) = self.vable_array_vars[args[0]]
self.emit('getarrayitem_vable',
- self.vable_array_vars[args[0]],
+ self.var_position(v_base),
+ arrayindex,
self.var_position(args[1]))
self.register_var(op.result)
return True
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py Thu Jun 25 16:55:31 2009
@@ -453,13 +453,44 @@
def opimpl_setfield_raw(self, box, fielddesc, valuebox):
self.execute(rop.SETFIELD_RAW, [box, valuebox], descr=fielddesc)
- @arguments("int")
- def opimpl_getfield_vable(self, index):
+ def _nonstandard_virtualizable(self, pc, box):
+ # returns True if 'box' is actually not the "standard" virtualizable
+ # that is stored in metainterp.virtualizable_boxes[-1]
+ standard_box = self.metainterp.virtualizable_boxes[-1]
+ if standard_box is box:
+ return False
+ eqbox = self.metainterp.execute_and_record(rop.OOIS,
+ [box, standard_box])
+ eqbox = self.implement_guard_value(pc, eqbox)
+ return not eqbox.getint()
+
+ def _get_virtualizable_field_descr(self, index):
+ vinfo = self.metainterp.staticdata.virtualizable_info
+ return vinfo.static_field_descrs[index]
+
+ def _get_virtualizable_array_field_descr(self, index):
+ vinfo = self.metainterp.staticdata.virtualizable_info
+ return vinfo.array_field_descrs[index]
+
+ def _get_virtualizable_array_descr(self, index):
+ vinfo = self.metainterp.staticdata.virtualizable_info
+ return vinfo.array_descrs[index]
+
+ @arguments("orgpc", "box", "int")
+ def opimpl_getfield_vable(self, pc, basebox, index):
+ if self._nonstandard_virtualizable(pc, basebox):
+ self.execute(rop.GETFIELD_GC, [basebox],
+ descr=self._get_virtualizable_field_descr(index))
+ return
self.metainterp.check_synchronized_virtualizable()
resbox = self.metainterp.virtualizable_boxes[index]
self.make_result_box(resbox)
- @arguments("int", "box")
- def opimpl_setfield_vable(self, index, valuebox):
+ @arguments("orgpc", "box", "int", "box")
+ def opimpl_setfield_vable(self, pc, basebox, index, valuebox):
+ if self._nonstandard_virtualizable(pc, basebox):
+ self.execute(rop.SETFIELD_GC, [basebox, valuebox],
+ descr=self._get_virtualizable_field_descr(index))
+ return
self.metainterp.virtualizable_boxes[index] = valuebox
self.metainterp.synchronize_virtualizable()
# XXX only the index'th field needs to be synchronized, really
@@ -475,20 +506,45 @@
assert 0 <= index < vinfo.get_array_length(virtualizable, arrayindex)
return vinfo.get_index_in_array(virtualizable, arrayindex, index)
- @arguments("orgpc", "int", "box")
- def opimpl_getarrayitem_vable(self, pc, arrayindex, indexbox):
+ @arguments("orgpc", "box", "int", "box")
+ def opimpl_getarrayitem_vable(self, pc, basebox, arrayindex, indexbox):
+ if self._nonstandard_virtualizable(pc, basebox):
+ arraybox = self.metainterp.execute_and_record(
+ rop.GETFIELD_GC, [basebox],
+ descr=self._get_virtualizable_array_field_descr(arrayindex))
+ self.execute(
+ rop.GETARRAYITEM_GC, [arraybox, indexbox],
+ descr=self._get_virtualizable_array_descr(arrayindex))
+ return
self.metainterp.check_synchronized_virtualizable()
index = self._get_arrayitem_vable_index(pc, arrayindex, indexbox)
resbox = self.metainterp.virtualizable_boxes[index]
self.make_result_box(resbox)
- @arguments("orgpc", "int", "box", "box")
- def opimpl_setarrayitem_vable(self, pc, arrayindex, indexbox, valuebox):
+ @arguments("orgpc", "box", "int", "box", "box")
+ def opimpl_setarrayitem_vable(self, pc, basebox, arrayindex, indexbox,
+ valuebox):
+ if self._nonstandard_virtualizable(pc, basebox):
+ arraybox = self.metainterp.execute_and_record(
+ rop.GETFIELD_GC, [basebox],
+ descr=self._get_virtualizable_array_field_descr(arrayindex))
+ self.execute(
+ rop.SETARRAYITEM_GC, [arraybox, indexbox, valuebox],
+ descr=self._get_virtualizable_array_descr(arrayindex))
+ return
index = self._get_arrayitem_vable_index(pc, arrayindex, indexbox)
self.metainterp.virtualizable_boxes[index] = valuebox
self.metainterp.synchronize_virtualizable()
# XXX only the index'th field needs to be synchronized, really
- @arguments("int")
- def opimpl_arraylen_vable(self, arrayindex):
+ @arguments("orgpc", "box", "int")
+ def opimpl_arraylen_vable(self, pc, basebox, arrayindex):
+ if self._nonstandard_virtualizable(pc, basebox):
+ arraybox = self.metainterp.execute_and_record(
+ rop.GETFIELD_GC, [basebox],
+ descr=self._get_virtualizable_array_field_descr(arrayindex))
+ self.execute(
+ rop.ARRAYLEN_GC, [arraybox],
+ descr=self._get_virtualizable_array_descr(arrayindex))
+ return
vinfo = self.metainterp.staticdata.virtualizable_info
virtualizable_box = self.metainterp.virtualizable_boxes[-1]
virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_virtualizable.py Thu Jun 25 16:55:31 2009
@@ -151,6 +151,28 @@
assert res == 50 * 4
self.check_loops(getfield_gc=0, setfield_gc=0)
+ def test_double_frame(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'xy', 'other'],
+ virtualizables = ['xy'])
+ def f(n):
+ xy = self.setup()
+ xy.inst_x = 10
+ other = self.setup()
+ other.inst_x = 15
+ while n > 0:
+ myjitdriver.can_enter_jit(xy=xy, n=n, other=other)
+ myjitdriver.jit_merge_point(xy=xy, n=n, other=other)
+ promote_virtualizable(lltype.Void, other, 'inst_x')
+ value = other.inst_x # getfield_gc
+ other.inst_x = value + 1 # setfield_gc
+ promote_virtualizable(lltype.Void, xy, 'inst_x')
+ xy.inst_x = value + 100 # virtualized away
+ n -= 1
+ return xy.inst_x
+ res = self.meta_interp(f, [20])
+ assert res == 134
+ self.check_loops(getfield_gc=1, setfield_gc=1)
+
# ------------------------------
XY2 = lltype.GcStruct(
@@ -283,6 +305,42 @@
self.check_loops(getfield_gc=0, setfield_gc=0,
getarrayitem_gc=0, arraylen_gc=1, call=1)
+ def test_double_frame_array(self):
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'xy2', 'other'],
+ virtualizables = ['xy2'])
+ ARRAY = lltype.GcArray(lltype.Signed)
+ def f(n):
+ xy2 = self.setup2()
+ xy2.inst_x = 10
+ xy2.inst_l1 = lltype.malloc(ARRAY, 1)
+ xy2.inst_l1[0] = 1982731
+ xy2.inst_l2 = lltype.malloc(ARRAY, 1)
+ xy2.inst_l2[0] = 10000
+ other = self.setup2()
+ other.inst_x = 15
+ other.inst_l1 = lltype.malloc(ARRAY, 2)
+ other.inst_l1[0] = 189182
+ other.inst_l1[1] = 58421
+ other.inst_l2 = lltype.malloc(ARRAY, 2)
+ other.inst_l2[0] = 181
+ other.inst_l2[1] = 189
+ while n > 0:
+ myjitdriver.can_enter_jit(xy2=xy2, n=n, other=other)
+ myjitdriver.jit_merge_point(xy2=xy2, n=n, other=other)
+ promote_virtualizable(lltype.Void, other, 'inst_l2')
+ length = len(other.inst_l2) # getfield_gc/arraylen_gc
+ value = other.inst_l2[0] # getfield_gc/getarrayitem_gc
+ other.inst_l2[0] = value + length # getfield_gc/setarrayitem_gc
+ promote_virtualizable(lltype.Void, xy2, 'inst_l2')
+ xy2.inst_l2[0] = value + 100 # virtualized away
+ n -= 1
+ return xy2.inst_l2[0]
+ expected = f(20)
+ res = self.meta_interp(f, [20])
+ assert res == expected
+ self.check_loops(getfield_gc=3, setfield_gc=0,
+ arraylen_gc=1, getarrayitem_gc=1, setarrayitem_gc=1)
+
# ------------------------------
XY2SUB = lltype.GcStruct(
More information about the Pypy-commit
mailing list