[pypy-svn] r37635 - in pypy/dist/pypy/jit/timeshifter: . test
ac at codespeak.net
ac at codespeak.net
Tue Jan 30 20:58:05 CET 2007
Author: ac
Date: Tue Jan 30 20:58:04 2007
New Revision: 37635
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
pypy/dist/pypy/jit/timeshifter/vlist.py
Log:
(pedronis, arre) Support virtual list in virtualizables.
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Jan 30 20:58:04 2007
@@ -1,5 +1,5 @@
import operator
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.annlowlevel import cachedtype, cast_base_ptr_to_instance
from pypy.rpython.annlowlevel import base_ptr_lltype, cast_instance_to_base_ptr
from pypy.jit.timeshifter import rvalue
@@ -7,7 +7,8 @@
from pypy.jit.timeshifter import rvirtualizable
from pypy.annotation import model as annmodel
-from pypy.rpython.lltypesystem import lloperation, llmemory
+
+from pypy.rpython.lltypesystem import lloperation
debug_print = lloperation.llop.debug_print
debug_pdb = lloperation.llop.debug_pdb
@@ -27,6 +28,11 @@
class VirtualContainer(AbstractContainer):
_attrs_ = []
+ allowed_in_virtualizable = False
+
+ def setforced(self, _):
+ raise NotImplementedError
+
class FrozenContainer(AbstractContainer):
_attrs_ = []
@@ -53,7 +59,7 @@
fielddescs fielddesc_by_name
immutable noidentity
materialize
- fill_into
+ devirtualize
""".split()
@@ -82,7 +88,7 @@
self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
self._compute_fielddescs(hrtyper)
- self._define_fill_into()
+ self._define_devirtualize()
if self.immutable and self.noidentity:
self._define_materialize()
@@ -118,17 +124,26 @@
self.fielddesc_by_name = fielddesc_by_name
self.innermostdesc = innermostdesc
- def _define_fill_into(self):
+ def _define_devirtualize(self):
+ TYPE = self.TYPE
+ PTRTYPE = self.PTRTYPE
descs = unrolling_iterable(self.fielddescs)
+
+ def make(vrti):
+ s = lltype.malloc(TYPE)
+ s = lltype.cast_opaque_ptr(llmemory.GCREF, s)
+ return s
+
def fill_into(vablerti, s, base, vrti):
+ s = lltype.cast_opaque_ptr(PTRTYPE, s)
i = 0
for desc in descs:
v = vrti._read_field(vablerti, desc, base, i)
- i += 1
tgt = lltype.cast_pointer(desc.PTRTYPE, s)
setattr(tgt, desc.fieldname, v)
-
- self.fill_into = fill_into
+ i = i + 1
+
+ self.devirtualize = make, fill_into
def _define_materialize(self):
TYPE = self.TYPE
@@ -139,7 +154,8 @@
i = 0
for desc in descs:
v = rvalue.ll_getvalue(boxes[i], desc.RESTYPE)
- setattr(s, desc.fieldname, v)
+ tgt = lltype.cast_pointer(desc.PTRTYPE, s)
+ setattr(tgt, desc.fieldname, v)
i = i + 1
return rgenop.genconst(s)
@@ -230,7 +246,7 @@
self._define_access_is_null(hrtyper)
- def _define_fill_into(self):
+ def _define_virtual_desc(self):
pass
def _define_getset_field_ptr(self, hrtyper, fielddesc, j):
@@ -324,6 +340,8 @@
# XXX basic field descs for now
class FieldDesc(object):
__metaclass__ = cachedtype
+ _attrs_ = 'structdesc'
+
allow_void = False
virtualizable = False
gv_default = None
@@ -343,7 +361,7 @@
self.virtualizable = T._hints.get('virtualizable', False)
self.gcref = T._gckind == 'gc'
if isinstance(T, lltype.ContainerType):
- if not T._is_varsize():
+ if not T._is_varsize() or hasattr(T, 'll_newlist'):
self.canbevirtual = True
else:
T = None
@@ -355,19 +373,12 @@
if RESTYPE is lltype.Void and self.allow_void:
pass # no redboxcls at all
elif self.virtualizable:
- pass
+ self.structdesc = StructTypeDesc(hrtyper, T)
else:
self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
-
- if T is not None and isinstance(T, lltype.Struct): # xxx for now
- self.structdesc = StructTypeDesc(hrtyper, T)
self.immutable = PTRTYPE.TO._hints.get('immutable', False)
- def _get_fill_into(self):
- return self.structdesc.fill_into
- fill_into = property(_get_fill_into)
-
def _freeze_(self):
return True
@@ -485,6 +496,8 @@
class VirtualStruct(VirtualContainer):
_attrs_ = "typedesc content_boxes ownbox".split()
+ allowed_in_virtualizable = True
+
def __init__(self, typedesc):
self.typedesc = typedesc
#self.content_boxes = ... set in factory()
@@ -497,6 +510,11 @@
for box in self.content_boxes:
box.enter_block(incoming, memo)
+ def setforced(self, gv_forced):
+ self.content_boxes = None
+ self.ownbox.genvar = gv_forced
+ self.ownbox.content = None
+
def force_runtime_container(self, jitstate):
typedesc = self.typedesc
builder = jitstate.curbuilder
@@ -515,8 +533,7 @@
#debug_pdb(lltype.Void)
genvar = builder.genop_malloc_fixedsize(typedesc.alloctoken)
# force the box pointing to this VirtualStruct
- self.ownbox.genvar = genvar
- self.ownbox.content = None
+ self.setforced(genvar)
fielddescs = typedesc.fielddescs
for i in range(len(fielddescs)):
fielddesc = fielddescs[i]
@@ -568,7 +585,8 @@
bitmask = 1 << memo.bitcount
memo.bitcount += 1
rgenop = jitstate.curbuilder.rgenop
- vrti = rvirtualizable.VirtualStructRTI(rgenop, bitmask)
+ vrti = rvirtualizable.VirtualRTI(rgenop, bitmask)
+ vrti.devirtualize = typedesc.devirtualize
memo.containers[self] = vrti
builder = jitstate.curbuilder
@@ -590,7 +608,7 @@
varindexes.append(j)
assert isinstance(box, rvalue.PtrRedBox)
content = box.content
- assert isinstance(content, VirtualStruct) # XXX for now
+ assert content.allowed_in_virtualizable
vrtis.append(content.make_rti(jitstate, memo))
j -= 1
@@ -618,7 +636,7 @@
if not box.genvar:
assert isinstance(box, rvalue.PtrRedBox)
content = box.content
- assert isinstance(content, VirtualStruct) # xxx for now
+ assert content.allowed_in_virtualizable
content.reshape(jitstate, shapemask, memo)
class VirtualizableStruct(VirtualStruct):
@@ -695,7 +713,7 @@
varindexes.append(j)
assert isinstance(box, rvalue.PtrRedBox)
content = box.content
- assert isinstance(content, VirtualStruct) # XXX for now
+ assert content.allowed_in_virtualizable
vrtis.append(content.make_rti(jitstate, memo))
j -= 1
@@ -752,7 +770,7 @@
nvirtual += 1
assert isinstance(box, rvalue.PtrRedBox)
content = box.content
- assert isinstance(content, VirtualStruct) # xxx for now
+ assert content.allowed_in_virtualizable
content.reshape(jitstate, shapemask, memo)
bitmask = 1 << memo.bitcount
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Tue Jan 30 20:58:04 2007
@@ -961,10 +961,8 @@
content.reshape(self, shapemask, memo)
if shapemask:
- for vstruct, gv_ptr in memo.forced:
- vstruct.content_boxes = None
- vstruct.ownbox.genvar = gv_ptr
- vstruct.ownbox.content = None
+ for vcontainer, gv_ptr in memo.forced:
+ vcontainer.setforced(gv_ptr)
def freeze(self, memo):
result = FrozenJITState()
Modified: pypy/dist/pypy/jit/timeshifter/rvirtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvirtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvirtualizable.py Tue Jan 30 20:58:04 2007
@@ -1,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory, lloperation
+from pypy.rpython.annlowlevel import cachedtype
from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
from pypy.rlib.unroll import unrolling_iterable
@@ -70,7 +71,7 @@
(get_field_touched, set_field_touched))
-class VirtualRTI(object):
+class RTI(object):
_attrs_ = 'rgenop varindexes vrtis bitmask'.split()
def __init__(self, rgenop, bitmask):
@@ -87,15 +88,14 @@
index = -frameindex-1
assert index >= 0
vrti = self.vrtis[index]
- assert isinstance(T, lltype.Ptr)
assert fielddesc.canbevirtual
assert fielddesc.gcref
- assert isinstance(vrti, VirtualStructRTI)
+ assert isinstance(vrti, VirtualRTI)
return vrti._get_forced(vablerti, fielddesc, base)
_read_field._annspecialcase_ = "specialize:arg(2)"
-class VirtualizableRTI(VirtualRTI):
+class VirtualizableRTI(RTI):
_attrs_ = "frameinfo touch_update shape_place".split()
def is_field_virtual(self, base, index):
@@ -105,7 +105,7 @@
index = -frameindex-1
assert index >= 0
vrti = self.vrtis[index]
- assert isinstance(vrti, VirtualStructRTI)
+ assert isinstance(vrti, VirtualRTI)
return vrti._is_virtual(self.get_shape(base))
def read_frame_var(self, T, base, frameindex):
@@ -139,23 +139,26 @@
self.set_shape(base, bitmask | self.get_shape(base))
-class VirtualStructRTI(VirtualRTI):
- _attrs_ = "forced_place"
+class VirtualRTI(RTI):
+ _attrs_ = "forced_place devirtualize".split()
- def _get_forced(self, vablerti, fielddesc, base):
- T = fielddesc.RESTYPE
+ def _get_forced(self, vablerti, elemdesc, base):
+ T = elemdesc.RESTYPE
assert isinstance(T, lltype.Ptr)
shapemask = vablerti.get_shape(base)
bitmask = self.bitmask
if bitmask & shapemask:
return self.rgenop.read_frame_place(T, base, self.forced_place)
- S = T.TO
- s = lltype.malloc(S)
- self.rgenop.write_frame_place(T, base, self.forced_place, s)
+ make, fill_into = self.devirtualize
+ cref = make(self)
+ c = lltype.cast_opaque_ptr(T, cref)
+ self.rgenop.write_frame_place(T, base, self.forced_place, c)
vablerti.set_shape(base, shapemask| bitmask)
- fielddesc.fill_into(vablerti, s, base, self)
- return s
+ fill_into(vablerti, cref, base, self)
+ return c
_get_forced._annspecialcase_ = "specialize:arg(2)"
def _is_virtual(self, shapemask):
return bool(self.bitmask & shapemask)
+
+
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 30 20:58:04 2007
@@ -1072,3 +1072,70 @@
assert res == main()
+
+ def test_virtual_list(self):
+ class V(object):
+ _virtualizable_ = True
+ def __init__(self, l):
+ self.l = l
+
+ def g(v):
+ l = v.l
+ x = l[0]
+ y = l[1]
+ l[0] = y
+ l[1] = x
+ v.l = [x*100, y*100]
+
+ def f(v):
+ hint(None, global_merge_point=True)
+ l = [1, 10]
+ v.l = l
+ g(v)
+ l2 = v.l
+ return l[0]*2 + l[1] + l2[0] * 2 + l2[1]
+
+ def main():
+ v = V(None)
+ return f(v)
+
+ res = self.timeshift_from_portal(main, f, [], policy=StopAtXPolicy(g))
+ assert res == 20 + 1 + 200 + 1000
+
+ def test_virtual_list_and_struct(self):
+ class S(object):
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ class V(object):
+ _virtualizable_ = True
+ def __init__(self, l, s):
+ self.l = l
+ self.s = s
+ def g(v):
+ l = v.l
+ x = l[0]
+ y = l[1]
+ l[0] = y
+ l[1] = x
+ v.l = [x*100, y*100]
+
+ def f(v):
+ hint(None, global_merge_point=True)
+ l = [1, 10]
+ s = S(3, 7)
+ v.l = l
+ v.s = s
+ g(v)
+ l2 = v.l
+ s2 = v.s
+ return l[0]*2 + l[1] + l2[0] * 2 + l2[1] + s.x * 7 + s.y + s2.x * 7 + s2.y
+
+ def main():
+ v = V(None, None)
+ return f(v)
+
+ res = self.timeshift_from_portal(main, f, [], policy=StopAtXPolicy(g))
+ assert res == main()
+
Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py Tue Jan 30 20:58:04 2007
@@ -1,9 +1,26 @@
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.timeshifter.rcontainer import VirtualContainer, FrozenContainer
from pypy.jit.timeshifter.rcontainer import cachedtype
-from pypy.jit.timeshifter import rvalue
+from pypy.jit.timeshifter import rvalue, rvirtualizable
+class ItemDesc(object):
+ __metaclass__ = cachedtype
+ gcref = False
+ canbevirtual = False
+
+ def _freeze_(self):
+ return True
+
+ def __init__(self, ITEM):
+ self.RESTYPE = ITEM
+ if isinstance(ITEM, lltype.Ptr):
+ T = ITEM.TO
+ self.gcref = T._gckind == 'gc'
+ if isinstance(T, lltype.ContainerType):
+ if not T._is_varsize():
+ self.canbevirtual = True
+
class ListTypeDesc(object):
__metaclass__ = cachedtype
@@ -13,6 +30,8 @@
self.LIST = LIST
self.LISTPTR = lltype.Ptr(LIST)
self.ptrkind = RGenOp.kindToken(self.LISTPTR)
+ self.null = self.LISTPTR._defl()
+ self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
argtypes = [lltype.Signed]
ll_newlist_ptr = rtyper.annotate_helper_fn(LIST.ll_newlist,
@@ -27,6 +46,27 @@
self.tok_ll_setitem_fast = RGenOp.sigToken(
lltype.typeOf(ll_setitem_fast).TO)
+ self._define_devirtualize()
+
+ def _define_devirtualize(self):
+ LIST = self.LIST
+ LISTPTR = self.LISTPTR
+ itemdesc = ItemDesc(LIST.ITEM)
+
+ def make(vrti):
+ n = len(vrti.varindexes)
+ l = LIST.ll_newlist(n)
+ return lltype.cast_opaque_ptr(llmemory.GCREF, l)
+
+ def fill_into(vablerti, l, base, vrti):
+ l = lltype.cast_opaque_ptr(LISTPTR, l)
+ n = len(vrti.varindexes)
+ for i in range(n):
+ v = vrti._read_field(vablerti, itemdesc, base, i)
+ l.ll_setitem_fast(i, v)
+
+ self.devirtualize = make, fill_into
+
def _freeze_(self):
return True
@@ -95,6 +135,8 @@
class VirtualList(VirtualContainer):
+ allowed_in_virtualizable = True
+
def __init__(self, typedesc, length=0, itembox=None):
self.typedesc = typedesc
self.item_boxes = [itembox] * length
@@ -107,6 +149,11 @@
for box in self.item_boxes:
box.enter_block(incoming, memo)
+ def setforced(self, gv_forced):
+ self.item_boxes = None
+ self.ownbox.genvar = gv_forced
+ self.ownbox.content = None
+
def force_runtime_container(self, jitstate):
typedesc = self.typedesc
builder = jitstate.curbuilder
@@ -117,8 +164,8 @@
gv_list = builder.genop_call(typedesc.tok_ll_newlist,
typedesc.gv_ll_newlist,
args_gv)
- self.ownbox.genvar = gv_list
- self.ownbox.content = None
+ self.setforced(gv_list)
+
for i in range(len(boxes)):
gv_item = boxes[i].getgenvar(jitstate)
args_gv = [gv_list, builder.rgenop.genconst(i), gv_item]
@@ -156,6 +203,70 @@
self.ownbox = self.ownbox.replace(memo)
+ def make_rti(self, jitstate, memo):
+ try:
+ return memo.containers[self]
+ except KeyError:
+ pass
+ typedesc = self.typedesc
+ bitmask = 1 << memo.bitcount
+ memo.bitcount += 1
+ rgenop = jitstate.curbuilder.rgenop
+ vrti = rvirtualizable.VirtualRTI(rgenop, bitmask)
+ vrti.devirtualize = typedesc.devirtualize
+ memo.containers[self] = vrti
+
+ builder = jitstate.curbuilder
+ place = builder.alloc_frame_place(typedesc.ptrkind,
+ typedesc.gv_null)
+ gv_forced = builder.genop_absorb_place(typedesc.ptrkind, place)
+ vrti.forced_place = place
+
+ vars_gv = memo.framevars_gv
+ varindexes = vrti.varindexes
+ vrtis = vrti.vrtis
+ j = -1
+ for box in self.item_boxes:
+ if box.genvar:
+ varindexes.append(memo.frameindex)
+ memo.frameindex += 1
+ vars_gv.append(box.genvar)
+ else:
+ varindexes.append(j)
+ assert isinstance(box, rvalue.PtrRedBox)
+ content = box.content
+ assert content.allowed_in_virtualizable
+ vrtis.append(content.make_rti(jitstate, memo))
+ j -= 1
+
+ self.item_boxes.append(rvalue.PtrRedBox(typedesc.ptrkind,
+ gv_forced))
+
+ return vrti
+
+ def reshape(self, jitstate, shapemask, memo):
+ if self in memo.containers:
+ return
+ typedesc = self.typedesc
+ builder = jitstate.curbuilder
+ memo.containers[self] = None
+ bitmask = 1<<memo.bitcount
+ memo.bitcount += 1
+
+ boxes = self.item_boxes
+ outside_box = boxes.pop()
+ if bitmask&shapemask:
+ gv_forced = outside_box.genvar
+ memo.forced.append((self, gv_forced))
+
+ for box in boxes:
+ if not box.genvar:
+ assert isinstance(box, rvalue.PtrRedBox)
+ content = box.content
+ assert content.allowed_in_virtualizable
+ content.reshape(jitstate, shapemask, memo)
+
+
def oop_newlist(jitstate, oopspecdesc, lengthbox, itembox=None):
if lengthbox.is_constant():
length = rvalue.ll_getvalue(lengthbox, lltype.Signed)
More information about the Pypy-commit
mailing list