27
27
#include "pycore_context.h"
28
28
#include "pycore_initconfig.h"
29
29
#include "pycore_object.h"
30
+ #include "pycore_pyerrors.h"
30
31
#include "pycore_pymem.h"
31
32
#include "pycore_pystate.h"
32
33
#include "frameobject.h" /* for PyFrame_ClearFreeList */
@@ -917,10 +918,11 @@ debug_cycle(const char *msg, PyObject *op)
917
918
* merged into the old list regardless.
918
919
*/
919
920
static void
920
- handle_legacy_finalizers (struct _gc_runtime_state * state ,
921
+ handle_legacy_finalizers (PyThreadState * tstate ,
922
+ struct _gc_runtime_state * state ,
921
923
PyGC_Head * finalizers , PyGC_Head * old )
922
924
{
923
- assert (!PyErr_Occurred ( ));
925
+ assert (!_PyErr_Occurred ( tstate ));
924
926
assert (state -> garbage != NULL );
925
927
926
928
PyGC_Head * gc = GC_NEXT (finalizers );
@@ -929,7 +931,7 @@ handle_legacy_finalizers(struct _gc_runtime_state *state,
929
931
930
932
if ((state -> debug & DEBUG_SAVEALL ) || has_legacy_finalizer (op )) {
931
933
if (PyList_Append (state -> garbage , op ) < 0 ) {
932
- PyErr_Clear ( );
934
+ _PyErr_Clear ( tstate );
933
935
break ;
934
936
}
935
937
}
@@ -979,10 +981,10 @@ finalize_garbage(PyGC_Head *collectable)
979
981
* objects may be freed. It is possible I screwed something up here.
980
982
*/
981
983
static void
982
- delete_garbage (struct _gc_runtime_state * state ,
984
+ delete_garbage (PyThreadState * tstate , struct _gc_runtime_state * state ,
983
985
PyGC_Head * collectable , PyGC_Head * old )
984
986
{
985
- assert (!PyErr_Occurred ( ));
987
+ assert (!_PyErr_Occurred ( tstate ));
986
988
987
989
while (!gc_list_is_empty (collectable )) {
988
990
PyGC_Head * gc = GC_NEXT (collectable );
@@ -994,15 +996,15 @@ delete_garbage(struct _gc_runtime_state *state,
994
996
if (state -> debug & DEBUG_SAVEALL ) {
995
997
assert (state -> garbage != NULL );
996
998
if (PyList_Append (state -> garbage , op ) < 0 ) {
997
- PyErr_Clear ( );
999
+ _PyErr_Clear ( tstate );
998
1000
}
999
1001
}
1000
1002
else {
1001
1003
inquiry clear ;
1002
1004
if ((clear = Py_TYPE (op )-> tp_clear ) != NULL ) {
1003
1005
Py_INCREF (op );
1004
1006
(void ) clear (op );
1005
- if (PyErr_Occurred ( )) {
1007
+ if (_PyErr_Occurred ( tstate )) {
1006
1008
_PyErr_WriteUnraisableMsg ("in tp_clear of" ,
1007
1009
(PyObject * )Py_TYPE (op ));
1008
1010
}
@@ -1143,7 +1145,7 @@ handle_resurrected_objects(PyGC_Head *unreachable, PyGC_Head* still_unreachable,
1143
1145
/* This is the main function. Read this to understand how the
1144
1146
* collection process works. */
1145
1147
static Py_ssize_t
1146
- collect (struct _gc_runtime_state * state , int generation ,
1148
+ collect (PyThreadState * tstate , struct _gc_runtime_state * state , int generation ,
1147
1149
Py_ssize_t * n_collected , Py_ssize_t * n_uncollectable , int nofail )
1148
1150
{
1149
1151
int i ;
@@ -1245,7 +1247,7 @@ collect(struct _gc_runtime_state *state, int generation,
1245
1247
* in finalizers to be freed.
1246
1248
*/
1247
1249
m += gc_list_size (& final_unreachable );
1248
- delete_garbage (state , & final_unreachable , old );
1250
+ delete_garbage (tstate , state , & final_unreachable , old );
1249
1251
1250
1252
/* Collect statistics on uncollectable objects found and print
1251
1253
* debugging information. */
@@ -1266,7 +1268,7 @@ collect(struct _gc_runtime_state *state, int generation,
1266
1268
* reachable list of garbage. The programmer has to deal with
1267
1269
* this if they insist on creating this type of structure.
1268
1270
*/
1269
- handle_legacy_finalizers (state , & finalizers , old );
1271
+ handle_legacy_finalizers (tstate , state , & finalizers , old );
1270
1272
validate_list (old , collecting_clear_unreachable_clear );
1271
1273
1272
1274
/* Clear free list only during the collection of the highest
@@ -1275,9 +1277,9 @@ collect(struct _gc_runtime_state *state, int generation,
1275
1277
clear_freelists ();
1276
1278
}
1277
1279
1278
- if (PyErr_Occurred ( )) {
1280
+ if (_PyErr_Occurred ( tstate )) {
1279
1281
if (nofail ) {
1280
- PyErr_Clear ( );
1282
+ _PyErr_Clear ( tstate );
1281
1283
}
1282
1284
else {
1283
1285
if (gc_str == NULL )
@@ -1301,11 +1303,11 @@ collect(struct _gc_runtime_state *state, int generation,
1301
1303
stats -> uncollectable += n ;
1302
1304
1303
1305
if (PyDTrace_GC_DONE_ENABLED ()) {
1304
- PyDTrace_GC_DONE (n + m );
1306
+ PyDTrace_GC_DONE (n + m );
1305
1307
}
1306
1308
1307
- assert (!PyErr_Occurred ( ));
1308
- return n + m ;
1309
+ assert (!_PyErr_Occurred ( tstate ));
1310
+ return n + m ;
1309
1311
}
1310
1312
1311
1313
/* Invoke progress callbacks to notify clients that garbage collection
@@ -1356,19 +1358,20 @@ invoke_gc_callback(struct _gc_runtime_state *state, const char *phase,
1356
1358
* progress callbacks.
1357
1359
*/
1358
1360
static Py_ssize_t
1359
- collect_with_callback (struct _gc_runtime_state * state , int generation )
1361
+ collect_with_callback (PyThreadState * tstate , struct _gc_runtime_state * state ,
1362
+ int generation )
1360
1363
{
1361
1364
assert (!PyErr_Occurred ());
1362
1365
Py_ssize_t result , collected , uncollectable ;
1363
1366
invoke_gc_callback (state , "start" , generation , 0 , 0 );
1364
- result = collect (state , generation , & collected , & uncollectable , 0 );
1367
+ result = collect (tstate , state , generation , & collected , & uncollectable , 0 );
1365
1368
invoke_gc_callback (state , "stop" , generation , collected , uncollectable );
1366
1369
assert (!PyErr_Occurred ());
1367
1370
return result ;
1368
1371
}
1369
1372
1370
1373
static Py_ssize_t
1371
- collect_generations (struct _gc_runtime_state * state )
1374
+ collect_generations (PyThreadState * tstate , struct _gc_runtime_state * state )
1372
1375
{
1373
1376
/* Find the oldest generation (highest numbered) where the count
1374
1377
* exceeds the threshold. Objects in the that generation and
@@ -1383,7 +1386,7 @@ collect_generations(struct _gc_runtime_state *state)
1383
1386
if (i == NUM_GENERATIONS - 1
1384
1387
&& state -> long_lived_pending < state -> long_lived_total / 4 )
1385
1388
continue ;
1386
- n = collect_with_callback (state , i );
1389
+ n = collect_with_callback (tstate , state , i );
1387
1390
break ;
1388
1391
}
1389
1392
}
@@ -1451,9 +1454,10 @@ static Py_ssize_t
1451
1454
gc_collect_impl (PyObject * module , int generation )
1452
1455
/*[clinic end generated code: output=b697e633043233c7 input=40720128b682d879]*/
1453
1456
{
1457
+ PyThreadState * tstate = _PyThreadState_GET ();
1454
1458
1455
1459
if (generation < 0 || generation >= NUM_GENERATIONS ) {
1456
- PyErr_SetString ( PyExc_ValueError , "invalid generation" );
1460
+ _PyErr_SetString ( tstate , PyExc_ValueError , "invalid generation" );
1457
1461
return -1 ;
1458
1462
}
1459
1463
@@ -1465,7 +1469,7 @@ gc_collect_impl(PyObject *module, int generation)
1465
1469
}
1466
1470
else {
1467
1471
state -> collecting = 1 ;
1468
- n = collect_with_callback (state , generation );
1472
+ n = collect_with_callback (tstate , state , generation );
1469
1473
state -> collecting = 0 ;
1470
1474
}
1471
1475
return n ;
@@ -1940,7 +1944,9 @@ PyInit_gc(void)
1940
1944
Py_ssize_t
1941
1945
PyGC_Collect (void )
1942
1946
{
1947
+ PyThreadState * tstate = _PyThreadState_GET ();
1943
1948
struct _gc_runtime_state * state = & _PyRuntime .gc ;
1949
+
1944
1950
if (!state -> enabled ) {
1945
1951
return 0 ;
1946
1952
}
@@ -1953,9 +1959,9 @@ PyGC_Collect(void)
1953
1959
else {
1954
1960
PyObject * exc , * value , * tb ;
1955
1961
state -> collecting = 1 ;
1956
- PyErr_Fetch ( & exc , & value , & tb );
1957
- n = collect_with_callback (state , NUM_GENERATIONS - 1 );
1958
- PyErr_Restore ( exc , value , tb );
1962
+ _PyErr_Fetch ( tstate , & exc , & value , & tb );
1963
+ n = collect_with_callback (tstate , state , NUM_GENERATIONS - 1 );
1964
+ _PyErr_Restore ( tstate , exc , value , tb );
1959
1965
state -> collecting = 0 ;
1960
1966
}
1961
1967
@@ -1971,7 +1977,8 @@ _PyGC_CollectIfEnabled(void)
1971
1977
Py_ssize_t
1972
1978
_PyGC_CollectNoFail (void )
1973
1979
{
1974
- assert (!PyErr_Occurred ());
1980
+ PyThreadState * tstate = _PyThreadState_GET ();
1981
+ assert (!_PyErr_Occurred (tstate ));
1975
1982
1976
1983
struct _gc_runtime_state * state = & _PyRuntime .gc ;
1977
1984
Py_ssize_t n ;
@@ -1987,7 +1994,7 @@ _PyGC_CollectNoFail(void)
1987
1994
}
1988
1995
else {
1989
1996
state -> collecting = 1 ;
1990
- n = collect (state , NUM_GENERATIONS - 1 , NULL , NULL , 1 );
1997
+ n = collect (tstate , state , NUM_GENERATIONS - 1 , NULL , NULL , 1 );
1991
1998
state -> collecting = 0 ;
1992
1999
}
1993
2000
return n ;
@@ -2098,32 +2105,38 @@ static PyObject *
2098
2105
_PyObject_GC_Alloc (int use_calloc , size_t basicsize )
2099
2106
{
2100
2107
struct _gc_runtime_state * state = & _PyRuntime .gc ;
2101
- PyObject * op ;
2102
- PyGC_Head * g ;
2103
- size_t size ;
2104
- if (basicsize > PY_SSIZE_T_MAX - sizeof (PyGC_Head ))
2108
+ if (basicsize > PY_SSIZE_T_MAX - sizeof (PyGC_Head )) {
2105
2109
return PyErr_NoMemory ();
2106
- size = sizeof (PyGC_Head ) + basicsize ;
2107
- if (use_calloc )
2110
+ }
2111
+ size_t size = sizeof (PyGC_Head ) + basicsize ;
2112
+
2113
+ PyGC_Head * g ;
2114
+ if (use_calloc ) {
2108
2115
g = (PyGC_Head * )PyObject_Calloc (1 , size );
2109
- else
2116
+ }
2117
+ else {
2110
2118
g = (PyGC_Head * )PyObject_Malloc (size );
2111
- if (g == NULL )
2119
+ }
2120
+ if (g == NULL ) {
2112
2121
return PyErr_NoMemory ();
2122
+ }
2113
2123
assert (((uintptr_t )g & 3 ) == 0 ); // g must be aligned 4bytes boundary
2124
+
2114
2125
g -> _gc_next = 0 ;
2115
2126
g -> _gc_prev = 0 ;
2116
2127
state -> generations [0 ].count ++ ; /* number of allocated GC objects */
2117
2128
if (state -> generations [0 ].count > state -> generations [0 ].threshold &&
2118
2129
state -> enabled &&
2119
2130
state -> generations [0 ].threshold &&
2120
2131
!state -> collecting &&
2121
- !PyErr_Occurred ()) {
2132
+ !PyErr_Occurred ())
2133
+ {
2134
+ PyThreadState * tstate = _PyThreadState_GET ();
2122
2135
state -> collecting = 1 ;
2123
- collect_generations (state );
2136
+ collect_generations (tstate , state );
2124
2137
state -> collecting = 0 ;
2125
2138
}
2126
- op = FROM_GC (g );
2139
+ PyObject * op = FROM_GC (g );
2127
2140
return op ;
2128
2141
}
2129
2142
0 commit comments