Author: Armin Rigo <ar...@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit