Author: Carl Friedrich Bolz-Tereick <cfb...@gmx.de> Branch: cpyext-faster-arg-passing Changeset: r93429:5187eda5bf36 Date: 2017-12-15 14:28 +0100 http://bitbucket.org/pypy/pypy/changeset/5187eda5bf36/
Log: generalize the code and store py_obj references in types, bools, and None diff --git a/pypy/module/cpyext/pyobject.py b/pypy/module/cpyext/pyobject.py --- a/pypy/module/cpyext/pyobject.py +++ b/pypy/module/cpyext/pyobject.py @@ -10,6 +10,8 @@ PyVarObject, Py_ssize_t, init_function, cts) from pypy.module.cpyext.state import State from pypy.objspace.std.typeobject import W_TypeObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.boolobject import W_BoolObject from pypy.objspace.std.objectobject import W_ObjectObject from rpython.rlib.objectmodel import specialize, we_are_translated from rpython.rlib.objectmodel import keepalive_until_here @@ -26,14 +28,6 @@ the link from the w_obj to the cpy ref. This is only used for C-defined types. """ - _cpy_ref = lltype.nullptr(PyObject.TO) - - def _cpyext_as_pyobj(self, space): - return self._cpy_ref - - def _cpyext_attach_pyobj(self, space, py_obj): - self._cpy_ref = py_obj - rawrefcount.create_link_pyobj(self, py_obj) def check_true(s_arg, bookeeper): assert s_arg.const is True @@ -53,6 +47,28 @@ # default implementation of _cpyext_attach_pyobj rawrefcount.create_link_pypy(w_obj, py_obj) + +def add_direct_pyobj_storage(cls): + """ Add the necessary methods to a class to store a reference to the py_obj + on its instances directly. """ + + cls._cpy_ref = lltype.nullptr(PyObject.TO) + + def _cpyext_as_pyobj(self, space): + return self._cpy_ref + cls._cpyext_as_pyobj = _cpyext_as_pyobj + + def _cpyext_attach_pyobj(self, space, py_obj): + self._cpy_ref = py_obj + rawrefcount.create_link_pyobj(self, py_obj) + cls._cpyext_attach_pyobj = _cpyext_attach_pyobj + +add_direct_pyobj_storage(W_BaseCPyObject) +add_direct_pyobj_storage(W_TypeObject) +add_direct_pyobj_storage(W_NoneObject) +add_direct_pyobj_storage(W_BoolObject) + + class BaseCpyTypedescr(object): basestruct = PyObject.TO W_BaseObject = W_ObjectObject 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 @@ -11,10 +11,9 @@ def setup_class(cls): AppTestCpythonExtensionBase.setup_class.im_func(cls) def _check_uses_shortcut(w_inst): - from pypy.module.cpyext.pyobject import W_BaseCPyObject - assert isinstance(w_inst, W_BaseCPyObject) - assert w_inst._cpy_ref - assert as_pyobj(cls.space, w_inst) == w_inst._cpy_ref + res = hasattr(w_inst, "_cpy_ref") and w_inst._cpy_ref + res = res and as_pyobj(cls.space, w_inst) == w_inst._cpy_ref + return cls.space.newbool(res) cls.w__check_uses_shortcut = cls.space.wrap( gateway.interp2app(_check_uses_shortcut)) @@ -174,7 +173,16 @@ # their pyobj, because they store a pointer to it directly. module = self.import_module(name='foo') obj = module.fooType() - self._check_uses_shortcut(obj) + assert self._check_uses_shortcut(obj) + # W_TypeObjects use shortcut + assert self._check_uses_shortcut(object) + assert self._check_uses_shortcut(type) + # None, True, False use shortcut + assert self._check_uses_shortcut(None) + assert self._check_uses_shortcut(True) + assert self._check_uses_shortcut(False) + assert not self._check_uses_shortcut(1) + assert not self._check_uses_shortcut(object()) def test_multiple_inheritance1(self): module = self.import_module(name='foo') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit