[pypy-commit] pypy rpython-deque: Add everywhere items+start instead of only items for all lists

arigo pypy.commits at gmail.com
Mon Aug 15 13:01:36 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: rpython-deque
Changeset: r86204:dcf07c3d78cf
Date: 2016-08-15 19:00 +0200
http://bitbucket.org/pypy/pypy/changeset/dcf07c3d78cf/

Log:	Add everywhere items+start instead of only items for all lists

diff --git a/rpython/rtyper/lltypesystem/rdict.py b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -839,7 +839,8 @@
         res = LIST.ll_newlist(dic.num_items)
         entries = dic.entries
         dlen = len(entries)
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         i = 0
         p = 0
         while i < dlen:
diff --git a/rpython/rtyper/lltypesystem/rlist.py b/rpython/rtyper/lltypesystem/rlist.py
--- a/rpython/rtyper/lltypesystem/rlist.py
+++ b/rpython/rtyper/lltypesystem/rlist.py
@@ -17,6 +17,7 @@
 #  Concrete implementation of RPython lists:
 #
 #    struct list {
+#        int start;  // optional, default to 0
 #        int length;
 #        items_array *items;
 #    }
@@ -67,7 +68,7 @@
                                  "ll_newlist": ll_fixed_newlist,
                                  "ll_newemptylist": ll_fixed_newemptylist,
                                  "ll_length": ll_fixed_length,
-                                 "ll_items": ll_fixed_items,
+                                 "ll_items_start": ll_fixed_items_start,
                                  "ITEM": ITEM,
                                  "ll_getitem_fast": ll_fixed_getitem_fast,
                                  "ll_setitem_fast": ll_fixed_setitem_fast,
@@ -94,6 +95,11 @@
             ITEM = self.item_repr.lowleveltype
             ITEMARRAY = self.get_itemarray_lowleveltype()
             # XXX we might think of turning length stuff into Unsigned
+            extra = []
+            _ll_items_start = ll_items_0
+            if getattr(self.listitem, 'deque_hinted', False):
+                extra = [("start", Signed)]
+                _ll_items_start = ll_items_start
             self.LIST.become(GcStruct("list", ("length", Signed),
                                               ("items", Ptr(ITEMARRAY)),
                                       adtmeths = ADTIList({
@@ -101,7 +107,7 @@
                                           "ll_newlist_hint": ll_newlist_hint,
                                           "ll_newemptylist": ll_newemptylist,
                                           "ll_length": ll_length,
-                                          "ll_items": ll_items,
+                                          "ll_items_start": _ll_items_start,
                                           "ITEM": ITEM,
                                           "ll_getitem_fast": ll_getitem_fast,
                                           "ll_setitem_fast": ll_setitem_fast,
@@ -347,17 +353,22 @@
     return l.length
 ll_length.oopspec = 'list.len(l)'
 
-def ll_items(l):
-    return l.items
+def ll_items_0(l):
+    return l.items, 0
+
+def ll_items_start(l):
+    return l.items, l.start
 
 def ll_getitem_fast(l, index):
     ll_assert(index < l.length, "getitem out of bounds")
-    return l.ll_items()[index]
+    items, start = l.ll_items_start()
+    return items[start + index]
 ll_getitem_fast.oopspec = 'list.getitem(l, index)'
 
 def ll_setitem_fast(l, index, item):
     ll_assert(index < l.length, "setitem out of bounds")
-    l.ll_items()[index] = item
+    items, start = l.ll_items_start()
+    items[start + index] = item
 ll_setitem_fast.oopspec = 'list.setitem(l, index, item)'
 
 # fixed size versions
@@ -377,8 +388,8 @@
     return len(l)
 ll_fixed_length.oopspec = 'list.len(l)'
 
-def ll_fixed_items(l):
-    return l
+def ll_fixed_items_start(l):
+    return l, 0
 
 def ll_fixed_getitem_fast(l, index):
     ll_assert(index < len(l), "fixed getitem out of bounds")
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -1236,7 +1236,8 @@
         res = LIST.ll_newlist(dic.num_live_items)
         entries = dic.entries
         dlen = dic.num_ever_used_items
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         i = 0
         p = 0
         while i < dlen:
diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -182,11 +182,18 @@
                             # where NULL is always valid: it is chr(0)
 
 
-    def _list_length_items(self, hop, v_lst, LIST):
+    def _list_length_items_start(self, hop, v_lst, LIST):
         LIST = LIST.TO
         v_length = hop.gendirectcall(LIST.ll_length, v_lst)
-        v_items = hop.gendirectcall(LIST.ll_items, v_lst)
-        return v_length, v_items
+        v_items = hop.gendirectcall(_ll_items_of, v_lst)
+        v_start = hop.gendirectcall(_ll_start_of, v_lst)
+        return v_length, v_items, v_start
+
+def _ll_items_of(l):
+    return l.ll_items_start()[0]
+def _ll_start_of(l):
+    return l.ll_items_start()[1]
+
 
 class StringRepr(BaseLLStringRepr, AbstractStringRepr):
     lowleveltype = Ptr(STR)
@@ -507,7 +514,7 @@
         return result
 
     @staticmethod
-    def ll_join(s, length, items):
+    def ll_join(s, length, items, start):
         s_chars = s.chars
         s_len = len(s_chars)
         num_items = length
@@ -517,7 +524,7 @@
         i = 0
         while i < num_items:
             try:
-                itemslen = ovfcheck(itemslen + len(items[i].chars))
+                itemslen = ovfcheck(itemslen + len(items[start + i].chars))
             except OverflowError:
                 raise MemoryError
             i += 1
@@ -528,14 +535,14 @@
         # a single '+' at the end is allowed to overflow: it gets
         # a negative result, and the gc will complain
         result = s.malloc(itemslen + seplen)
-        res_index = len(items[0].chars)
-        s.copy_contents(items[0], result, 0, 0, res_index)
+        res_index = len(items[start].chars)
+        s.copy_contents(items[start], result, 0, 0, res_index)
         i = 1
         while i < num_items:
             s.copy_contents(s, result, 0, res_index, s_len)
             res_index += s_len
-            lgt = len(items[i].chars)
-            s.copy_contents(items[i], result, 0, res_index, lgt)
+            lgt = len(items[start + i].chars)
+            s.copy_contents(items[start + i], result, 0, res_index, lgt)
             res_index += lgt
             i += 1
         return result
@@ -811,20 +818,20 @@
         return count
 
     @staticmethod
-    @signature(types.int(), types.any(), returns=types.any())
-    @jit.look_inside_iff(lambda length, items: jit.loop_unrolling_heuristic(
-        items, length))
-    def ll_join_strs(length, items):
+    @signature(types.int(), types.any(), types.int(), returns=types.any())
+    @jit.look_inside_iff(lambda length, items, start:
+                         jit.loop_unrolling_heuristic(items, length))
+    def ll_join_strs(length, items, start):
         # Special case for length 1 items, helps both the JIT and other code
         if length == 1:
-            return items[0]
+            return items[start]
 
         num_items = length
         itemslen = 0
         i = 0
         while i < num_items:
             try:
-                itemslen = ovfcheck(itemslen + len(items[i].chars))
+                itemslen = ovfcheck(itemslen + len(items[start + i].chars))
             except OverflowError:
                 raise MemoryError
             i += 1
@@ -838,18 +845,17 @@
         res_index = 0
         i = 0
         while i < num_items:
-            item_chars = items[i].chars
+            item_chars = items[start + i].chars
             item_len = len(item_chars)
-            copy_contents(items[i], result, 0, res_index, item_len)
+            copy_contents(items[start + i], result, 0, res_index, item_len)
             res_index += item_len
             i += 1
         return result
 
     @staticmethod
-    @jit.look_inside_iff(lambda length, chars, RES: jit.isconstant(length) and jit.isvirtual(chars))
-    def ll_join_chars(length, chars, RES):
-        # no need to optimize this, will be replaced by string builder
-        # at some point soon
+    @jit.look_inside_iff(lambda length, chars, start, RES:
+                         jit.isconstant(length) and jit.isvirtual(chars))
+    def ll_join_chars(length, chars, start, RES):
         num_chars = length
         if RES is StringRepr.lowleveltype:
             target = Char
@@ -861,7 +867,7 @@
         res_chars = result.chars
         i = 0
         while i < num_chars:
-            res_chars[i] = cast_primitive(target, chars[i])
+            res_chars[i] = cast_primitive(target, chars[start + i])
             i += 1
         return result
 
@@ -918,7 +924,8 @@
                     break
             i += 1
         res = LIST.ll_newlist(count)
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         i = 0
         j = 0
         resindex = 0
@@ -951,7 +958,8 @@
             pos = s.find(c, pos + markerlen, last)
             count += 1
         res = LIST.ll_newlist(count)
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         pos = 0
         count = 0
         pos = s.find(c, 0, last)
@@ -985,7 +993,8 @@
                     break
             i += 1
         res = LIST.ll_newlist(count)
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         i = strlen
         j = strlen
         resindex = count - 1
@@ -1018,7 +1027,8 @@
             pos = s.rfind(c, 0, pos - markerlen)
             count += 1
         res = LIST.ll_newlist(count)
-        items = res.ll_items()
+        items, start = res.ll_items_start()
+        assert start == 0
         pos = 0
         pos = len(s.chars)
         prev_pos = pos
@@ -1133,7 +1143,7 @@
 
     @staticmethod
     def ll_build_finish(builder):
-        return LLHelpers.ll_join_strs(len(builder), builder)
+        return LLHelpers.ll_join_strs(len(builder), builder, 0)
 
     @staticmethod
     @specialize.memo()
@@ -1210,14 +1220,16 @@
             hop.genop('setarrayitem', [vtemp, i, vchunk])
 
         hop.exception_cannot_occur()   # to ignore the ZeroDivisionError of '%'
-        return hop.gendirectcall(cls.ll_join_strs, size, vtemp)
+        c_zero = inputconst(Signed, 0)
+        return hop.gendirectcall(cls.ll_join_strs, size, vtemp, c_zero)
 
     @staticmethod
     @jit.dont_look_inside
     def ll_string2list(RESLIST, src):
         length = len(src.chars)
         lst = RESLIST.ll_newlist(length)
-        dst = lst.ll_items()
+        dst, start = lst.ll_items_start()
+        assert start == 0
         SRC = typeOf(src).TO     # STR or UNICODE
         DST = typeOf(dst).TO     # GcArray
         assert DST.OF is SRC.chars.OF
diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py
--- a/rpython/rtyper/rlist.py
+++ b/rpython/rtyper/rlist.py
@@ -555,8 +555,10 @@
 def ll_arraycopy(source, dest, source_start, dest_start, length):
     SRCTYPE = typeOf(source)
     # lltype
-    rgc.ll_arraycopy(source.ll_items(), dest.ll_items(),
-                     source_start, dest_start, length)
+    srcitems, srcstart = source.ll_items_start()
+    dstitems, dststart = dest.ll_items_start()
+    rgc.ll_arraycopy(srcitems, dstitems,
+                     srcstart + source_start, dststart + dest_start, length)
 
 
 def ll_copy(RESLIST, l):
diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py
--- a/rpython/rtyper/rstr.py
+++ b/rpython/rtyper/rstr.py
@@ -203,7 +203,7 @@
         hop.exception_cannot_occur()
         return hop.gendirectcall(self.ll.ll_isalnum, v_str)
 
-    def _list_length_items(self, hop, v_lst, LIST):
+    def _list_length_items_start(self, hop, v_lst, LIST):
         """Return two Variables containing the length and items of a
         list. Need to be overriden because it is typesystem-specific."""
         raise NotImplementedError
@@ -219,7 +219,8 @@
         if not isinstance(r_lst, BaseListRepr):
             raise TyperError("string.join of non-list: %r" % r_lst)
         v_str, v_lst = hop.inputargs(rstr.repr, r_lst)
-        v_length, v_items = self._list_length_items(hop, v_lst, r_lst.lowleveltype)
+        v_length, v_items, v_start = self._list_length_items_start(hop, v_lst,
+                                                            r_lst.lowleveltype)
 
         if hop.args_s[0].is_constant() and hop.args_s[0].const == '':
             if r_lst.item_repr == rstr.repr:
@@ -228,16 +229,16 @@
                   r_lst.item_repr == unichar_repr):
                 v_tp = hop.inputconst(Void, self.lowleveltype)
                 return hop.gendirectcall(self.ll.ll_join_chars, v_length,
-                                         v_items, v_tp)
+                                         v_items, v_start, v_tp)
             else:
                 raise TyperError("''.join() of non-string list: %r" % r_lst)
-            return hop.gendirectcall(llfn, v_length, v_items)
+            return hop.gendirectcall(llfn, v_length, v_items, v_start)
         else:
             if r_lst.item_repr == rstr.repr:
                 llfn = self.ll.ll_join
             else:
                 raise TyperError("sep.join() of non-string list: %r" % r_lst)
-            return hop.gendirectcall(llfn, v_str, v_length, v_items)
+            return hop.gendirectcall(llfn, v_str, v_length, v_items, v_start)
 
     def rtype_method_splitlines(self, hop):
         rstr = hop.args_r[0].repr
diff --git a/rpython/rtyper/test/test_llinterp.py b/rpython/rtyper/test/test_llinterp.py
--- a/rpython/rtyper/test/test_llinterp.py
+++ b/rpython/rtyper/test/test_llinterp.py
@@ -207,9 +207,11 @@
     def f():
         return [1,2,3]
     res = interpret(f,[])
-    assert len(res.ll_items()) == len([1,2,3])
+    items, start = res.ll_items_start()
+    assert start == 0
+    assert len(items) == len([1,2,3])
     for i in range(3):
-        assert res.ll_items()[i] == i+1
+        assert items[i] == i+1
 
 def test_list_itemops():
     def f(i):
@@ -250,10 +252,12 @@
         l.reverse()
         return l
     res = interpret(f,[])
-    assert len(res.ll_items()) == len([3,2,1])
+    items, start = res.ll_items_start()
+    assert start == 0
+    assert len(items) == len([3,2,1])
     print res
     for i in range(3):
-        assert res.ll_items()[i] == 3-i
+        assert items[i] == 3-i
 
 def test_list_pop():
     def f():
@@ -263,7 +267,9 @@
         l3 = l.pop(-1)
         return [l1,l2,l3]
     res = interpret(f,[])
-    assert len(res.ll_items()) == 3
+    items, start = res.ll_items_start()
+    assert start == 0
+    assert len(items) == 3
 
 def test_ovf():
     def f(x):
diff --git a/rpython/rtyper/test/tool.py b/rpython/rtyper/test/tool.py
--- a/rpython/rtyper/test/tool.py
+++ b/rpython/rtyper/test/tool.py
@@ -77,8 +77,8 @@
     @staticmethod
     def ll_to_list(l):
         r = []
-        items = l.ll_items()
-        for i in range(l.ll_length()):
+        items, start = l.ll_items_start()
+        for i in range(start, start + l.ll_length()):
             r.append(items[i])
         return r
 


More information about the pypy-commit mailing list