[pypy-commit] pypy cpyext-refactor-methodobject: merge cpyext-avoid-roundtrip inside this
antocuni
pypy.commits at gmail.com
Mon Oct 16 06:23:57 EDT 2017
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: cpyext-refactor-methodobject
Changeset: r92776:a5eb32fe2228
Date: 2017-10-16 12:23 +0200
http://bitbucket.org/pypy/pypy/changeset/a5eb32fe2228/
Log: merge cpyext-avoid-roundtrip inside this
diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h
--- a/pypy/module/cpyext/include/object.h
+++ b/pypy/module/cpyext/include/object.h
@@ -65,7 +65,10 @@
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
-#define _Py_NewReference(ob) (((PyObject *)(ob))->ob_refcnt = 1)
+#define _Py_NewReference(op) \
+ ( ((PyObject *)(op))->ob_refcnt = 1, \
+ ((PyObject *)(op))->ob_pypy_link = 0 )
+
#define _Py_ForgetReference(ob) /* nothing */
#define Py_None (&_Py_NoneStruct)
diff --git a/pypy/module/cpyext/src/object.c b/pypy/module/cpyext/src/object.c
--- a/pypy/module/cpyext/src/object.c
+++ b/pypy/module/cpyext/src/object.c
@@ -17,7 +17,16 @@
Py_XDECREF(o);
}
-Py_ssize_t _pypy_rawrefcount_w_marker_deallocating; /* set from pyobject.py */
+/*
+ * The actual value of this variable will be the address of
+ * pyobject.w_marker_deallocating, and will be set by
+ * pyobject.write_w_marker_deallocating().
+ *
+ * The value set here is used only as a marker by tests (because during the
+ * tests we cannot call set_marker(), so we need to set a special value
+ * directly here)
+ */
+Py_ssize_t _pypy_rawrefcount_w_marker_deallocating = 0xDEADFFF;
void
_Py_Dealloc(PyObject *obj)
diff --git a/pypy/module/cpyext/test/test_tupleobject.py b/pypy/module/cpyext/test/test_tupleobject.py
--- a/pypy/module/cpyext/test/test_tupleobject.py
+++ b/pypy/module/cpyext/test/test_tupleobject.py
@@ -52,6 +52,31 @@
py_b = as_pyobj(space, w_b)
assert py_a != py_b
+ def test_PyTuple_New_initialize_pypy_link(self, space, api):
+ from rpython.rlib.rawrefcount import _collect
+ state = space.fromcache(State)
+ # see object.c:_pypy_rawrefcount_w_marker_deallocating
+ MARKER = 0xDEADFFF
+ #
+ # first: create a pytuple, attach a w_obj, decref the pytuple and let
+ # the GC to collect the w_obj: this way, c_ob_pypy_link is set to
+ # w_marker_deallocating
+ py_a = state.C.PyTuple_New(0)
+ assert py_a.c_ob_pypy_link == 0
+ w_a = from_ref(space, py_a)
+ assert py_a.c_ob_pypy_link != 0
+ decref(space, py_a)
+ w_a = None
+ _collect()
+ assert py_a.c_ob_pypy_link == MARKER
+ #
+ # second: create another tuple, which will reuse the same memory as
+ # before thanks to the freelist. Check that c_ob_pypy_link has been
+ # initialized to 0.
+ py_b = state.C.PyTuple_New(0)
+ assert py_b == py_a
+ assert py_b.c_ob_pypy_link == 0
+
def test_tuple_resize(self, space, api):
state = space.fromcache(State)
w_42 = space.wrap(42)
diff --git a/pypy/module/cpyext/tupleobject.py b/pypy/module/cpyext/tupleobject.py
--- a/pypy/module/cpyext/tupleobject.py
+++ b/pypy/module/cpyext/tupleobject.py
@@ -27,6 +27,10 @@
## Then the macro PyTuple_GET_ITEM can be implemented like CPython.
##
+# CCC: we have a problem in the branch: some of the functions defined in C,
+# like PyTuple_New, might call PyErr_*, but since these are implemented in
+# RPython, they are not GIL-safe. We need to think about it :(
+
PyTupleObjectStruct = lltype.ForwardReference()
PyTupleObject = lltype.Ptr(PyTupleObjectStruct)
ObjectItems = rffi.CArray(PyObject)
More information about the pypy-commit
mailing list