[pypy-svn] r69799 - in pypy/trunk/pypy/jit/metainterp: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Tue Dec 1 14:26:57 CET 2009


Author: cfbolz
Date: Tue Dec  1 14:26:56 2009
New Revision: 69799

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:
A different approach to sharing the descrlists of virtual info object: use a
global dictionary.


Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py	Tue Dec  1 14:26:56 2009
@@ -10,6 +10,7 @@
 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 descrlist_dict
 from pypy.jit.metainterp.optimizeutil import InvalidLoop
 from pypy.jit.metainterp import resume, compile
 from pypy.jit.metainterp.typesystem import llhelper, oohelper
@@ -172,6 +173,13 @@
     def _make_virtual(self, modifier):
         raise NotImplementedError("abstract base")
 
+def get_fielddescrlist_cache(cpu):
+    if not hasattr(cpu, '_optimizeopt_fielddescrlist_cache'):
+        result = descrlist_dict()
+        cpu._optimizeopt_fielddescrlist_cache = result
+        return result
+    return cpu._optimizeopt_fielddescrlist_cache
+get_fielddescrlist_cache._annspecialcase_ = "specialize:memo"
 
 class AbstractVirtualStructValue(AbstractVirtualValue):
     _attrs_ = ('_fields', '_cached_sorted_fields')
@@ -206,7 +214,6 @@
         self._fields = 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)):
@@ -214,6 +221,14 @@
         else:
             lst = self._fields.keys()
             sort_descrs(lst)
+            cache = get_fielddescrlist_cache(self.optimizer.cpu)
+            result = cache.get(lst, None)
+            if result is None:
+                cache[lst] = lst
+            else:
+                lst = result
+            # store on self, to not have to repeatedly get it from the global
+            # cache, which involves sorting
             self._cached_sorted_fields = lst
         return lst
 

Modified: pypy/trunk/pypy/jit/metainterp/optimizeutil.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeutil.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeutil.py	Tue Dec  1 14:26:56 2009
@@ -54,3 +54,26 @@
     quicksort(lst, 0, len(lst)-1)
 
 
+def descrlist_hash(l):
+    res = 0x345678
+    mult = 1000003
+    z = len(l)
+    for descr in l:
+        y = descr.sort_key()
+        res = (res ^ y) * mult
+        z -= 1
+        mult += 82520 + z + z
+    res += 97531
+    return res
+
+def descrlist_eq(l1, l2):
+    if len(l1) != len(l2):
+        return False
+    for i in range(len(l1)):
+        if l1[i].sort_key() != l2[i].sort_key():
+            return False
+    return True
+
+def descrlist_dict():
+    return r_dict(descrlist_eq, descrlist_hash)
+

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	Tue Dec  1 14:26:56 2009
@@ -63,16 +63,27 @@
     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):
@@ -88,7 +99,26 @@
     assert vinfo3 is not vinfo2
     vinfo4 = v1.make_virtual_info(None, [1, 2, 6])
     assert vinfo3 is vinfo4
-    
+
+def test_descrlist_dict():
+    from pypy.jit.metainterp import optimizeutil
+    h1 = optimizeutil.descrlist_hash([])
+    h2 = optimizeutil.descrlist_hash([LLtypeMixin.valuedescr])
+    h3 = optimizeutil.descrlist_hash(
+            [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
+    assert h1 != h2
+    assert h2 != h3
+    assert optimizeutil.descrlist_eq([], [])
+    assert not optimizeutil.descrlist_eq([], [LLtypeMixin.valuedescr])
+    assert optimizeutil.descrlist_eq([LLtypeMixin.valuedescr],
+                                     [LLtypeMixin.valuedescr])
+    assert not optimizeutil.descrlist_eq([LLtypeMixin.valuedescr],
+                                         [LLtypeMixin.nextdescr])
+    assert optimizeutil.descrlist_eq([LLtypeMixin.valuedescr, LLtypeMixin.nextdescr],
+                                     [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
+    assert not optimizeutil.descrlist_eq([LLtypeMixin.nextdescr, LLtypeMixin.valuedescr],
+                                         [LLtypeMixin.valuedescr, LLtypeMixin.nextdescr])
+
 
 # ____________________________________________________________
 

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	Tue Dec  1 14:26:56 2009
@@ -361,13 +361,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():
@@ -800,18 +805,19 @@
     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.setfield(LLtypeMixin.nextdescr, OptValue(b2s))
+    v4.setfield(LLtypeMixin.valuedescr, OptValue(b3s))
+    v4.setfield(LLtypeMixin.otherdescr, OptValue(b5s))
     v4._cached_sorted_fields = [LLtypeMixin.nextdescr, LLtypeMixin.valuedescr,
                                 LLtypeMixin.otherdescr]
+    v2 = VirtualValue(fakeoptimizer, ConstAddr(LLtypeMixin.node_vtable_adr,
+                                                LLtypeMixin.cpu), b2s)
+    v2.setfield(LLtypeMixin.nextdescr, v4)
+    v2.setfield(LLtypeMixin.valuedescr, OptValue(c1s))
+    v2._cached_sorted_fields = [LLtypeMixin.nextdescr, LLtypeMixin.valuedescr]
+
     modifier.register_virtual_fields(b2s, [b4s, c1s])
     modifier.register_virtual_fields(b4s, [b2s, b3s, b5s])
     values = {b2s: v2, b4s: v4}
@@ -873,6 +879,8 @@
     modifier.vfieldboxes = {}
 
     class FakeOptimizer(object):
+        class cpu:
+            pass
         def new_const_item(self, descr):
             return None
     v2 = VArrayValue(FakeOptimizer(), LLtypeMixin.arraydescr, 2, b2s)
@@ -921,9 +929,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