[pypy-commit] pypy faster-rstruct-2: implement rgc.ll_for_resizable_list, which is the equivalent of llstr(), but for lists

antocuni pypy.commits at gmail.com
Mon May 8 06:01:33 EDT 2017


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91199:ed23f8739819
Date: 2017-05-08 12:00 +0200
http://bitbucket.org/pypy/pypy/changeset/ed23f8739819/

Log:	implement rgc.ll_for_resizable_list, which is the equivalent of
	llstr(), but for lists

diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -1226,7 +1226,7 @@
         list.sort(lst, *args, **kwds)
         self.__from_list(lst)
 
-    def _nonmoving_raw_ptr_for_resizable_list(self):
+    def _get_ll_list(self):
         if self._ll_list is None:
             existing_items = list(self)
             from rpython.rtyper.lltypesystem import lltype, rffi
@@ -1237,8 +1237,11 @@
             self._ll_list.items = lltype.malloc(LIST.items.TO, n)
             self.__from_list(existing_items)
             assert self._ll_list is not None
-        return ll_nonmovable_raw_ptr_for_resizable_list(self._ll_list)
-        #return self._raw_items
+        return self._ll_list
+
+    def _nonmoving_raw_ptr_for_resizable_list(self):
+        ll_list = self._get_ll_list()
+        return ll_nonmovable_raw_ptr_for_resizable_list(ll_list)
 
 def resizable_list_supporting_raw_ptr(lst):
     return _ResizableListSupportingRawPtr(lst)
@@ -1247,6 +1250,18 @@
     assert isinstance(lst, _ResizableListSupportingRawPtr)
     return lst._nonmoving_raw_ptr_for_resizable_list()
 
+def ll_for_resizable_list(lst):
+    """
+    This is the equivalent of llstr(), but for lists. It can be called only if
+    the list has been created by calling resizable_list_supporting_raw_ptr().
+
+    In theory, all the operations on lst are immediately visible also on
+    ll_list. However, support for that is incomplete in
+    _ResizableListSupportingRawPtr and as such, the pointer becomes invalid as
+    soon as you call a resizing operation on lst.
+    """
+    assert isinstance(lst, _ResizableListSupportingRawPtr)
+    return lst._get_ll_list()
 
 def _check_resizable_list_of_chars(s_list):
     from rpython.annotator import model as annmodel
@@ -1289,6 +1304,23 @@
         return hop.gendirectcall(ll_nonmovable_raw_ptr_for_resizable_list,
                                  v_list)
 
+class Entry(ExtRegistryEntry):
+    _about_ = ll_for_resizable_list
+
+    def compute_result_annotation(self, s_list):
+        from rpython.rtyper.llannotation import lltype_to_annotation
+        _check_resizable_list_of_chars(s_list)
+        LIST = _ResizableListSupportingRawPtr._get_lltype()
+        return lltype_to_annotation(lltype.Ptr(LIST))
+
+    def specialize_call(self, hop):
+        hop.exception_cannot_occur()
+        assert hop.args_r[0].lowleveltype == hop.r_result.lowleveltype
+        v_ll_list, = hop.inputargs(*hop.args_r)
+        return hop.genop('same_as', [v_ll_list],
+                         resulttype = hop.r_result.lowleveltype)
+
+
 @jit.dont_look_inside
 def ll_nonmovable_raw_ptr_for_resizable_list(ll_list):
     """
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -304,6 +304,50 @@
     data = subprocess.check_output([str(exename), '.', '.', '.'])
     assert data.strip().endswith('OK!')
 
+def test_ll_for_resizable_list():
+    def f(n):
+        lst = ['a', 'b', 'c']
+        lst = rgc.resizable_list_supporting_raw_ptr(lst)
+        lst.append(chr(n))
+        assert lst[3] == chr(n)
+        assert lst[-1] == chr(n)
+        #
+        ll_list = rgc.ll_for_resizable_list(lst)
+        assert lst[:] == ['a', 'b', 'c', chr(n)]
+        assert ll_list.length == 4
+        assert [ll_list.items[i] for i in range(4)] == ['a', 'b', 'c', chr(n)]
+        #
+        lst[-3] = 'X'
+        assert ll_list.items[1] == 'X'
+        ll_list.items[2] = 'Y'
+        assert lst[-2] == 'Y'
+        #
+        return lst
+    #
+    # direct untranslated run
+    lst = f(35)
+    assert isinstance(lst, rgc._ResizableListSupportingRawPtr)
+    #
+    # llinterp run
+    interpret(f, [35])
+    #
+    # compilation with the GC transformer
+    import subprocess
+    from rpython.translator.interactive import Translation
+    #
+    def main(argv):
+        f(len(argv))
+        print "OK!"
+        return 0
+    #
+    t = Translation(main, gc="incminimark")
+    t.disable(['backendopt'])
+    t.set_backend_extra_options(c_debug_defines=True)
+    exename = t.compile()
+    data = subprocess.check_output([str(exename), '.', '.', '.'])
+    assert data.strip().endswith('OK!')
+
+
 def test_ListSupportingRawPtr_direct():
     lst = ['a', 'b', 'c']
     lst = rgc.resizable_list_supporting_raw_ptr(lst)
@@ -353,7 +397,8 @@
     check_nonresizing()
     assert lst._ll_list is None
     p = lst._nonmoving_raw_ptr_for_resizable_list()
-    ll_list = lst._ll_list
+    ll_list = rgc.ll_for_resizable_list(lst)
+    assert ll_list is lst._ll_list
     check_nonresizing()
     assert lst._ll_list == ll_list
     assert p[0] == ll_list.items[0] == 'a'


More information about the pypy-commit mailing list