Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80218:b20b38d7dd99
Date: 2015-10-14 21:57 +0200
http://bitbucket.org/pypy/pypy/changeset/b20b38d7dd99/

Log:    Yay, the first test passes (in test_api)

diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -512,7 +512,7 @@
 PyObjectStruct = lltype.ForwardReference()
 PyObject = lltype.Ptr(PyObjectStruct)
 PyObjectFields = (("ob_refcnt", lltype.Signed), ("ob_type", PyTypeObjectPtr),
-                  ("ob_pypy_link", llmemory.GCREF))
+                  ("ob_pypy_link", lltype.Signed))
 PyVarObjectFields = PyObjectFields + (("ob_size", Py_ssize_t), )
 cpython_struct('PyObject', PyObjectFields, PyObjectStruct)
 PyVarObjectStruct = cpython_struct("PyVarObject", PyVarObjectFields)
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
@@ -17,9 +17,9 @@
 #define staticforward static
 
 #define PyObject_HEAD  \
-    long ob_refcnt;       \
-    struct _typeobject *ob_type; \
-    void *ob_pypy_link;
+    Py_ssize_t ob_refcnt;        \
+    Py_ssize_t ob_pypy_link;     \
+    struct _typeobject *ob_type;
 
 #define PyObject_VAR_HEAD              \
        PyObject_HEAD                   \
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
@@ -286,13 +286,11 @@
         state.py_objects_r2w[ptr] = w_obj
 
 
-NULL_GCREF = lltype.nullptr(llmemory.GCREF.TO)
-
 def _create_pyobj_from_w_obj(w_obj):
     # XXX temp, needs cases
     ob = lltype.malloc(PyObject.TO, flavor='raw', track_allocation=False)
     ob.c_ob_refcnt = 0
-    ob.c_ob_pypy_link = NULL_GCREF
+    ob.c_ob_pypy_link = 0
     # ob.c_ob_type = ...
     rawrefcount.create_link_pypy(w_obj, ob)
     return ob
@@ -309,7 +307,7 @@
         return lltype.nullptr(PyObject.TO)
     #if isinstance(w_obj, W_CPyExtPlaceHolderObject):
     #    xxx
-    ob = rawrefcount.from_obj(PyObject.TO, w_obj)
+    ob = rawrefcount.from_obj(PyObject, w_obj)
     if not ob:
         ob = _create_pyobj_from_w_obj(w_obj)
     return ob
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -12,16 +12,25 @@
 REFCNT_FROM_PYPY_OBJECT = 80   # == 0x50
 
 
-_p_list = []     # not rpython
-_o_list = []     # not rpython
-_s_list = []     # not rpython
+def _reset_state():
+    global _p_list, _o_list, _s_list, _adr2pypy
+    _p_list = []     # not rpython
+    _o_list = []     # not rpython
+    _s_list = []     # not rpython
+    _adr2pypy = [None]  # not rpython
+_reset_state()
+
+def _build_pypy_link(p):
+    res = len(_adr2pypy)
+    _adr2pypy.append(p)
+    return res
 
 
 def create_link_pypy(p, ob):
     "NOT_RPYTHON: a link where the PyPy object contains all the data"
     assert not hasattr(p, '__rawrefcount')
     assert not ob.c_ob_pypy_link
-    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_pypy_link = _build_pypy_link(p)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = ob
     _p_list.append(ob)
@@ -31,7 +40,7 @@
        from_obj() will not work on this 'p'."""
     assert not hasattr(p, '__rawrefcount')
     assert not ob.c_ob_pypy_link
-    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_pypy_link = _build_pypy_link(p)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
     _o_list.append(ob)
@@ -41,28 +50,29 @@
        from_obj() will not work on this 'p'."""
     assert not hasattr(p, '__rawrefcount')
     assert not ob.c_ob_pypy_link
-    ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+    ob.c_ob_pypy_link = _build_pypy_link(p)
     ob.c_ob_refcnt += REFCNT_FROM_PYPY_OBJECT
     p.__rawrefcount = lltype.nullptr(lltype.typeOf(ob).TO)
     _s_list.append(ob)
 
-def from_obj(OBTYPE, p):
+def from_obj(OB_PTR_TYPE, p):
     "NOT_RPYTHON"
-    null = lltype.nullptr(OBTYPE)
+    null = lltype.nullptr(OB_PTR_TYPE.TO)
     ob = getattr(p, '__rawrefcount', null)
-    assert lltype.typeOf(ob) == lltype.Ptr(OBTYPE)
+    assert lltype.typeOf(ob) == OB_PTR_TYPE
     return ob
 
 @specialize.arg(0)
 def to_obj(Class, ob):
-    pypy_gcref = ob.c_ob_pypy_link
+    link = ob.c_ob_pypy_link
     if we_are_translated():
+        pypy_gcref = lltype.cast_int_to_ptr(llmemory.GCREF, link)
         return annlowlevel.cast_gcref_to_instance(Class, pypy_gcref)
     else:
-        if not pypy_gcref:
+        if link == 0:
             return None
-        p = rgc.try_cast_gcref_to_instance(Class, pypy_gcref)
-        assert p is not None
+        p = _adr2pypy[link]
+        assert isinstance(p, Class)
         return p
 
 def _collect():
@@ -73,9 +83,9 @@
     def detach(ob, wr_list):
         assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
         assert ob.c_ob_pypy_link
-        p = rgc.try_cast_gcref_to_instance(object, ob.c_ob_pypy_link)
+        p = _adr2pypy[ob.c_ob_pypy_link]
         assert p is not None
-        ob.c_ob_pypy_link = lltype.nullptr(llmemory.GCREF.TO)
+        _adr2pypy[ob.c_ob_pypy_link] = None
         wr_list.append((ob, weakref.ref(p)))
 
     global _p_list, _o_list, _s_list
@@ -85,7 +95,7 @@
         if ob.c_ob_refcnt > REFCNT_FROM_PYPY_OBJECT:
             new_p_list.append(ob)
         else:
-            wr_p_list.append(weakref.ref(ob))
+            detach(ob, wr_p_list)
         ob = None
     _p_list = Ellipsis
 
@@ -112,18 +122,19 @@
         assert ob.c_ob_refcnt >= REFCNT_FROM_PYPY_OBJECT
         p = wr()
         if p is not None:
-            ob.c_ob_pypy_link = rgc.cast_instance_to_gcref(p)
+            assert ob.c_ob_pypy_link
+            _adr2pypy[ob.c_ob_pypy_link] = p
             final_list.append(ob)
         else:
             ob.c_ob_refcnt -= REFCNT_FROM_PYPY_OBJECT
-            if ob.c_ob_refcnt == 0:
+            ob.c_ob_pypy_link = 0
+            if ob.c_ob_refcnt == 0 and dealloc is not None:
                 dealloc.append(ob)
 
     _p_list = new_p_list
-    for wr in wr_p_list:
-        ob = wr()
-        if ob is not None:
-            _p_list.append(ob)
+    dealloc = None
+    for ob, wr in wr_p_list:
+        attach(ob, wr, _p_list)
     #
     dealloc = []
     _s_list = new_s_list
diff --git a/rpython/rlib/test/test_rawrefcount.py 
b/rpython/rlib/test/test_rawrefcount.py
--- a/rpython/rlib/test/test_rawrefcount.py
+++ b/rpython/rlib/test/test_rawrefcount.py
@@ -8,45 +8,43 @@
 
 PyObjectS = lltype.Struct('PyObjectS',
                           ('c_ob_refcnt', lltype.Signed),
-                          ('c_ob_pypy_link', llmemory.GCREF))
+                          ('c_ob_pypy_link', lltype.Signed))
 PyObject = lltype.Ptr(PyObjectS)
 
 
 class TestRawRefCount:
 
     def setup_method(self, meth):
-        del rawrefcount._p_list[:]
-        del rawrefcount._o_list[:]
-        del rawrefcount._s_list[:]
+        rawrefcount._reset_state()
 
     def test_create_link_pypy(self):
         p = W_Root(42)
         ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
                            track_allocation=False)
-        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == None
         rawrefcount.create_link_pypy(p, ob)
-        assert rawrefcount.from_obj(PyObjectS, p) == ob
+        assert rawrefcount.from_obj(PyObject, p) == ob
         assert rawrefcount.to_obj(W_Root, ob) == p
 
     def test_create_link_pyobj(self):
         p = W_Root(42)
         ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
                            track_allocation=False)
-        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == None
         rawrefcount.create_link_pyobj(p, ob)
-        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == p
 
     def test_create_link_shared(self):
         p = W_Root(42)
         ob = lltype.malloc(PyObjectS, flavor='raw', zero=True,
                            track_allocation=False)
-        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == None
         rawrefcount.create_link_shared(p, ob)
-        assert rawrefcount.from_obj(PyObjectS, p) == lltype.nullptr(PyObjectS)
+        assert rawrefcount.from_obj(PyObject, p) == lltype.nullptr(PyObjectS)
         assert rawrefcount.to_obj(W_Root, ob) == p
 
     def test_collect_p_dies(self):
@@ -79,7 +77,7 @@
         assert ob is not None and p is not None
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
-        assert rawrefcount.from_obj(PyObjectS, p) == ob
+        assert rawrefcount.from_obj(PyObject, p) == ob
 
     def test_collect_p_keepalive_w_root(self):
         p = W_Root(42)
@@ -94,7 +92,7 @@
         assert ob is not None
         assert rawrefcount._p_list == [ob]
         assert rawrefcount.to_obj(W_Root, ob) == p
-        assert rawrefcount.from_obj(PyObjectS, p) == ob
+        assert rawrefcount.from_obj(PyObject, p) == ob
 
     def test_collect_o_dies(self):
         p = W_Root(42)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to