[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