mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	bpo-42208: Pass tstate to _PyGC_CollectNoFail() (GH-23038)
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()
This commit is contained in:
		
							parent
							
								
									99608c733c
								
							
						
					
					
						commit
						8b3414818f
					
				
					 5 changed files with 25 additions and 34 deletions
				
			
		|  | @ -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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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; | ||||
|         return 0; | ||||
|     } | ||||
|     else { | ||||
| 
 | ||||
|     Py_ssize_t n; | ||||
|     gcstate->collecting = 1; | ||||
|         n = collect(tstate, NUM_GENERATIONS - 1, NULL, NULL, 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); | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner