[pypy-commit] pypy faster-rstruct-2: experimental checkin, reviews are welcome :). Refactor rgc._ResizableListSupportingRawPtr to use a proper lltype representation of its items, instead of a custom raw-malloced array. This makes it possible to implement ll_list(), i.e. the equivalent of llstr but for lists
antocuni
pypy.commits at gmail.com
Mon May 8 06:01:31 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct-2
Changeset: r91198:8a582e197e5b
Date: 2017-05-08 11:35 +0200
http://bitbucket.org/pypy/pypy/changeset/8a582e197e5b/
Log: experimental checkin, reviews are welcome :). Refactor
rgc._ResizableListSupportingRawPtr to use a proper lltype
representation of its items, instead of a custom raw-malloced array.
This makes it possible to implement ll_list(), i.e. 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
@@ -1051,17 +1051,25 @@
rgc.nonmoving_raw_ptr_for_resizable_list() might be
used if needed. For now, only supports lists of chars.
"""
- __slots__ = ('_raw_items',) # either None or a rffi.CCHARP
+ __slots__ = ('_ll_list',) # either None or a struct of TYPE=_get_lltype()
+
+ _LLTYPE = None
+ @classmethod
+ def _get_lltype(cls):
+ from rpython.rtyper.lltypesystem.rlist import make_LIST
+ if cls._LLTYPE is None:
+ cls._LLTYPE = make_LIST(lltype.Char)
+ return cls._LLTYPE
def __init__(self, lst):
- self._raw_items = None
+ self._ll_list = None
self.__from_list(lst)
def __resize(self):
"""Called before an operation changes the size of the list"""
- if self._raw_items is not None:
+ if self._ll_list is not None:
list.__init__(self, self.__as_list())
- self._raw_items = None
+ self._ll_list = None
def __from_list(self, lst):
"""Initialize the list from a copy of the list 'lst'."""
@@ -1072,39 +1080,39 @@
return
if len(self) != len(lst):
self.__resize()
- if self._raw_items is None:
+ if self._ll_list is None:
list.__init__(self, lst)
else:
- assert len(self) == self._raw_items._obj.getlength() == len(lst)
+ assert len(self) == self._ll_list.length == len(lst)
for i in range(len(self)):
- self._raw_items[i] = lst[i]
+ self._ll_list.items[i] = lst[i]
def __as_list(self):
"""Return a list (the same or a different one) which contains the
items in the regular way."""
- if self._raw_items is None:
+ if self._ll_list is None:
return self
- length = self._raw_items._obj.getlength()
+ length = self._ll_list.length
assert length == len(self)
- return [self._raw_items[i] for i in range(length)]
+ return [self._ll_list.items[i] for i in range(length)]
def __getitem__(self, index):
- if self._raw_items is None:
+ if self._ll_list is None:
return list.__getitem__(self, index)
if index < 0:
index += len(self)
if not (0 <= index < len(self)):
raise IndexError
- return self._raw_items[index]
+ return self._ll_list.items[index]
def __setitem__(self, index, new):
- if self._raw_items is None:
+ if self._ll_list is None:
return list.__setitem__(self, index, new)
if index < 0:
index += len(self)
if not (0 <= index < len(self)):
raise IndexError
- self._raw_items[index] = new
+ self._ll_list.items[index] = new
def __delitem__(self, index):
self.__resize()
@@ -1219,14 +1227,18 @@
self.__from_list(lst)
def _nonmoving_raw_ptr_for_resizable_list(self):
- if self._raw_items is None:
+ if self._ll_list is None:
existing_items = list(self)
from rpython.rtyper.lltypesystem import lltype, rffi
- self._raw_items = lltype.malloc(rffi.CCHARP.TO, len(self),
- flavor='raw', immortal=True)
+ LIST = self._get_lltype()
+ n = len(self)
+ self._ll_list = lltype.malloc(LIST, immortal=True)
+ self._ll_list.length = n
+ self._ll_list.items = lltype.malloc(LIST.items.TO, n)
self.__from_list(existing_items)
- assert self._raw_items is not None
- return self._raw_items
+ assert self._ll_list is not None
+ return ll_nonmovable_raw_ptr_for_resizable_list(self._ll_list)
+ #return self._raw_items
def resizable_list_supporting_raw_ptr(lst):
return _ResizableListSupportingRawPtr(lst)
@@ -1256,6 +1268,9 @@
return s_list
def specialize_call(self, hop):
+ if hop.args_r[0].LIST != _ResizableListSupportingRawPtr._get_lltype():
+ raise ValueError('Resizable list of chars does not have the '
+ 'expected low-level type')
hop.exception_cannot_occur()
return hop.inputarg(hop.args_r[0], 0)
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
@@ -351,14 +351,14 @@
p = lst
check_nonresizing()
- assert lst._raw_items is None
- lst._nonmoving_raw_ptr_for_resizable_list()
- p = lst._raw_items
+ assert lst._ll_list is None
+ p = lst._nonmoving_raw_ptr_for_resizable_list()
+ ll_list = lst._ll_list
check_nonresizing()
- assert lst._raw_items == p
- assert p[0] == 'a'
- assert p[1] == 'b'
- assert p[2] == 'c'
+ assert lst._ll_list == ll_list
+ assert p[0] == ll_list.items[0] == 'a'
+ assert p[1] == ll_list.items[1] == 'b'
+ assert p[2] == ll_list.items[2] == 'c'
def do_resizing_operation():
del lst[1]
@@ -397,7 +397,7 @@
assert lst == ['a', 'b', 'c']
for expect in do_resizing_operation():
assert lst == expect
- assert lst._raw_items is None
+ assert lst._ll_list is None
lst = ['a', 'b', 'c']
lst = rgc.resizable_list_supporting_raw_ptr(lst)
lst._nonmoving_raw_ptr_for_resizable_list()
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
@@ -4,7 +4,7 @@
from rpython.rtyper.error import TyperError
from rpython.rtyper.lltypesystem import rstr
from rpython.rtyper.lltypesystem.lltype import (GcForwardReference, Ptr, GcArray,
- GcStruct, Void, Signed, malloc, typeOf, nullptr, typeMethod)
+ GcStruct, Void, Signed, malloc, typeOf, nullptr, typeMethod, Char)
from rpython.rtyper.rlist import (AbstractBaseListRepr, AbstractListRepr,
AbstractFixedSizeListRepr, AbstractListIteratorRepr, ll_setitem_nonneg,
ADTIList, ADTIFixedList, dum_nocheck)
@@ -30,6 +30,18 @@
# item_t list_items[]
#
+def make_LIST(ITEMTYPE):
+ """
+ Return the low-level type for a resizable list of ITEMTYPE
+ """
+ from rpython.rtyper.lltypesystem.rstr import CharRepr
+ assert ITEMTYPE is Char, 'only Char is supported for now'
+ # XXX: maybe we should think of a better way to build the type?
+ list_of_char_repr = ListRepr(None, CharRepr())
+ list_of_char_repr._setup_repr()
+ return list_of_char_repr.LIST
+
+
class BaseListRepr(AbstractBaseListRepr):
rstr_ll = rstr.LLHelpers
More information about the pypy-commit
mailing list