[pypy-commit] pypy length-hint: have resizelist_hint return nothing and not change the actual len

pjenvey noreply at buildbot.pypy.org
Sat Jul 14 23:41:23 CEST 2012


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: length-hint
Changeset: r56079:957f20610bc1
Date: 2012-07-14 14:14 -0700
http://bitbucket.org/pypy/pypy/changeset/957f20610bc1/

Log:	have resizelist_hint return nothing and not change the actual len

diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -264,24 +264,22 @@
 
 def resizelist_hint(l, sizehint):
     """Reallocate the underlying list to the specified sizehint"""
-    return l
+    return
 
 class Entry(ExtRegistryEntry):
     _about_ = resizelist_hint
 
     def compute_result_annotation(self, s_l, s_sizehint):
-        from pypy.annotation.model import SomeInteger, SomeList
-        assert isinstance(s_l, SomeList)
-        assert isinstance(s_sizehint, SomeInteger)
+        from pypy.annotation import model as annmodel
+        assert isinstance(s_l, annmodel.SomeList)
+        assert isinstance(s_sizehint, annmodel.SomeInteger)
         s_l.listdef.listitem.resize()
-        return s_l
 
     def specialize_call(self, hop):
-        r_list = hop.r_result
+        r_list = hop.args_r[0]
         v_list, v_sizehint = hop.inputargs(*hop.args_r)
         hop.exception_is_here()
-        hop.llops.gendirectcall(r_list.LIST._ll_resize, v_list, v_sizehint)
-        return v_list
+        hop.gendirectcall(r_list.LIST._ll_resize_hint, v_list, v_sizehint)
 
 # ____________________________________________________________
 #
diff --git a/pypy/rlib/test/test_objectmodel.py b/pypy/rlib/test/test_objectmodel.py
--- a/pypy/rlib/test/test_objectmodel.py
+++ b/pypy/rlib/test/test_objectmodel.py
@@ -2,6 +2,7 @@
 from pypy.rlib.objectmodel import *
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+from pypy.rpython.test.test_llinterp import interpret
 from pypy.conftest import option
 
 def strange_key_eq(key1, key2):
@@ -470,15 +471,22 @@
     def f(z):
         x = []
         resizelist_hint(x, 39)
-        if z < 0:
-            x.append(1)
         return len(x)
 
     graph = getgraph(f, [SomeInteger()])
-    for llop in graph.startblock.operations:
-        if llop.opname == 'direct_call':
+    for _, op in graph.iterblockops():
+        if op.opname == 'direct_call':
             break
-    call_name = llop.args[0].value._obj.graph.name
-    call_arg2 = llop.args[2].value
-    assert call_name.startswith('_ll_list_resize_really')
+    call_name = op.args[0].value._obj.graph.name
+    call_arg2 = op.args[2].value
+    assert call_name.startswith('_ll_list_resize_hint')
     assert call_arg2 == 39
+
+def test_resizelist_hint_len():
+    def f(i):
+        l = [44]
+        resizelist_hint(l, i)
+        return len(l)
+
+    r = interpret(f, [29])
+    assert r == 1
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -103,6 +103,7 @@
                                           "_ll_resize_ge": _ll_list_resize_ge,
                                           "_ll_resize_le": _ll_list_resize_le,
                                           "_ll_resize": _ll_list_resize,
+                                          "_ll_resize_hint": _ll_list_resize_hint,
                                       }),
                                       hints = {'list': True})
                              )
@@ -171,11 +172,11 @@
 # adapted C code
 
 @enforceargs(None, int, None)
-def _ll_list_resize_really(l, newsize, overallocate):
+def _ll_list_resize_hint_really(l, newsize, overallocate):
     """
-    Ensure l.items has room for at least newsize elements, and set
-    l.length to newsize.  Note that l.items may change, and even if
-    newsize is less than l.length on entry.
+    Ensure l.items has room for at least newsize elements.  Note that
+    l.items may change, and even if newsize is less than l.length on
+    entry.
     """
     # This over-allocates proportional to the list size, making room
     # for additional growth.  The over-allocation is mild, but is
@@ -210,8 +211,32 @@
         else:
             p = newsize
         rgc.ll_arraycopy(items, newitems, 0, 0, p)
+    l.items = newitems
+
+ at jit.dont_look_inside
+def _ll_list_resize_hint(l, newsize):
+    """Ensure l.items has room for at least newsize elements without
+    setting l.length to newsize.
+
+    Used before (and after) a batch operation that will likely grow the
+    list to the newsize (and after the operation incase the initial
+    guess lied).
+    """
+    allocated = len(l.items)
+    if allocated < newsize:
+        _ll_list_resize_hint_really(l, newsize, True)
+    elif newsize < (allocated >> 1) - 5:
+        _ll_list_resize_hint_really(l, newsize, False)
+
+ at enforceargs(None, int, None)
+def _ll_list_resize_really(l, newsize, overallocate):
+    """
+    Ensure l.items has room for at least newsize elements, and set
+    l.length to newsize.  Note that l.items may change, and even if
+    newsize is less than l.length on entry.
+    """
+    _ll_list_resize_hint_really(l, newsize, overallocate)
     l.length = newsize
-    l.items = newitems
 
 # this common case was factored out of _ll_list_resize
 # to see if inlining it gives some speed-up.


More information about the pypy-commit mailing list