@@ -150,7 +150,22 @@ validate_and_copy_tuple(PyObject *tup)
150150 return newtuple ;
151151}
152152
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 ;
153167
168+ }
154169/******************
155170 * _PyCode_New()
156171 ******************/
@@ -336,7 +351,7 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
336351 /* not set */
337352 co -> co_weakreflist = NULL ;
338353 co -> co_extra = NULL ;
339- co -> _co_code = NULL ;
354+ co -> _co_cached = NULL ;
340355
341356 co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
342357 co -> _co_linearray_entry_size = 0 ;
@@ -1384,10 +1399,31 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
13841399 * other PyCodeObject accessor functions
13851400 ******************/
13861401
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+
13871420PyObject *
13881421_PyCode_GetVarnames (PyCodeObject * co )
13891422{
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 );
13911427}
13921428
13931429PyObject *
@@ -1399,7 +1435,10 @@ PyCode_GetVarnames(PyCodeObject *code)
13991435PyObject *
14001436_PyCode_GetCellvars (PyCodeObject * co )
14011437{
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 );
14031442}
14041443
14051444PyObject *
@@ -1411,7 +1450,10 @@ PyCode_GetCellvars(PyCodeObject *code)
14111450PyObject *
14121451_PyCode_GetFreevars (PyCodeObject * co )
14131452{
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 );
14151457}
14161458
14171459PyObject *
@@ -1437,17 +1479,20 @@ deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len)
14371479PyObject *
14381480_PyCode_GetCode (PyCodeObject * co )
14391481{
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 );
14421487 }
14431488 PyObject * code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
14441489 _PyCode_NBYTES (co ));
14451490 if (code == NULL ) {
14461491 return NULL ;
14471492 }
14481493 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 );
14511496 return code ;
14521497}
14531498
@@ -1606,7 +1651,13 @@ code_dealloc(PyCodeObject *co)
16061651 Py_XDECREF (co -> co_qualname );
16071652 Py_XDECREF (co -> co_linetable );
16081653 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+ }
16101661 if (co -> co_weakreflist != NULL ) {
16111662 PyObject_ClearWeakRefs ((PyObject * )co );
16121663 }
@@ -2181,7 +2232,13 @@ _PyStaticCode_Dealloc(PyCodeObject *co)
21812232 deopt_code (_PyCode_CODE (co ), Py_SIZE (co ));
21822233 co -> co_warmup = QUICKENING_INITIAL_WARMUP_VALUE ;
21832234 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+ }
21852242 co -> co_extra = NULL ;
21862243 if (co -> co_weakreflist != NULL ) {
21872244 PyObject_ClearWeakRefs ((PyObject * )co );
0 commit comments