Author: Antonio Cuni <anto.c...@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' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit