]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42208: Pass tstate to _PyGC_CollectNoFail() (GH-23038)
authorVictor Stinner <vstinner@python.org>
Fri, 30 Oct 2020 16:00:00 +0000 (17:00 +0100)
committerGitHub <noreply@github.com>
Fri, 30 Oct 2020 16:00:00 +0000 (17:00 +0100)
Move private _PyGC_CollectNoFail() to the internal C API.

Remove the private _PyGC_CollectIfEnabled() which was just an alias
to the public PyGC_Collect() function since Python 3.8.

Rename functions:

* collect() => gc_collect_main()
* collect_with_callback() => gc_collect_with_callback()
* collect_generations() => gc_collect_generations()

Include/cpython/objimpl.h
Include/internal/pycore_gc.h
Modules/gcmodule.c
Python/import.c
Python/pylifecycle.c

index 15999a239f7a9a2a65ba7f031749a0799ca6e507..d83700e2a4647fe534ea44e5df60888fdc7112cb 100644 (file)
@@ -79,10 +79,6 @@ PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
 PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
 
 
-PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void);
-PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
-
-
 /* Test if an object implements the garbage collector protocol */
 PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);
 
index da202a1df532e4a9bc34d6d97c8f5607af44e447..e2d47c90c10d8035a060a0838b8fd9442b718cf1 100644 (file)
@@ -161,7 +161,9 @@ struct _gc_runtime_state {
     Py_ssize_t long_lived_pending;
 };
 
-PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *);
+extern void _PyGC_InitState(struct _gc_runtime_state *);
+
+extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
 
 
 // Functions to clear types free lists
index 8833400caba75e3f83819534d153779cc734f8c2..d90ff33684fe8c864a07ddf0250deb6efa3e5e84 100644 (file)
@@ -1176,8 +1176,9 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable,
 /* This is the main function.  Read this to understand how the
  * collection process works. */
 static Py_ssize_t
-collect(PyThreadState *tstate, int generation,
-        Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, int nofail)
+gc_collect_main(PyThreadState *tstate, int generation,
+                Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
+                int nofail)
 {
     int i;
     Py_ssize_t m = 0; /* # objects collected */
@@ -1395,19 +1396,19 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase,
  * progress callbacks.
  */
 static Py_ssize_t
-collect_with_callback(PyThreadState *tstate, int generation)
+gc_collect_with_callback(PyThreadState *tstate, int generation)
 {
     assert(!_PyErr_Occurred(tstate));
     Py_ssize_t result, collected, uncollectable;
     invoke_gc_callback(tstate, "start", generation, 0, 0);
-    result = collect(tstate, generation, &collected, &uncollectable, 0);
+    result = gc_collect_main(tstate, generation, &collected, &uncollectable, 0);
     invoke_gc_callback(tstate, "stop", generation, collected, uncollectable);
     assert(!_PyErr_Occurred(tstate));
     return result;
 }
 
 static Py_ssize_t
-collect_generations(PyThreadState *tstate)
+gc_collect_generations(PyThreadState *tstate)
 {
     GCState *gcstate = &tstate->interp->gc;
     /* Find the oldest generation (highest numbered) where the count
@@ -1455,7 +1456,7 @@ collect_generations(PyThreadState *tstate)
             if (i == NUM_GENERATIONS - 1
                 && gcstate->long_lived_pending < gcstate->long_lived_total / 4)
                 continue;
-            n = collect_with_callback(tstate, i);
+            n = gc_collect_with_callback(tstate, i);
             break;
         }
     }
@@ -1541,7 +1542,7 @@ gc_collect_impl(PyObject *module, int generation)
     }
     else {
         gcstate->collecting = 1;
-        n = collect_with_callback(tstate, generation);
+        n = gc_collect_with_callback(tstate, generation);
         gcstate->collecting = 0;
     }
     return n;
@@ -2041,7 +2042,7 @@ PyInit_gc(void)
     return m;
 }
 
-/* API to invoke gc.collect() from C */
+/* Public API to invoke gc.collect() from C */
 Py_ssize_t
 PyGC_Collect(void)
 {
@@ -2061,7 +2062,7 @@ PyGC_Collect(void)
         PyObject *exc, *value, *tb;
         gcstate->collecting = 1;
         _PyErr_Fetch(tstate, &exc, &value, &tb);
-        n = collect_with_callback(tstate, NUM_GENERATIONS - 1);
+        n = gc_collect_with_callback(tstate, NUM_GENERATIONS - 1);
         _PyErr_Restore(tstate, exc, value, tb);
         gcstate->collecting = 0;
     }
@@ -2070,19 +2071,11 @@ PyGC_Collect(void)
 }
 
 Py_ssize_t
-_PyGC_CollectIfEnabled(void)
+_PyGC_CollectNoFail(PyThreadState *tstate)
 {
-    return PyGC_Collect();
-}
-
-Py_ssize_t
-_PyGC_CollectNoFail(void)
-{
-    PyThreadState *tstate = _PyThreadState_GET();
     assert(!_PyErr_Occurred(tstate));
 
     GCState *gcstate = &tstate->interp->gc;
-    Py_ssize_t n;
 
     /* Ideally, this function is only called on interpreter shutdown,
        and therefore not recursively.  Unfortunately, when there are daemon
@@ -2091,13 +2084,13 @@ _PyGC_CollectNoFail(void)
        See http://bugs.python.org/issue8713#msg195178 for an example.
        */
     if (gcstate->collecting) {
-        n = 0;
-    }
-    else {
-        gcstate->collecting = 1;
-        n = collect(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1);
-        gcstate->collecting = 0;
+        return 0;
     }
+
+    Py_ssize_t n;
+    gcstate->collecting = 1;
+    n = gc_collect_main(tstate, NUM_GENERATIONS - 1, NULL, NULL, 1);
+    gcstate->collecting = 0;
     return n;
 }
 
@@ -2240,7 +2233,7 @@ _PyObject_GC_Alloc(int use_calloc, size_t basicsize)
         !_PyErr_Occurred(tstate))
     {
         gcstate->collecting = 1;
-        collect_generations(tstate);
+        gc_collect_generations(tstate);
         gcstate->collecting = 0;
     }
     PyObject *op = FROM_GC(g);
index b79bda058db822401ebeac73400a77fa9869f641..8b9cc3066fc4adc5b3fbc1473af0fc6a213db9cf 100644 (file)
@@ -566,7 +566,7 @@ _PyImport_Cleanup(PyThreadState *tstate)
     }
     Py_XDECREF(dict);
     /* Collect references */
-    _PyGC_CollectNoFail();
+    _PyGC_CollectNoFail(tstate);
     /* Dump GC stats before it's too late, since it uses the warnings
        machinery. */
     _PyGC_DumpShutdownStats(tstate);
@@ -626,7 +626,7 @@ _PyImport_Cleanup(PyThreadState *tstate)
     Py_DECREF(modules);
 
     /* Once more */
-    _PyGC_CollectNoFail();
+    _PyGC_CollectNoFail(tstate);
 
 #undef CLEAR_MODULE
 #undef STORE_MODULE_WEAKREF
index 774a4f9de08e0e9ea62aca03d391338d14b39392..71834f63f2a78da1d1df077696fa16bc5e805af0 100644 (file)
@@ -1293,7 +1293,7 @@ finalize_interp_clear(PyThreadState *tstate)
     PyInterpreterState_Clear(tstate->interp);
 
     /* Last explicit GC collection */
-    _PyGC_CollectNoFail();
+    _PyGC_CollectNoFail(tstate);
 
     /* Clear all loghooks */
     /* Both _PySys_Audit function and users still need PyObject, such as tuple.
@@ -1414,7 +1414,7 @@ Py_FinalizeEx(void)
      * XXX but I'm unclear on exactly how that one happens.  In any case,
      * XXX I haven't seen a real-life report of either of these.
      */
-    _PyGC_CollectIfEnabled();
+    PyGC_Collect();
 
     /* Destroy all modules */
     _PyImport_Cleanup(tstate);