@@ -1162,7 +1162,7 @@ typedef enum {
1162
1162
} AwaitableState ;
1163
1163
1164
1164
1165
- typedef struct {
1165
+ typedef struct PyAsyncGenASend {
1166
1166
PyObject_HEAD
1167
1167
PyAsyncGenObject * ags_gen ;
1168
1168
@@ -1174,7 +1174,7 @@ typedef struct {
1174
1174
} PyAsyncGenASend ;
1175
1175
1176
1176
1177
- typedef struct {
1177
+ typedef struct PyAsyncGenAThrow {
1178
1178
PyObject_HEAD
1179
1179
PyAsyncGenObject * agt_gen ;
1180
1180
@@ -1186,28 +1186,12 @@ typedef struct {
1186
1186
} PyAsyncGenAThrow ;
1187
1187
1188
1188
1189
- typedef struct {
1189
+ typedef struct _PyAsyncGenWrappedValue {
1190
1190
PyObject_HEAD
1191
1191
PyObject * agw_val ;
1192
1192
} _PyAsyncGenWrappedValue ;
1193
1193
1194
1194
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
-
1211
1195
#define _PyAsyncGenWrappedValue_CheckExact (o ) \
1212
1196
Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type)
1213
1197
@@ -1423,27 +1407,29 @@ PyAsyncGen_New(PyFrameObject *f, PyObject *name, PyObject *qualname)
1423
1407
1424
1408
1425
1409
void
1426
- _PyAsyncGen_ClearFreeLists (void )
1410
+ _PyAsyncGen_ClearFreeLists (PyThreadState * tstate )
1427
1411
{
1428
- while (ag_value_freelist_free ) {
1412
+ struct _Py_async_gen_state * state = & tstate -> interp -> async_gen ;
1413
+
1414
+ while (state -> value_numfree ) {
1429
1415
_PyAsyncGenWrappedValue * o ;
1430
- o = ag_value_freelist [-- ag_value_freelist_free ];
1416
+ o = state -> value_freelist [-- state -> value_numfree ];
1431
1417
assert (_PyAsyncGenWrappedValue_CheckExact (o ));
1432
1418
PyObject_GC_Del (o );
1433
1419
}
1434
1420
1435
- while (ag_asend_freelist_free ) {
1421
+ while (state -> asend_numfree ) {
1436
1422
PyAsyncGenASend * o ;
1437
- o = ag_asend_freelist [-- ag_asend_freelist_free ];
1423
+ o = state -> asend_freelist [-- state -> asend_numfree ];
1438
1424
assert (Py_IS_TYPE (o , & _PyAsyncGenASend_Type ));
1439
1425
PyObject_GC_Del (o );
1440
1426
}
1441
1427
}
1442
1428
1443
1429
void
1444
- _PyAsyncGen_Fini (void )
1430
+ _PyAsyncGen_Fini (PyThreadState * tstate )
1445
1431
{
1446
- _PyAsyncGen_ClearFreeLists ();
1432
+ _PyAsyncGen_ClearFreeLists (tstate );
1447
1433
}
1448
1434
1449
1435
@@ -1486,10 +1472,13 @@ async_gen_asend_dealloc(PyAsyncGenASend *o)
1486
1472
_PyObject_GC_UNTRACK ((PyObject * )o );
1487
1473
Py_CLEAR (o -> ags_gen );
1488
1474
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 ) {
1490
1478
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 {
1493
1482
PyObject_GC_Del (o );
1494
1483
}
1495
1484
}
@@ -1641,11 +1630,14 @@ static PyObject *
1641
1630
async_gen_asend_new (PyAsyncGenObject * gen , PyObject * sendval )
1642
1631
{
1643
1632
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 ];
1647
1638
_Py_NewReference ((PyObject * )o );
1648
- } else {
1639
+ }
1640
+ else {
1649
1641
o = PyObject_GC_New (PyAsyncGenASend , & _PyAsyncGenASend_Type );
1650
1642
if (o == NULL ) {
1651
1643
return NULL ;
@@ -1673,10 +1665,13 @@ async_gen_wrapped_val_dealloc(_PyAsyncGenWrappedValue *o)
1673
1665
{
1674
1666
_PyObject_GC_UNTRACK ((PyObject * )o );
1675
1667
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 ) {
1677
1671
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 {
1680
1675
PyObject_GC_Del (o );
1681
1676
}
1682
1677
}
@@ -1740,12 +1735,15 @@ _PyAsyncGenValueWrapperNew(PyObject *val)
1740
1735
_PyAsyncGenWrappedValue * o ;
1741
1736
assert (val );
1742
1737
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 ];
1746
1743
assert (_PyAsyncGenWrappedValue_CheckExact (o ));
1747
1744
_Py_NewReference ((PyObject * )o );
1748
- } else {
1745
+ }
1746
+ else {
1749
1747
o = PyObject_GC_New (_PyAsyncGenWrappedValue ,
1750
1748
& _PyAsyncGenWrappedValue_Type );
1751
1749
if (o == NULL ) {
0 commit comments