[pypy-commit] pypy cpyext-faster-arg-passing: generalize the code and store py_obj references in types, bools, and None
cfbolz
pypy.commits at gmail.com
Fri Dec 15 17:57:58 EST 2017
Author: Carl Friedrich Bolz-Tereick <cfbolz at 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')
More information about the pypy-commit
mailing list