[pypy-svn] r69772 - in pypy/trunk/pypy/jit/metainterp: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Mon Nov 30 17:13:05 CET 2009
Author: cfbolz
Date: Mon Nov 30 17:13:04 2009
New Revision: 69772
Modified:
pypy/trunk/pypy/jit/metainterp/optimizeopt.py
pypy/trunk/pypy/jit/metainterp/optimizeutil.py
pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
pypy/trunk/pypy/jit/metainterp/test/test_resume.py
Log:
Share the field descr lists between all virtual info objects that have the same
layout, not just those coming from the same specific virtual instance. This is
done by having a sharing-dict-like (or SELF map-like) approach.
Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py Mon Nov 30 17:13:04 2009
@@ -9,7 +9,7 @@
from pypy.jit.metainterp.specnode import VirtualInstanceSpecNode
from pypy.jit.metainterp.specnode import VirtualArraySpecNode
from pypy.jit.metainterp.specnode import VirtualStructSpecNode
-from pypy.jit.metainterp.optimizeutil import av_newdict2, _findall, sort_descrs
+from pypy.jit.metainterp.optimizeutil import av_newdict2, av_newdict_int, _findall
from pypy.jit.metainterp.optimizeutil import InvalidLoop
from pypy.jit.metainterp import resume, compile
from pypy.jit.metainterp.typesystem import llhelper, oohelper
@@ -173,20 +173,60 @@
raise NotImplementedError("abstract base")
+class FieldMap(object):
+ def __init__(self, prev, newfield):
+ if prev is not None:
+ assert newfield is not None
+ self.fieldindexes = prev.fieldindexes.copy()
+ self.fieldindexes[newfield] = len(self.fieldindexes)
+ self.fieldlist = prev.fieldlist + [newfield]
+ else:
+ assert newfield is None
+ self.fieldindexes = av_newdict_int()
+ self.fieldlist = []
+ self.nextmaps = av_newdict2()
+
+ def getindex(self, field):
+ return self.fieldindexes.get(field, -1)
+
+ def nextmap(self, field):
+ result = self.nextmaps.get(field, None)
+ if result is None:
+ result = FieldMap(self, field)
+ self.nextmaps[field] = result
+ return result
+
+def get_no_fields_map(cpu):
+ if hasattr(cpu, '_optimizeopt_fieldmap'):
+ return cpu._optimizeopt_fieldmap
+ res = FieldMap(None, None)
+ cpu._optimizeopt_fieldmap = res
+ return res
+get_no_fields_map._annspecialcase_ = 'specialize:memo'
+
class AbstractVirtualStructValue(AbstractVirtualValue):
- _attrs_ = ('_fields', '_cached_sorted_fields')
+ _attrs_ = ('_fieldmap', '_fieldvalues')
def __init__(self, optimizer, keybox, source_op=None):
AbstractVirtualValue.__init__(self, optimizer, keybox, source_op)
- self._fields = av_newdict2()
- self._cached_sorted_fields = None
+ self._fieldmap = get_no_fields_map(optimizer.cpu)
+ self._fieldvalues = []
def getfield(self, ofs, default):
- return self._fields.get(ofs, default)
+ i = self._fieldmap.getindex(ofs)
+ if i == -1:
+ return default
+ return self._fieldvalues[i]
def setfield(self, ofs, fieldvalue):
assert isinstance(fieldvalue, OptValue)
- self._fields[ofs] = fieldvalue
+ i = self._fieldmap.getindex(ofs)
+ if i != -1:
+ self._fieldvalues[i] = fieldvalue
+ else:
+ self._fieldmap = self._fieldmap.nextmap(ofs)
+ self._fieldvalues.append(fieldvalue)
+
def _really_force(self):
assert self.source_op is not None
@@ -194,39 +234,30 @@
newoperations.append(self.source_op)
self.box = box = self.source_op.result
#
- iteritems = self._fields.iteritems()
- if not we_are_translated(): #random order is fine, except for tests
- iteritems = list(iteritems)
- iteritems.sort(key = lambda (x,y): x.sort_key())
- for ofs, value in iteritems:
+ #if not we_are_translated(): #random order is fine, except for tests
+ # iteritems = self._fields.iteritems()
+ # iteritems = list(iteritems)
+ # iteritems.sort(key = lambda (x,y): x.sort_key())
+ for i in range(len(self._fieldmap.fieldlist)):
+ ofs = self._fieldmap.fieldlist[i]
+ value = self._fieldvalues[i]
subbox = value.force_box()
op = ResOperation(rop.SETFIELD_GC, [box, subbox], None,
descr=ofs)
newoperations.append(op)
- self._fields = None
+ self._fieldvalues = None
def _get_field_descr_list(self):
- # this shares only per instance and not per type, but better than nothing
- _cached_sorted_fields = self._cached_sorted_fields
- if (_cached_sorted_fields is not None and
- len(self._fields) == len(_cached_sorted_fields)):
- lst = self._cached_sorted_fields
- else:
- lst = self._fields.keys()
- sort_descrs(lst)
- self._cached_sorted_fields = lst
- return lst
+ return self._fieldmap.fieldlist
def get_args_for_fail(self, modifier):
+ # modifier.already_seen_virtual()
+ # checks for recursion: it is False unless
+ # we have already seen the very same keybox
if self.box is None and not modifier.already_seen_virtual(self.keybox):
- # modifier.already_seen_virtual()
- # checks for recursion: it is False unless
- # we have already seen the very same keybox
- lst = self._get_field_descr_list()
- fieldboxes = [self._fields[ofs].get_key_box() for ofs in lst]
+ fieldboxes = [value.get_key_box() for value in self._fieldvalues]
modifier.register_virtual_fields(self.keybox, fieldboxes)
- for ofs in lst:
- fieldvalue = self._fields[ofs]
+ for fieldvalue in self._fieldvalues:
fieldvalue.get_args_for_fail(modifier)
Modified: pypy/trunk/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeutil.py (original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeutil.py Mon Nov 30 17:13:04 2009
@@ -24,6 +24,9 @@
# the values...
return r_dict(av_eq, av_hash)
+def av_newdict_int():
+ return r_dict(av_eq, av_hash)
+
def _findall(Class, name_prefix):
result = []
for value, name in resoperation.opname.items():
Modified: pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_optimizeopt.py Mon Nov 30 17:13:04 2009
@@ -63,16 +63,28 @@
assert fdescr.rd_consts == []
def test_sharing_field_lists_of_virtual():
- virt1 = optimizeopt.AbstractVirtualStructValue(None, None)
+ class FakeOptimizer(object):
+ class cpu(object):
+ pass
+ opt = FakeOptimizer()
+ virt1 = optimizeopt.AbstractVirtualStructValue(opt, None)
lst1 = virt1._get_field_descr_list()
assert lst1 == []
lst2 = virt1._get_field_descr_list()
assert lst1 is lst2
virt1.setfield(LLtypeMixin.valuedescr, optimizeopt.OptValue(None))
- lst1 = virt1._get_field_descr_list()
- assert lst1 == [LLtypeMixin.valuedescr]
- lst2 = virt1._get_field_descr_list()
- assert lst1 is lst2
+ lst3 = virt1._get_field_descr_list()
+ assert lst3 == [LLtypeMixin.valuedescr]
+ lst4 = virt1._get_field_descr_list()
+ assert lst3 is lst4
+
+ virt2 = optimizeopt.AbstractVirtualStructValue(opt, None)
+ lst5 = virt2._get_field_descr_list()
+ assert lst5 is lst1
+ virt2.setfield(LLtypeMixin.valuedescr, optimizeopt.OptValue(None))
+ lst6 = virt1._get_field_descr_list()
+ assert lst6 is lst3
+
def test_reuse_vinfo():
class FakeVInfo(object):
@@ -90,6 +102,15 @@
assert vinfo3 is vinfo4
+def test_fieldmap():
+ map = optimizeopt.FieldMap(None, None)
+ assert map.getindex(LLtypeMixin.valuedescr) == -1
+ map2 = map.nextmap(LLtypeMixin.valuedescr)
+ assert map2.getindex(LLtypeMixin.valuedescr) == 0
+ assert map2.fieldlist == [LLtypeMixin.valuedescr]
+ map3 = map.nextmap(LLtypeMixin.valuedescr)
+ assert map2 is map3
+
# ____________________________________________________________
def equaloplists(oplist1, oplist2, strict_fail_args=True, remap={}):
Modified: pypy/trunk/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_resume.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_resume.py Mon Nov 30 17:13:04 2009
@@ -358,13 +358,18 @@
assert metainterp.framestack == fs2
+class FakeOptimizer_VirtualValue(object):
+ class cpu:
+ pass
+fakeoptimizer = FakeOptimizer_VirtualValue()
+
def virtual_value(keybox, value, next):
- vv = VirtualValue(None, ConstAddr(LLtypeMixin.node_vtable_adr,
- LLtypeMixin.cpu), keybox)
+ vv = VirtualValue(fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr,
+ LLtypeMixin.cpu), keybox)
if not isinstance(next, OptValue):
next = OptValue(next)
- vv.setfield(LLtypeMixin.nextdescr, next)
vv.setfield(LLtypeMixin.valuedescr, OptValue(value))
+ vv.setfield(LLtypeMixin.nextdescr, next)
return vv
def test_rebuild_from_resumedata_two_guards_w_virtuals():
@@ -797,18 +802,16 @@
modifier.liveboxes = {}
modifier.vfieldboxes = {}
- v2 = VirtualValue(None, ConstAddr(LLtypeMixin.node_vtable_adr,
- LLtypeMixin.cpu), b2s)
- v2._fields = {LLtypeMixin.nextdescr: b4s,
- LLtypeMixin.valuedescr: c1s}
- v2._cached_sorted_fields = [LLtypeMixin.nextdescr, LLtypeMixin.valuedescr]
- v4 = VirtualValue(None, ConstAddr(LLtypeMixin.node_vtable_adr2,
+ v4 = VirtualValue(fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr2,
LLtypeMixin.cpu), b4s)
- v4._fields = {LLtypeMixin.nextdescr: b2s,
- LLtypeMixin.valuedescr: b3s,
- LLtypeMixin.otherdescr: b5s}
- v4._cached_sorted_fields = [LLtypeMixin.nextdescr, LLtypeMixin.valuedescr,
- LLtypeMixin.otherdescr]
+ v4.setfield(LLtypeMixin.nextdescr, OptValue(b2s))
+ v4.setfield(LLtypeMixin.valuedescr, OptValue(b3s))
+ v4.setfield(LLtypeMixin.otherdescr, OptValue(b5s))
+ v2 = VirtualValue(fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr,
+ LLtypeMixin.cpu), b2s)
+ v2.setfield(LLtypeMixin.nextdescr, v4)
+ v2.setfield(LLtypeMixin.valuedescr, OptValue(c1s))
+
modifier.register_virtual_fields(b2s, [b4s, c1s])
modifier.register_virtual_fields(b4s, [b2s, b3s, b5s])
values = {b2s: v2, b4s: v4}
@@ -870,6 +873,8 @@
modifier.vfieldboxes = {}
class FakeOptimizer(object):
+ class cpu:
+ pass
def new_const_item(self, descr):
return None
v2 = VArrayValue(FakeOptimizer(), LLtypeMixin.arraydescr, 2, b2s)
@@ -918,9 +923,9 @@
modifier.liveboxes_from_env = {}
modifier.liveboxes = {}
modifier.vfieldboxes = {}
- v2 = VStructValue(None, LLtypeMixin.ssize, b2s)
- v2._fields = {LLtypeMixin.adescr: c1s, LLtypeMixin.bdescr: b4s}
- v2._cached_sorted_fields = [LLtypeMixin.adescr, LLtypeMixin.bdescr]
+ v2 = VStructValue(fakeoptimizer, LLtypeMixin.ssize, b2s)
+ v2.setfield(LLtypeMixin.adescr, OptValue(c1s))
+ v2.setfield(LLtypeMixin.bdescr, OptValue(b4s))
modifier.register_virtual_fields(b2s, [c1s, b4s])
liveboxes = []
modifier._number_virtuals(liveboxes, {b2s: v2}, 0)
More information about the Pypy-commit
mailing list