]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-105268: Add _Py_FROM_GC() function to pycore_gc.h (#105362)
authorVictor Stinner <vstinner@python.org>
Tue, 6 Jun 2023 12:44:48 +0000 (14:44 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Jun 2023 12:44:48 +0000 (14:44 +0200)
* gcmodule.c reuses _Py_AS_GC(op) for AS_GC()
* Move gcmodule.c FROM_GC() implementation to a new _Py_FROM_GC()
  static inline function in pycore_gc.h.
* _PyObject_IS_GC(): only get the type once
* gc_is_finalized(à) and PyObject_GC_IsFinalized() use
  _PyGC_FINALIZED(), instead of _PyGCHead_FINALIZED().
* Remove _Py_CAST() in pycore_gc.h: this header file is not built
  with C++.

Include/internal/pycore_gc.h
Include/internal/pycore_object.h
Modules/gcmodule.c

index b3abe2030a03dacfc2ea31317ef67c9c26ef64c1..2d33aa76d78229f60d8e6edf6bcee2fdd1aae804 100644 (file)
@@ -19,10 +19,21 @@ typedef struct {
     uintptr_t _gc_prev;
 } PyGC_Head;
 
+#define _PyGC_Head_UNUSED PyGC_Head
+
+
+/* Get an object's GC head */
 static inline PyGC_Head* _Py_AS_GC(PyObject *op) {
-    return (_Py_CAST(PyGC_Head*, op) - 1);
+    char *gc = ((char*)op) - sizeof(PyGC_Head);
+    return (PyGC_Head*)gc;
 }
-#define _PyGC_Head_UNUSED PyGC_Head
+
+/* Get the object given the GC head */
+static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
+    char *op = ((char *)gc) + sizeof(PyGC_Head);
+    return (PyObject *)op;
+}
+
 
 /* True if the object is currently tracked by the GC. */
 static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
@@ -57,19 +68,19 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
 // But it is always 0 for normal code.
 static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
     uintptr_t next = gc->_gc_next;
-    return _Py_CAST(PyGC_Head*, next);
+    return (PyGC_Head*)next;
 }
 static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
-    gc->_gc_next = _Py_CAST(uintptr_t, next);
+    gc->_gc_next = (uintptr_t)next;
 }
 
 // Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
 static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
     uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
-    return _Py_CAST(PyGC_Head*, prev);
+    return (PyGC_Head*)prev;
 }
 static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
-    uintptr_t uprev = _Py_CAST(uintptr_t, prev);
+    uintptr_t uprev = (uintptr_t)prev;
     assert((uprev & ~_PyGC_PREV_MASK) == 0);
     gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev);
 }
index 0981d1122fec5487bdee01b1d272b2452c7fa5dc..3ac7e89bbf53453ae43e8593e0111908f5e25407 100644 (file)
@@ -326,9 +326,9 @@ _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
 static inline int
 _PyObject_IS_GC(PyObject *obj)
 {
-    return (PyType_IS_GC(Py_TYPE(obj))
-            && (Py_TYPE(obj)->tp_is_gc == NULL
-                || Py_TYPE(obj)->tp_is_gc(obj)));
+    PyTypeObject *type = Py_TYPE(obj);
+    return (PyType_IS_GC(type)
+            && (type->tp_is_gc == NULL || type->tp_is_gc(obj)));
 }
 
 // Fast inlined version of PyType_IS_GC()
index 26ddcdd538a4d4a3efbf9b899cc19127b319a850..c51c100be8361defcfd11b6c34a5568eefa55b95 100644 (file)
@@ -68,11 +68,9 @@ module gc
 // most gc_list_* functions for it.
 #define NEXT_MASK_UNREACHABLE  (1)
 
-/* Get an object's GC head */
-#define AS_GC(o) ((PyGC_Head *)(((char *)(o))-sizeof(PyGC_Head)))
+#define AS_GC(op) _Py_AS_GC(op)
+#define FROM_GC(gc) _Py_FROM_GC(gc)
 
-/* Get the object given the GC head */
-#define FROM_GC(g) ((PyObject *)(((char *)(g))+sizeof(PyGC_Head)))
 
 static inline int
 gc_is_collecting(PyGC_Head *g)
@@ -861,7 +859,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
              * to imagine how calling it later could create a problem for us.  wr
              * is moved to wrcb_to_call in this case.
              */
-            if (gc_is_collecting(AS_GC(wr))) {
+            if (gc_is_collecting(AS_GC((PyObject *)wr))) {
                 /* it should already have been cleared above */
                 assert(wr->wr_object == Py_None);
                 continue;
@@ -873,7 +871,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
             Py_INCREF(wr);
 
             /* Move wr to wrcb_to_call, for the next pass. */
-            wrasgc = AS_GC(wr);
+            wrasgc = AS_GC((PyObject *)wr);
             assert(wrasgc != next); /* wrasgc is reachable, but
                                        next isn't, so they can't
                                        be the same */
@@ -1909,7 +1907,7 @@ static PyObject *
 gc_is_finalized(PyObject *module, PyObject *obj)
 /*[clinic end generated code: output=e1516ac119a918ed input=201d0c58f69ae390]*/
 {
-    if (_PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
+    if (_PyObject_IS_GC(obj) && _PyGC_FINALIZED(obj)) {
          Py_RETURN_TRUE;
     }
     Py_RETURN_FALSE;
@@ -2409,7 +2407,7 @@ PyObject_GC_IsTracked(PyObject* obj)
 int
 PyObject_GC_IsFinalized(PyObject *obj)
 {
-    if (_PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(AS_GC(obj))) {
+    if (_PyObject_IS_GC(obj) && _PyGC_FINALIZED(obj)) {
          return 1;
     }
     return 0;