bpo-40521: Cleanup code of free lists (GH-21082)

Add get_xxx_state() function to factorize duplicated code.
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index f3b1157..b1f11b3 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -249,6 +249,15 @@
 
 #include "clinic/dictobject.c.h"
 
+
+static struct _Py_dict_state *
+get_dict_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->dict_state;
+}
+
+
 void
 _PyDict_ClearFreeList(PyThreadState *tstate)
 {
@@ -269,8 +278,7 @@
 {
     _PyDict_ClearFreeList(tstate);
 #ifdef Py_DEBUG
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
     state->numfree = -1;
     state->keys_numfree = -1;
 #endif
@@ -281,8 +289,7 @@
 void
 _PyDict_DebugMallocStats(FILE *out)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
     _PyDebugAllocatorStats(out, "free PyDictObject",
                            state->numfree, sizeof(PyDictObject));
 }
@@ -557,8 +564,7 @@
         es = sizeof(Py_ssize_t);
     }
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
 #ifdef Py_DEBUG
     // new_keys_object() must not be called after _PyDict_Fini()
     assert(state->keys_numfree != -1);
@@ -598,8 +604,7 @@
         Py_XDECREF(entries[i].me_key);
         Py_XDECREF(entries[i].me_value);
     }
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
 #ifdef Py_DEBUG
     // free_keys_object() must not be called after _PyDict_Fini()
     assert(state->keys_numfree != -1);
@@ -620,8 +625,7 @@
 {
     PyDictObject *mp;
     assert(keys != NULL);
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
 #ifdef Py_DEBUG
     // new_dict() must not be called after _PyDict_Fini()
     assert(state->numfree != -1);
@@ -1281,8 +1285,7 @@
 #ifdef Py_REF_DEBUG
         _Py_RefTotal--;
 #endif
-        PyInterpreterState *interp = _PyInterpreterState_GET();
-        struct _Py_dict_state *state = &interp->dict_state;
+        struct _Py_dict_state *state = get_dict_state();
 #ifdef Py_DEBUG
         // dictresize() must not be called after _PyDict_Fini()
         assert(state->keys_numfree != -1);
@@ -2032,8 +2035,7 @@
         assert(keys->dk_refcnt == 1);
         dictkeys_decref(keys);
     }
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_dict_state *state = &interp->dict_state;
+    struct _Py_dict_state *state = get_dict_state();
 #ifdef Py_DEBUG
     // new_dict() must not be called after _PyDict_Fini()
     assert(state->numfree != -1);
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 7ffd7ee..0606f29 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -23,6 +23,15 @@
 #  define PyFloat_MAXFREELIST   100
 #endif
 
+
+static struct _Py_float_state *
+get_float_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->float_state;
+}
+
+
 double
 PyFloat_GetMax(void)
 {
@@ -113,8 +122,7 @@
 PyObject *
 PyFloat_FromDouble(double fval)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_float_state *state = &interp->float_state;
+    struct _Py_float_state *state = get_float_state();
     PyFloatObject *op = state->free_list;
     if (op != NULL) {
 #ifdef Py_DEBUG
@@ -222,8 +230,7 @@
 float_dealloc(PyFloatObject *op)
 {
     if (PyFloat_CheckExact(op)) {
-        PyInterpreterState *interp = _PyInterpreterState_GET();
-        struct _Py_float_state *state = &interp->float_state;
+        struct _Py_float_state *state = get_float_state();
 #ifdef Py_DEBUG
         // float_dealloc() must not be called after _PyFloat_Fini()
         assert(state->numfree != -1);
@@ -236,8 +243,9 @@
         Py_SET_TYPE(op, (PyTypeObject *)state->free_list);
         state->free_list = op;
     }
-    else
+    else {
         Py_TYPE(op)->tp_free((PyObject *)op);
+    }
 }
 
 double
@@ -2017,8 +2025,7 @@
 void
 _PyFloat_DebugMallocStats(FILE *out)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_float_state *state = &interp->float_state;
+    struct _Py_float_state *state = get_float_state();
     _PyDebugAllocatorStats(out,
                            "free PyFloatObject",
                            state->numfree, sizeof(PyFloatObject));
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 6e1cbcf..7c2bce3 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -22,6 +22,15 @@
     {NULL}      /* Sentinel */
 };
 
+
+static struct _Py_frame_state *
+get_frame_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->frame;
+}
+
+
 static PyObject *
 frame_getlocals(PyFrameObject *f, void *closure)
 {
@@ -593,8 +602,7 @@
         co->co_zombieframe = f;
     }
     else {
-        PyInterpreterState *interp = _PyInterpreterState_GET();
-        struct _Py_frame_state *state = &interp->frame;
+        struct _Py_frame_state *state = get_frame_state();
 #ifdef Py_DEBUG
         // frame_dealloc() must not be called after _PyFrame_Fini()
         assert(state->numfree != -1);
@@ -784,8 +792,7 @@
     Py_ssize_t ncells = PyTuple_GET_SIZE(code->co_cellvars);
     Py_ssize_t nfrees = PyTuple_GET_SIZE(code->co_freevars);
     Py_ssize_t extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_frame_state *state = &interp->frame;
+    struct _Py_frame_state *state = get_frame_state();
     if (state->free_list == NULL)
     {
         f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras);
@@ -1206,8 +1213,7 @@
 void
 _PyFrame_DebugMallocStats(FILE *out)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_frame_state *state = &interp->frame;
+    struct _Py_frame_state *state = get_frame_state();
     _PyDebugAllocatorStats(out,
                            "free PyFrameObject",
                            state->numfree, sizeof(PyFrameObject));
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 4207d53..6a68c94 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -1389,6 +1389,14 @@
 };
 
 
+static struct _Py_async_gen_state *
+get_async_gen_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->async_gen;
+}
+
+
 PyObject *
 PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
 {
@@ -1477,8 +1485,7 @@
     _PyObject_GC_UNTRACK((PyObject *)o);
     Py_CLEAR(o->ags_gen);
     Py_CLEAR(o->ags_sendval);
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_async_gen_state *state = &interp->async_gen;
+    struct _Py_async_gen_state *state = get_async_gen_state();
 #ifdef Py_DEBUG
     // async_gen_asend_dealloc() must not be called after _PyAsyncGen_Fini()
     assert(state->asend_numfree != -1);
@@ -1639,8 +1646,7 @@
 async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval)
 {
     PyAsyncGenASend *o;
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_async_gen_state *state = &interp->async_gen;
+    struct _Py_async_gen_state *state = get_async_gen_state();
 #ifdef Py_DEBUG
     // async_gen_asend_new() must not be called after _PyAsyncGen_Fini()
     assert(state->asend_numfree != -1);
@@ -1678,8 +1684,7 @@
 {
     _PyObject_GC_UNTRACK((PyObject *)o);
     Py_CLEAR(o->agw_val);
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_async_gen_state *state = &interp->async_gen;
+    struct _Py_async_gen_state *state = get_async_gen_state();
 #ifdef Py_DEBUG
     // async_gen_wrapped_val_dealloc() must not be called after _PyAsyncGen_Fini()
     assert(state->value_numfree != -1);
@@ -1752,8 +1757,7 @@
     _PyAsyncGenWrappedValue *o;
     assert(val);
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_async_gen_state *state = &interp->async_gen;
+    struct _Py_async_gen_state *state = get_async_gen_state();
 #ifdef Py_DEBUG
     // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini()
     assert(state->value_numfree != -1);
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 261a0fd..ab03615 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -19,6 +19,15 @@
 
 #include "clinic/listobject.c.h"
 
+
+static struct _Py_list_state *
+get_list_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->list;
+}
+
+
 /* Ensure ob_item has room for at least newsize elements, and set
  * ob_size to newsize.  If newsize > ob_size on entry, the content
  * of the new slots at exit is undefined heap trash; it's the caller's
@@ -121,8 +130,7 @@
 void
 _PyList_DebugMallocStats(FILE *out)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_list_state *state = &interp->list;
+    struct _Py_list_state *state = get_list_state();
     _PyDebugAllocatorStats(out,
                            "free PyListObject",
                            state->numfree, sizeof(PyListObject));
@@ -136,8 +144,7 @@
         return NULL;
     }
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_list_state *state = &interp->list;
+    struct _Py_list_state *state = get_list_state();
     PyListObject *op;
 #ifdef Py_DEBUG
     // PyList_New() must not be called after _PyList_Fini()
@@ -336,8 +343,7 @@
         }
         PyMem_FREE(op->ob_item);
     }
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_list_state *state = &interp->list;
+    struct _Py_list_state *state = get_list_state();
 #ifdef Py_DEBUG
     // list_dealloc() must not be called after _PyList_Fini()
     assert(state->numfree != -1);
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index f97a570..e8af623 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -113,27 +113,35 @@
 PyObject *
 PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
 {
+    if (step == NULL) {
+        step = Py_None;
+    }
+    if (start == NULL) {
+        start = Py_None;
+    }
+    if (stop == NULL) {
+        stop = Py_None;
+    }
+
     PyInterpreterState *interp = _PyInterpreterState_GET();
     PySliceObject *obj;
     if (interp->slice_cache != NULL) {
         obj = interp->slice_cache;
         interp->slice_cache = NULL;
         _Py_NewReference((PyObject *)obj);
-    } else {
+    }
+    else {
         obj = PyObject_GC_New(PySliceObject, &PySlice_Type);
-        if (obj == NULL)
+        if (obj == NULL) {
             return NULL;
+        }
     }
 
-    if (step == NULL) step = Py_None;
     Py_INCREF(step);
-    if (start == NULL) start = Py_None;
-    Py_INCREF(start);
-    if (stop == NULL) stop = Py_None;
-    Py_INCREF(stop);
-
     obj->step = step;
+    Py_INCREF(start);
     obj->start = start;
+    Py_INCREF(stop);
     obj->stop = stop;
 
     _PyObject_GC_TRACK(obj);
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 2ff4c48..f4f9aa2 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -14,19 +14,28 @@
 
 #include "clinic/tupleobject.c.h"
 
+
+static struct _Py_tuple_state *
+get_tuple_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->tuple;
+}
+
+
 static inline void
 tuple_gc_track(PyTupleObject *op)
 {
     _PyObject_GC_TRACK(op);
 }
 
+
 /* Print summary info about the state of the optimized allocator */
 void
 _PyTuple_DebugMallocStats(FILE *out)
 {
 #if PyTuple_MAXSAVESIZE > 0
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
     for (int i = 1; i < PyTuple_MAXSAVESIZE; i++) {
         char buf[128];
         PyOS_snprintf(buf, sizeof(buf),
@@ -89,8 +98,7 @@
 {
     PyTupleObject *op;
 #if PyTuple_MAXSAVESIZE > 0
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
     if (size == 0 && state->free_list[0]) {
         op = state->free_list[0];
         Py_INCREF(op);
@@ -198,8 +206,7 @@
         return PyTuple_New(0);
     }
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
 
     va_start(vargs, n);
     PyTupleObject *result = tuple_alloc(state, n);
@@ -233,8 +240,7 @@
             Py_XDECREF(op->ob_item[i]);
         }
 #if PyTuple_MAXSAVESIZE > 0
-        PyInterpreterState *interp = _PyInterpreterState_GET();
-        struct _Py_tuple_state *state = &interp->tuple;
+        struct _Py_tuple_state *state = get_tuple_state();
 #ifdef Py_DEBUG
         // tupledealloc() must not be called after _PyTuple_Fini()
         assert(state->numfree[0] != -1);
@@ -420,8 +426,7 @@
         return PyTuple_New(0);
     }
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
     PyTupleObject *tuple = tuple_alloc(state, n);
     if (tuple == NULL) {
         return NULL;
@@ -492,8 +497,7 @@
         return PyTuple_New(0);
     }
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
     np = tuple_alloc(state, size);
     if (np == NULL) {
         return NULL;
@@ -537,8 +541,7 @@
     if (n > PY_SSIZE_T_MAX / Py_SIZE(a))
         return PyErr_NoMemory();
     size = Py_SIZE(a) * n;
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_tuple_state *state = &interp->tuple;
+    struct _Py_tuple_state *state = get_tuple_state();
     np = tuple_alloc(state, size);
     if (np == NULL)
         return NULL;
@@ -804,8 +807,7 @@
             return (PyObject *)self;
         }
         else {
-            PyInterpreterState *interp = _PyInterpreterState_GET();
-            struct _Py_tuple_state *state = &interp->tuple;
+            struct _Py_tuple_state *state = get_tuple_state();
             PyTupleObject* result = tuple_alloc(state, slicelength);
             if (!result) return NULL;
 
diff --git a/Python/context.c b/Python/context.c
index dedbca9..dc34071 100644
--- a/Python/context.c
+++ b/Python/context.c
@@ -66,6 +66,14 @@
 contextvar_del(PyContextVar *var);
 
 
+static struct _Py_context_state *
+get_context_state(void)
+{
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->context;
+}
+
+
 PyObject *
 _PyContext_NewHamtForTests(void)
 {
@@ -332,8 +340,7 @@
 static inline PyContext *
 _context_alloc(void)
 {
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_context_state *state = &interp->context;
+    struct _Py_context_state *state = get_context_state();
     PyContext *ctx;
 #ifdef Py_DEBUG
     // _context_alloc() must not be called after _PyContext_Fini()
@@ -462,8 +469,7 @@
     }
     (void)context_tp_clear(self);
 
-    PyInterpreterState *interp = _PyInterpreterState_GET();
-    struct _Py_context_state *state = &interp->context;
+    struct _Py_context_state *state = get_context_state();
 #ifdef Py_DEBUG
     // _context_alloc() must not be called after _PyContext_Fini()
     assert(state->numfree != -1);