Skip to content

Commit 522691c

Browse files
authored
bpo-40521: Cleanup code of free lists (GH-21082)
Add get_xxx_state() function to factorize duplicated code.
1 parent bc43f6e commit 522691c

File tree

8 files changed

+110
-69
lines changed

8 files changed

+110
-69
lines changed

Objects/dictobject.c

+16-14
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ static uint64_t pydict_global_version = 0;
249249

250250
#include "clinic/dictobject.c.h"
251251

252+
253+
static struct _Py_dict_state *
254+
get_dict_state(void)
255+
{
256+
PyInterpreterState *interp = _PyInterpreterState_GET();
257+
return &interp->dict_state;
258+
}
259+
260+
252261
void
253262
_PyDict_ClearFreeList(PyThreadState *tstate)
254263
{
@@ -269,8 +278,7 @@ _PyDict_Fini(PyThreadState *tstate)
269278
{
270279
_PyDict_ClearFreeList(tstate);
271280
#ifdef Py_DEBUG
272-
PyInterpreterState *interp = _PyInterpreterState_GET();
273-
struct _Py_dict_state *state = &interp->dict_state;
281+
struct _Py_dict_state *state = get_dict_state();
274282
state->numfree = -1;
275283
state->keys_numfree = -1;
276284
#endif
@@ -281,8 +289,7 @@ _PyDict_Fini(PyThreadState *tstate)
281289
void
282290
_PyDict_DebugMallocStats(FILE *out)
283291
{
284-
PyInterpreterState *interp = _PyInterpreterState_GET();
285-
struct _Py_dict_state *state = &interp->dict_state;
292+
struct _Py_dict_state *state = get_dict_state();
286293
_PyDebugAllocatorStats(out, "free PyDictObject",
287294
state->numfree, sizeof(PyDictObject));
288295
}
@@ -557,8 +564,7 @@ new_keys_object(Py_ssize_t size)
557564
es = sizeof(Py_ssize_t);
558565
}
559566

560-
PyInterpreterState *interp = _PyInterpreterState_GET();
561-
struct _Py_dict_state *state = &interp->dict_state;
567+
struct _Py_dict_state *state = get_dict_state();
562568
#ifdef Py_DEBUG
563569
// new_keys_object() must not be called after _PyDict_Fini()
564570
assert(state->keys_numfree != -1);
@@ -598,8 +604,7 @@ free_keys_object(PyDictKeysObject *keys)
598604
Py_XDECREF(entries[i].me_key);
599605
Py_XDECREF(entries[i].me_value);
600606
}
601-
PyInterpreterState *interp = _PyInterpreterState_GET();
602-
struct _Py_dict_state *state = &interp->dict_state;
607+
struct _Py_dict_state *state = get_dict_state();
603608
#ifdef Py_DEBUG
604609
// free_keys_object() must not be called after _PyDict_Fini()
605610
assert(state->keys_numfree != -1);
@@ -620,8 +625,7 @@ new_dict(PyDictKeysObject *keys, PyObject **values)
620625
{
621626
PyDictObject *mp;
622627
assert(keys != NULL);
623-
PyInterpreterState *interp = _PyInterpreterState_GET();
624-
struct _Py_dict_state *state = &interp->dict_state;
628+
struct _Py_dict_state *state = get_dict_state();
625629
#ifdef Py_DEBUG
626630
// new_dict() must not be called after _PyDict_Fini()
627631
assert(state->numfree != -1);
@@ -1281,8 +1285,7 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
12811285
#ifdef Py_REF_DEBUG
12821286
_Py_RefTotal--;
12831287
#endif
1284-
PyInterpreterState *interp = _PyInterpreterState_GET();
1285-
struct _Py_dict_state *state = &interp->dict_state;
1288+
struct _Py_dict_state *state = get_dict_state();
12861289
#ifdef Py_DEBUG
12871290
// dictresize() must not be called after _PyDict_Fini()
12881291
assert(state->keys_numfree != -1);
@@ -2032,8 +2035,7 @@ dict_dealloc(PyDictObject *mp)
20322035
assert(keys->dk_refcnt == 1);
20332036
dictkeys_decref(keys);
20342037
}
2035-
PyInterpreterState *interp = _PyInterpreterState_GET();
2036-
struct _Py_dict_state *state = &interp->dict_state;
2038+
struct _Py_dict_state *state = get_dict_state();
20372039
#ifdef Py_DEBUG
20382040
// new_dict() must not be called after _PyDict_Fini()
20392041
assert(state->numfree != -1);

Objects/floatobject.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ class float "PyObject *" "&PyFloat_Type"
2323
# define PyFloat_MAXFREELIST 100
2424
#endif
2525

26+
27+
static struct _Py_float_state *
28+
get_float_state(void)
29+
{
30+
PyInterpreterState *interp = _PyInterpreterState_GET();
31+
return &interp->float_state;
32+
}
33+
34+
2635
double
2736
PyFloat_GetMax(void)
2837
{
@@ -113,8 +122,7 @@ PyFloat_GetInfo(void)
113122
PyObject *
114123
PyFloat_FromDouble(double fval)
115124
{
116-
PyInterpreterState *interp = _PyInterpreterState_GET();
117-
struct _Py_float_state *state = &interp->float_state;
125+
struct _Py_float_state *state = get_float_state();
118126
PyFloatObject *op = state->free_list;
119127
if (op != NULL) {
120128
#ifdef Py_DEBUG
@@ -222,8 +230,7 @@ static void
222230
float_dealloc(PyFloatObject *op)
223231
{
224232
if (PyFloat_CheckExact(op)) {
225-
PyInterpreterState *interp = _PyInterpreterState_GET();
226-
struct _Py_float_state *state = &interp->float_state;
233+
struct _Py_float_state *state = get_float_state();
227234
#ifdef Py_DEBUG
228235
// float_dealloc() must not be called after _PyFloat_Fini()
229236
assert(state->numfree != -1);
@@ -236,8 +243,9 @@ float_dealloc(PyFloatObject *op)
236243
Py_SET_TYPE(op, (PyTypeObject *)state->free_list);
237244
state->free_list = op;
238245
}
239-
else
246+
else {
240247
Py_TYPE(op)->tp_free((PyObject *)op);
248+
}
241249
}
242250

243251
double
@@ -2017,8 +2025,7 @@ _PyFloat_Fini(PyThreadState *tstate)
20172025
void
20182026
_PyFloat_DebugMallocStats(FILE *out)
20192027
{
2020-
PyInterpreterState *interp = _PyInterpreterState_GET();
2021-
struct _Py_float_state *state = &interp->float_state;
2028+
struct _Py_float_state *state = get_float_state();
20222029
_PyDebugAllocatorStats(out,
20232030
"free PyFloatObject",
20242031
state->numfree, sizeof(PyFloatObject));

Objects/frameobject.c

+12-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ static PyMemberDef frame_memberlist[] = {
2222
{NULL} /* Sentinel */
2323
};
2424

25+
26+
static struct _Py_frame_state *
27+
get_frame_state(void)
28+
{
29+
PyInterpreterState *interp = _PyInterpreterState_GET();
30+
return &interp->frame;
31+
}
32+
33+
2534
static PyObject *
2635
frame_getlocals(PyFrameObject *f, void *closure)
2736
{
@@ -593,8 +602,7 @@ frame_dealloc(PyFrameObject *f)
593602
co->co_zombieframe = f;
594603
}
595604
else {
596-
PyInterpreterState *interp = _PyInterpreterState_GET();
597-
struct _Py_frame_state *state = &interp->frame;
605+
struct _Py_frame_state *state = get_frame_state();
598606
#ifdef Py_DEBUG
599607
// frame_dealloc() must not be called after _PyFrame_Fini()
600608
assert(state->numfree != -1);
@@ -784,8 +792,7 @@ frame_alloc(PyCodeObject *code)
784792
Py_ssize_t ncells = PyTuple_GET_SIZE(code->co_cellvars);
785793
Py_ssize_t nfrees = PyTuple_GET_SIZE(code->co_freevars);
786794
Py_ssize_t extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
787-
PyInterpreterState *interp = _PyInterpreterState_GET();
788-
struct _Py_frame_state *state = &interp->frame;
795+
struct _Py_frame_state *state = get_frame_state();
789796
if (state->free_list == NULL)
790797
{
791798
f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras);
@@ -1206,8 +1213,7 @@ _PyFrame_Fini(PyThreadState *tstate)
12061213
void
12071214
_PyFrame_DebugMallocStats(FILE *out)
12081215
{
1209-
PyInterpreterState *interp = _PyInterpreterState_GET();
1210-
struct _Py_frame_state *state = &interp->frame;
1216+
struct _Py_frame_state *state = get_frame_state();
12111217
_PyDebugAllocatorStats(out,
12121218
"free PyFrameObject",
12131219
state->numfree, sizeof(PyFrameObject));

Objects/genobject.c

+12-8
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,14 @@ PyTypeObject PyAsyncGen_Type = {
13891389
};
13901390

13911391

1392+
static struct _Py_async_gen_state *
1393+
get_async_gen_state(void)
1394+
{
1395+
PyInterpreterState *interp = _PyInterpreterState_GET();
1396+
return &interp->async_gen;
1397+
}
1398+
1399+
13921400
PyObject *
13931401
PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
13941402
{
@@ -1477,8 +1485,7 @@ async_gen_asend_dealloc(PyAsyncGenASend *o)
14771485
_PyObject_GC_UNTRACK((PyObject *)o);
14781486
Py_CLEAR(o->ags_gen);
14791487
Py_CLEAR(o->ags_sendval);
1480-
PyInterpreterState *interp = _PyInterpreterState_GET();
1481-
struct _Py_async_gen_state *state = &interp->async_gen;
1488+
struct _Py_async_gen_state *state = get_async_gen_state();
14821489
#ifdef Py_DEBUG
14831490
// async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini()
14841491
assert(state->asend_numfree != -1);
@@ -1639,8 +1646,7 @@ static PyObject *
16391646
async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)
16401647
{
16411648
PyAsyncGenASend *o;
1642-
PyInterpreterState *interp = _PyInterpreterState_GET();
1643-
struct _Py_async_gen_state *state = &interp->async_gen;
1649+
struct _Py_async_gen_state *state = get_async_gen_state();
16441650
#ifdef Py_DEBUG
16451651
// async_gen_asend_new() must not be called after _PyAsyncGen_Fini()
16461652
assert(state->asend_numfree != -1);
@@ -1678,8 +1684,7 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
16781684
{
16791685
_PyObject_GC_UNTRACK((PyObject *)o);
16801686
Py_CLEAR(o->agw_val);
1681-
PyInterpreterState *interp = _PyInterpreterState_GET();
1682-
struct _Py_async_gen_state *state = &interp->async_gen;
1687+
struct _Py_async_gen_state *state = get_async_gen_state();
16831688
#ifdef Py_DEBUG
16841689
// async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini()
16851690
assert(state->value_numfree != -1);
@@ -1752,8 +1757,7 @@ _PyAsyncGenValueWrapperNew(PyObject *val)
17521757
_PyAsyncGenWrappedValue *o;
17531758
assert(val);
17541759

1755-
PyInterpreterState *interp = _PyInterpreterState_GET();
1756-
struct _Py_async_gen_state *state = &interp->async_gen;
1760+
struct _Py_async_gen_state *state = get_async_gen_state();
17571761
#ifdef Py_DEBUG
17581762
// _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini()
17591763
assert(state->value_numfree != -1);

Objects/listobject.c

+12-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ class list "PyListObject *" "&PyList_Type"
1919

2020
#include "clinic/listobject.c.h"
2121

22+
23+
static struct _Py_list_state *
24+
get_list_state(void)
25+
{
26+
PyInterpreterState *interp = _PyInterpreterState_GET();
27+
return &interp->list;
28+
}
29+
30+
2231
/* Ensure ob_item has room for at least newsize elements, and set
2332
* ob_size to newsize. If newsize > ob_size on entry, the content
2433
* of the new slots at exit is undefined heap trash; it's the caller's
@@ -121,8 +130,7 @@ _PyList_Fini(PyThreadState *tstate)
121130
void
122131
_PyList_DebugMallocStats(FILE *out)
123132
{
124-
PyInterpreterState *interp = _PyInterpreterState_GET();
125-
struct _Py_list_state *state = &interp->list;
133+
struct _Py_list_state *state = get_list_state();
126134
_PyDebugAllocatorStats(out,
127135
"free PyListObject",
128136
state->numfree, sizeof(PyListObject));
@@ -136,8 +144,7 @@ PyList_New(Py_ssize_t size)
136144
return NULL;
137145
}
138146

139-
PyInterpreterState *interp = _PyInterpreterState_GET();
140-
struct _Py_list_state *state = &interp->list;
147+
struct _Py_list_state *state = get_list_state();
141148
PyListObject *op;
142149
#ifdef Py_DEBUG
143150
// PyList_New() must not be called after _PyList_Fini()
@@ -336,8 +343,7 @@ list_dealloc(PyListObject *op)
336343
}
337344
PyMem_FREE(op->ob_item);
338345
}
339-
PyInterpreterState *interp = _PyInterpreterState_GET();
340-
struct _Py_list_state *state = &interp->list;
346+
struct _Py_list_state *state = get_list_state();
341347
#ifdef Py_DEBUG
342348
// list_dealloc() must not be called after _PyList_Fini()
343349
assert(state->numfree != -1);

Objects/sliceobject.c

+16-8
Original file line numberDiff line numberDiff line change
@@ -113,27 +113,35 @@ void _PySlice_Fini(PyThreadState *tstate)
113113
PyObject *
114114
PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
115115
{
116+
if (step == NULL) {
117+
step = Py_None;
118+
}
119+
if (start == NULL) {
120+
start = Py_None;
121+
}
122+
if (stop == NULL) {
123+
stop = Py_None;
124+
}
125+
116126
PyInterpreterState *interp = _PyInterpreterState_GET();
117127
PySliceObject *obj;
118128
if (interp->slice_cache != NULL) {
119129
obj = interp->slice_cache;
120130
interp->slice_cache = NULL;
121131
_Py_NewReference((PyObject *)obj);
122-
} else {
132+
}
133+
else {
123134
obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
124-
if (obj == NULL)
135+
if (obj == NULL) {
125136
return NULL;
137+
}
126138
}
127139

128-
if (step == NULL) step = Py_None;
129140
Py_INCREF(step);
130-
if (start == NULL) start = Py_None;
131-
Py_INCREF(start);
132-
if (stop == NULL) stop = Py_None;
133-
Py_INCREF(stop);
134-
135141
obj->step = step;
142+
Py_INCREF(start);
136143
obj->start = start;
144+
Py_INCREF(stop);
137145
obj->stop = stop;
138146

139147
_PyObject_GC_TRACK(obj);

0 commit comments

Comments
 (0)