@@ -150,7 +150,22 @@ validate_and_copy_tuple(PyObject *tup)
150
150
return newtuple ;
151
151
}
152
152
153
+ static int
154
+ init_co_cached (PyCodeObject * self ) {
155
+ if (self -> _co_cached == NULL ) {
156
+ self -> _co_cached = PyMem_New (_PyCoCached , 1 );
157
+ if (self -> _co_cached == NULL ) {
158
+ PyErr_NoMemory ();
159
+ return -1 ;
160
+ }
161
+ self -> _co_cached -> _co_code = NULL ;
162
+ self -> _co_cached -> _co_cellvars = NULL ;
163
+ self -> _co_cached -> _co_freevars = NULL ;
164
+ self -> _co_cached -> _co_varnames = NULL ;
165
+ }
166
+ return 0 ;
153
167
168
+ }
154
169
/******************
155
170
* _PyCode_New()
156
171
******************/
@@ -336,7 +351,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
336
351
/* not set */
337
352
co -> co_weakreflist = NULL ;
338
353
co -> co_extra = NULL ;
339
- co -> _co_code = NULL ;
354
+ co -> _co_cached = NULL ;
340
355
341
356
co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
342
357
co -> _co_linearray_entry_size = 0 ;
@@ -1384,10 +1399,31 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
1384
1399
* other PyCodeObject accessor functions
1385
1400
******************/
1386
1401
1402
+ static PyObject *
1403
+ get_cached_locals (PyCodeObject * co , PyObject * * cached_field ,
1404
+ _PyLocals_Kind kind , int num )
1405
+ {
1406
+ assert (cached_field != NULL );
1407
+ assert (co -> _co_cached != NULL );
1408
+ if (* cached_field != NULL ) {
1409
+ return Py_NewRef (* cached_field );
1410
+ }
1411
+ assert (* cached_field == NULL );
1412
+ PyObject * varnames = get_localsplus_names (co , kind , num );
1413
+ if (varnames == NULL ) {
1414
+ return NULL ;
1415
+ }
1416
+ * cached_field = Py_NewRef (varnames );
1417
+ return varnames ;
1418
+ }
1419
+
1387
1420
PyObject *
1388
1421
_PyCode_GetVarnames (PyCodeObject * co )
1389
1422
{
1390
- return get_localsplus_names (co , CO_FAST_LOCAL , co -> co_nlocals );
1423
+ if (init_co_cached (co )) {
1424
+ return NULL ;
1425
+ }
1426
+ return get_cached_locals (co , & co -> _co_cached -> _co_varnames , CO_FAST_LOCAL , co -> co_nlocals );
1391
1427
}
1392
1428
1393
1429
PyObject *
@@ -1399,7 +1435,10 @@ PyCode_GetVarnames(PyCodeObject *code)
1399
1435
PyObject *
1400
1436
_PyCode_GetCellvars (PyCodeObject * co )
1401
1437
{
1402
- return get_localsplus_names (co , CO_FAST_CELL , co -> co_ncellvars );
1438
+ if (init_co_cached (co )) {
1439
+ return NULL ;
1440
+ }
1441
+ return get_cached_locals (co , & co -> _co_cached -> _co_cellvars , CO_FAST_CELL , co -> co_ncellvars );
1403
1442
}
1404
1443
1405
1444
PyObject *
@@ -1411,7 +1450,10 @@ PyCode_GetCellvars(PyCodeObject *code)
1411
1450
PyObject *
1412
1451
_PyCode_GetFreevars (PyCodeObject * co )
1413
1452
{
1414
- return get_localsplus_names (co , CO_FAST_FREE , co -> co_nfreevars );
1453
+ if (init_co_cached (co )) {
1454
+ return NULL ;
1455
+ }
1456
+ return get_cached_locals (co , & co -> _co_cached -> _co_freevars , CO_FAST_FREE , co -> co_nfreevars );
1415
1457
}
1416
1458
1417
1459
PyObject *
@@ -1437,17 +1479,20 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
1437
1479
PyObject *
1438
1480
_PyCode_GetCode (PyCodeObject * co )
1439
1481
{
1440
- if (co -> _co_code != NULL ) {
1441
- return Py_NewRef (co -> _co_code );
1482
+ if (init_co_cached (co )) {
1483
+ return NULL ;
1484
+ }
1485
+ if (co -> _co_cached -> _co_code != NULL ) {
1486
+ return Py_NewRef (co -> _co_cached -> _co_code );
1442
1487
}
1443
1488
PyObject * code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
1444
1489
_PyCode_NBYTES (co ));
1445
1490
if (code == NULL ) {
1446
1491
return NULL ;
1447
1492
}
1448
1493
deopt_code ((_Py_CODEUNIT * )PyBytes_AS_STRING (code ), Py_SIZE (co ));
1449
- assert (co -> _co_code == NULL );
1450
- co -> _co_code = Py_NewRef (code );
1494
+ assert (co -> _co_cached -> _co_code == NULL );
1495
+ co -> _co_cached -> _co_code = Py_NewRef (code );
1451
1496
return code ;
1452
1497
}
1453
1498
@@ -1606,7 +1651,13 @@ code_dealloc(PyCodeObject *co)
1606
1651
Py_XDECREF (co -> co_qualname );
1607
1652
Py_XDECREF (co -> co_linetable );
1608
1653
Py_XDECREF (co -> co_exceptiontable );
1609
- Py_XDECREF (co -> _co_code );
1654
+ if (co -> _co_cached != NULL ) {
1655
+ Py_XDECREF (co -> _co_cached -> _co_code );
1656
+ Py_XDECREF (co -> _co_cached -> _co_cellvars );
1657
+ Py_XDECREF (co -> _co_cached -> _co_freevars );
1658
+ Py_XDECREF (co -> _co_cached -> _co_varnames );
1659
+ PyMem_Free (co -> _co_cached );
1660
+ }
1610
1661
if (co -> co_weakreflist != NULL ) {
1611
1662
PyObject_ClearWeakRefs ((PyObject * )co );
1612
1663
}
@@ -2181,7 +2232,13 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
2181
2232
deopt_code (_PyCode_CODE (co ), Py_SIZE (co ));
2182
2233
co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
2183
2234
PyMem_Free (co -> co_extra );
2184
- Py_CLEAR (co -> _co_code );
2235
+ if (co -> _co_cached != NULL ) {
2236
+ Py_CLEAR (co -> _co_cached -> _co_code );
2237
+ Py_CLEAR (co -> _co_cached -> _co_cellvars );
2238
+ Py_CLEAR (co -> _co_cached -> _co_freevars );
2239
+ Py_CLEAR (co -> _co_cached -> _co_varnames );
2240
+ PyMem_Free (co -> _co_cached );
2241
+ }
2185
2242
co -> co_extra = NULL ;
2186
2243
if (co -> co_weakreflist != NULL ) {
2187
2244
PyObject_ClearWeakRefs ((PyObject * )co );
0 commit comments