Author: Matti Picus <matti.pi...@gmail.com> Branch: py3.5 Changeset: r94166:c3b4518f2322 Date: 2018-03-29 12:48 +0300 http://bitbucket.org/pypy/pypy/changeset/c3b4518f2322/
Log: merge default into branch diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -62,3 +62,13 @@ .. branch: rpython-sprint Refactor in rpython signatures + +.. branch: cpyext-tls-operror2 + +Store error state thread-locally in executioncontext, fixes issue #2764 + +.. branch: cpyext-fast-typecheck + +Optimize `Py*_Check` for `Bool`, `Float`, `Set`. Also refactor and simplify +`W_PyCWrapperObject` which is used to call slots from the C-API, greatly +improving microbenchmarks in https://github.com/antocuni/cpyext-benchmarks diff --git a/pypy/module/cpyext/sequence.py b/pypy/module/cpyext/sequence.py --- a/pypy/module/cpyext/sequence.py +++ b/pypy/module/cpyext/sequence.py @@ -5,7 +5,8 @@ from pypy.objspace.std.listobject import ( ListStrategy, UNROLL_CUTOFF, W_ListObject, ObjectListStrategy) from pypy.module.cpyext.api import ( - cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t, PyObject, PyObjectP) + cpython_api, CANNOT_FAIL, CONST_STRING, Py_ssize_t, PyObject, PyObjectP, + generic_cpy_call) from pypy.module.cpyext.pyobject import PyObject, make_ref, from_ref from pypy.module.cpyext.pyobject import as_pyobj, incref from rpython.rtyper.lltypesystem import rffi, lltype @@ -145,21 +146,26 @@ # XXX we should call Py*_GET_ITEM() instead of Py*_GetItem() # from here, but we cannot because we are also called from # PySequence_GetItem() + py_obj = as_pyobj(space, w_obj) if isinstance(w_obj, tupleobject.W_TupleObject): from pypy.module.cpyext.tupleobject import PyTuple_GetItem - py_obj = as_pyobj(space, w_obj) py_res = PyTuple_GetItem(space, py_obj, i) incref(space, py_res) keepalive_until_here(w_obj) return py_res if isinstance(w_obj, W_ListObject): from pypy.module.cpyext.listobject import PyList_GetItem - py_obj = as_pyobj(space, w_obj) py_res = PyList_GetItem(space, py_obj, i) incref(space, py_res) keepalive_until_here(w_obj) return py_res - return make_ref(space, space.getitem(w_obj, space.newint(i))) + + as_sequence = py_obj.c_ob_type.c_tp_as_sequence + if not as_sequence or not as_sequence.c_sq_item: + raise oefmt(space.w_TypeError, + "'%T' object does not support indexing", w_obj) + ret = generic_cpy_call(space, as_sequence.c_sq_item, w_obj, i) + return make_ref(space, ret) @cpython_api([PyObject, Py_ssize_t], PyObject, result_is_ll=True) def PySequence_GetItem(space, w_obj, i): diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c --- a/pypy/module/cpyext/test/array.c +++ b/pypy/module/cpyext/test/array.c @@ -2638,6 +2638,16 @@ Py_RETURN_NONE; }; +static PyObject * +getitem(PyObject* self, PyObject * args) { + PyObject * obj; + int i; + if (!PyArg_ParseTuple(args, "Oi", &obj, &i)) { + return NULL; + } + return PySequence_ITEM(obj, i); +} + PyDoc_STRVAR(module_doc, "This module defines an object type which can efficiently represent\n\ an array of basic values: characters, integers, floating point\n\ @@ -2937,6 +2947,7 @@ {"create_and_release_buffer", (PyCFunction)create_and_release_buffer, METH_O, NULL}, {"write_buffer_len", write_buffer_len, METH_O, NULL}, {"same_dealloc", (PyCFunction)same_dealloc, METH_VARARGS, NULL}, + {"getitem", (PyCFunction)getitem, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py --- a/pypy/module/cpyext/test/test_arraymodule.py +++ b/pypy/module/cpyext/test/test_arraymodule.py @@ -167,3 +167,15 @@ fd = BytesIO() # only test that it works fd.write(a) + + def test_getitem_via_PySequence_GetItem(self): + module = self.import_module(name='array') + a = module.array('i', range(10)) + # call via tp_as_mapping.mp_subscript + assert 5 == a[-5] + # PySequence_ITEM used to call space.getitem() which + # prefers tp_as_mapping.mp_subscript over tp_as_sequence.sq_item + # Now fixed so this test raises (array_item does not add len(a), + # array_subscr does) + raises(IndexError, module.getitem, a, -5) + diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -8,6 +8,7 @@ from pypy.module.cpyext.typeobject import cts, PyTypeObjectPtr + class AppTestTypeObject(AppTestCpythonExtensionBase): def setup_class(cls): @@ -917,6 +918,10 @@ res = "foo" in obj assert res is True + #if PY_MAJOR_VERSION > 2 + #define PyInt_Check PyLong_Check + #define PyInt_AsLong PyLong_AsLong + #endif def test_sq_ass_item(self): module = self.import_extension('foo', [ ("new_obj", "METH_NOARGS", diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py --- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py +++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py @@ -375,28 +375,58 @@ log = self.run(main, [300]) loop, = log.loops_by_filename(self.filepath) assert loop.match(""" - i161 = int_lt(i160, i43) + i106 = getfield_gc_i(p20, descr=...) + i161 = int_lt(i106, i43) guard_true(i161, descr=...) - i162 = int_add(i160, 1) - setfield_gc(p22, i162, descr=<FieldS pypy.module.__builtin__.functional.W_IntRangeIterator.inst_current .>) + i162 = int_add(i106, 1) + p110 = getfield_gc_r(p16, descr=...) + setfield_gc(p20, i162, descr=...) + guard_value(p110, ConstPtr(ptr111), descr=...) guard_not_invalidated(descr=...) p163 = force_token() p164 = force_token() - p167 = call_r(ConstClass(_ll_0_alloc_with_del___), descr=<Callr . EF=5>) + p118 = getfield_gc_r(p16, descr=...) + p120 = getarrayitem_gc_r(p118, 0, descr=...) + guard_value(p120, ConstPtr(ptr121), descr=...) + p122 = getfield_gc_r(p120, descr=...) + guard_value(p122, ConstPtr(ptr123), descr=...) + p125 = getfield_gc_r(p16, descr=...) + guard_nonnull_class(p125, ..., descr=...) + p127 = getfield_gc_r(p125, descr=...) + guard_value(p127, ConstPtr(ptr128), descr=...) + p129 = getfield_gc_r(p127, descr=...) + guard_value(p129, ConstPtr(ptr130), descr=...) + p132 = call_r(ConstClass(_ll_0_alloc_with_del___), descr=...) guard_no_exception(descr=...) - i112 = int_signext(i160, 2) - setfield_gc(p167, ConstPtr(ptr85), descr=<FieldP pypy.module._cffi_backend.cdataobj.W_CData.inst_ctype .+>) - setfield_gc(p167, -1, descr=<FieldS pypy.module._cffi_backend.cdataobj.W_CDataNewOwning.inst_allocated_length .+>) - i114 = int_ne(i160, i112) - guard_false(i114, descr=...) - # NB. we get threads because '_hashlib' uses ffi callback/def_extern - --THREAD-TICK-- - i123 = arraylen_gc(p67, descr=<ArrayP .>) - i119 = call_i(ConstClass(_ll_1_raw_malloc_varsize_zero_mpressure__Signed), 6, descr=<Calli . i EF=5 OS=110>) - check_memory_error(i119) - raw_store(i119, 0, i160, descr=<ArrayS 2>) - raw_store(i119, 2, i160, descr=<ArrayS 2>) - raw_store(i119, 4, i160, descr=<ArrayS 2>) - setfield_gc(p167, i119, descr=<FieldU pypy.module._cffi_backend.cdataobj.W_CData.inst__ptr .+>) + p133 = force_token() + p134 = new_with_vtable(descr=...) + setfield_gc(p134, ..., descr=...) + setfield_gc(p134, ConstPtr(null), descr=...) + setfield_gc(p48, p134, descr=...) + setfield_gc(p132, ..., descr=...) + i138 = call_i(ConstClass(_ll_1_raw_malloc_varsize_zero__Signed), 6, descr=...) + check_memory_error(i138) + setfield_gc(p132, i138, descr=...) + setfield_gc(p132, ConstPtr(ptr139), descr=...) + setfield_gc(p132, -1, descr=...) + setfield_gc(p0, p133, descr=...) + call_may_force_n(ConstClass(_ll_2_gc_add_memory_pressure__Signed_pypy_module__cffi_backend_cdataobj_W_CDataNewStdPtr), 6, p132, descr=...) + guard_not_forced(descr=...) + guard_no_exception(descr=...) + i144 = int_add(i138, 0) + i146 = int_signext(i106, 2) + i147 = int_ne(i106, i146) + guard_false(i147, descr=...) + setarrayitem_raw(i144, 0, i106, descr=...) + i150 = int_add(i138, 2) + setarrayitem_raw(i150, 0, i106, descr=...) + i153 = int_add(i138, 4) + setarrayitem_raw(i153, 0, i106, descr=...) + p156 = getfield_gc_r(p48, descr=...) + i158 = getfield_raw_i(..., descr=...) + setfield_gc(p48, p49, descr=...) + setfield_gc(p134, ConstPtr(null), descr=...) + i160 = int_lt(i158, 0) + guard_false(i160, descr=...) jump(..., descr=...) """) diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -742,6 +742,9 @@ def op_zero_gc_pointers_inside(self, obj): raise NotImplementedError("zero_gc_pointers_inside") + def op_gc_get_stats(self, obj): + raise NotImplementedError("gc_get_stats") + def op_gc_writebarrier_before_copy(self, source, dest, source_start, dest_start, length): if hasattr(self.heap, 'writebarrier_before_copy'): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit