@@ -1162,7 +1162,7 @@ typedef enum {
11621162} AwaitableState ;
11631163
11641164
1165- typedef struct {
1165+ typedef struct PyAsyncGenASend {
11661166 PyObject_HEAD
11671167 PyAsyncGenObject * ags_gen ;
11681168
@@ -1174,7 +1174,7 @@ typedef struct {
11741174} PyAsyncGenASend ;
11751175
11761176
1177- typedef struct {
1177+ typedef struct PyAsyncGenAThrow {
11781178 PyObject_HEAD
11791179 PyAsyncGenObject * agt_gen ;
11801180
@@ -1186,28 +1186,12 @@ typedef struct {
11861186} PyAsyncGenAThrow ;
11871187
11881188
1189- typedef struct {
1189+ typedef struct _PyAsyncGenWrappedValue {
11901190 PyObject_HEAD
11911191 PyObject * agw_val ;
11921192} _PyAsyncGenWrappedValue ;
11931193
11941194
1195- #ifndef _PyAsyncGen_MAXFREELIST
1196- #define _PyAsyncGen_MAXFREELIST 80
1197- #endif
1198-
1199- /* Freelists boost performance 6-10%; they also reduce memory
1200- fragmentation, as _PyAsyncGenWrappedValue and PyAsyncGenASend
1201- are short-living objects that are instantiated for every
1202- __anext__ call.
1203- */
1204-
1205- static _PyAsyncGenWrappedValue * ag_value_freelist [_PyAsyncGen_MAXFREELIST ];
1206- static int ag_value_freelist_free = 0 ;
1207-
1208- static PyAsyncGenASend * ag_asend_freelist [_PyAsyncGen_MAXFREELIST ];
1209- static int ag_asend_freelist_free = 0 ;
1210-
12111195#define _PyAsyncGenWrappedValue_CheckExact (o ) \
12121196 Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type)
12131197
@@ -1423,27 +1407,29 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
14231407
14241408
14251409void
1426- _PyAsyncGen_ClearFreeLists (void )
1410+ _PyAsyncGen_ClearFreeLists (PyThreadState * tstate )
14271411{
1428- while (ag_value_freelist_free ) {
1412+ struct _Py_async_gen_state * state = & tstate -> interp -> async_gen ;
1413+
1414+ while (state -> value_numfree ) {
14291415 _PyAsyncGenWrappedValue * o ;
1430- o = ag_value_freelist [-- ag_value_freelist_free ];
1416+ o = state -> value_freelist [-- state -> value_numfree ];
14311417 assert (_PyAsyncGenWrappedValue_CheckExact (o ));
14321418 PyObject_GC_Del (o );
14331419 }
14341420
1435- while (ag_asend_freelist_free ) {
1421+ while (state -> asend_numfree ) {
14361422 PyAsyncGenASend * o ;
1437- o = ag_asend_freelist [-- ag_asend_freelist_free ];
1423+ o = state -> asend_freelist [-- state -> asend_numfree ];
14381424 assert (Py_IS_TYPE (o , & _PyAsyncGenASend_Type ));
14391425 PyObject_GC_Del (o );
14401426 }
14411427}
14421428
14431429void
1444- _PyAsyncGen_Fini (void )
1430+ _PyAsyncGen_Fini (PyThreadState * tstate )
14451431{
1446- _PyAsyncGen_ClearFreeLists ();
1432+ _PyAsyncGen_ClearFreeLists (tstate );
14471433}
14481434
14491435
@@ -1486,10 +1472,13 @@ async_gen_asend_dealloc(PyAsyncGenASend *o)
14861472 _PyObject_GC_UNTRACK ((PyObject * )o );
14871473 Py_CLEAR (o -> ags_gen );
14881474 Py_CLEAR (o -> ags_sendval );
1489- if (ag_asend_freelist_free < _PyAsyncGen_MAXFREELIST ) {
1475+ PyInterpreterState * interp = _PyInterpreterState_GET ();
1476+ struct _Py_async_gen_state * state = & interp -> async_gen ;
1477+ if (state -> asend_numfree < _PyAsyncGen_MAXFREELIST ) {
14901478 assert (PyAsyncGenASend_CheckExact (o ));
1491- ag_asend_freelist [ag_asend_freelist_free ++ ] = o ;
1492- } else {
1479+ state -> asend_freelist [state -> asend_numfree ++ ] = o ;
1480+ }
1481+ else {
14931482 PyObject_GC_Del (o );
14941483 }
14951484}
@@ -1641,11 +1630,14 @@ static PyObject *
16411630async_gen_asend_new (PyAsyncGenObject * gen , PyObject * sendval )
16421631{
16431632 PyAsyncGenASend * o ;
1644- if (ag_asend_freelist_free ) {
1645- ag_asend_freelist_free -- ;
1646- o = ag_asend_freelist [ag_asend_freelist_free ];
1633+ PyInterpreterState * interp = _PyInterpreterState_GET ();
1634+ struct _Py_async_gen_state * state = & interp -> async_gen ;
1635+ if (state -> asend_numfree ) {
1636+ state -> asend_numfree -- ;
1637+ o = state -> asend_freelist [state -> asend_numfree ];
16471638 _Py_NewReference ((PyObject * )o );
1648- } else {
1639+ }
1640+ else {
16491641 o = PyObject_GC_New (PyAsyncGenASend , & _PyAsyncGenASend_Type );
16501642 if (o == NULL ) {
16511643 return NULL ;
@@ -1673,10 +1665,13 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
16731665{
16741666 _PyObject_GC_UNTRACK ((PyObject * )o );
16751667 Py_CLEAR (o -> agw_val );
1676- if (ag_value_freelist_free < _PyAsyncGen_MAXFREELIST ) {
1668+ PyInterpreterState * interp = _PyInterpreterState_GET ();
1669+ struct _Py_async_gen_state * state = & interp -> async_gen ;
1670+ if (state -> value_numfree < _PyAsyncGen_MAXFREELIST ) {
16771671 assert (_PyAsyncGenWrappedValue_CheckExact (o ));
1678- ag_value_freelist [ag_value_freelist_free ++ ] = o ;
1679- } else {
1672+ state -> value_freelist [state -> value_numfree ++ ] = o ;
1673+ }
1674+ else {
16801675 PyObject_GC_Del (o );
16811676 }
16821677}
@@ -1740,12 +1735,15 @@ _PyAsyncGenValueWrapperNew(PyObject *val)
17401735 _PyAsyncGenWrappedValue * o ;
17411736 assert (val );
17421737
1743- if (ag_value_freelist_free ) {
1744- ag_value_freelist_free -- ;
1745- o = ag_value_freelist [ag_value_freelist_free ];
1738+ PyInterpreterState * interp = _PyInterpreterState_GET ();
1739+ struct _Py_async_gen_state * state = & interp -> async_gen ;
1740+ if (state -> value_numfree ) {
1741+ state -> value_numfree -- ;
1742+ o = state -> value_freelist [state -> value_numfree ];
17461743 assert (_PyAsyncGenWrappedValue_CheckExact (o ));
17471744 _Py_NewReference ((PyObject * )o );
1748- } else {
1745+ }
1746+ else {
17491747 o = PyObject_GC_New (_PyAsyncGenWrappedValue ,
17501748 & _PyAsyncGenWrappedValue_Type );
17511749 if (o == NULL ) {
0 commit comments