@@ -304,21 +304,32 @@ validate_and_copy_tuple(PyObject *tup)
304304}
305305
306306static int
307- init_co_cached (PyCodeObject * self ) {
308- if (self -> _co_cached == NULL ) {
309- self -> _co_cached = PyMem_New (_PyCoCached , 1 );
310- if (self -> _co_cached == NULL ) {
307+ init_co_cached (PyCodeObject * self )
308+ {
309+ _PyCoCached * cached = FT_ATOMIC_LOAD_PTR (self -> _co_cached );
310+ if (cached != NULL ) {
311+ return 0 ;
312+ }
313+
314+ Py_BEGIN_CRITICAL_SECTION (self );
315+ cached = self -> _co_cached ;
316+ if (cached == NULL ) {
317+ cached = PyMem_New (_PyCoCached , 1 );
318+ if (cached == NULL ) {
311319 PyErr_NoMemory ();
312- return -1 ;
313320 }
314- self -> _co_cached -> _co_code = NULL ;
315- self -> _co_cached -> _co_cellvars = NULL ;
316- self -> _co_cached -> _co_freevars = NULL ;
317- self -> _co_cached -> _co_varnames = NULL ;
321+ else {
322+ cached -> _co_code = NULL ;
323+ cached -> _co_cellvars = NULL ;
324+ cached -> _co_freevars = NULL ;
325+ cached -> _co_varnames = NULL ;
326+ FT_ATOMIC_STORE_PTR (self -> _co_cached , cached );
327+ }
318328 }
319- return 0 ;
320-
329+ Py_END_CRITICAL_SECTION () ;
330+ return cached != NULL ? 0 : -1 ;
321331}
332+
322333/******************
323334 * _PyCode_New()
324335 ******************/
@@ -1544,16 +1555,21 @@ get_cached_locals(PyCodeObject *co, PyObject **cached_field,
15441555{
15451556 assert (cached_field != NULL );
15461557 assert (co -> _co_cached != NULL );
1547- if (* cached_field != NULL ) {
1548- return Py_NewRef (* cached_field );
1558+ PyObject * varnames = FT_ATOMIC_LOAD_PTR (* cached_field );
1559+ if (varnames != NULL ) {
1560+ return Py_NewRef (varnames );
15491561 }
1550- assert (* cached_field == NULL );
1551- PyObject * varnames = get_localsplus_names (co , kind , num );
1562+
1563+ Py_BEGIN_CRITICAL_SECTION (co );
1564+ varnames = * cached_field ;
15521565 if (varnames == NULL ) {
1553- return NULL ;
1566+ varnames = get_localsplus_names (co , kind , num );
1567+ if (varnames != NULL ) {
1568+ FT_ATOMIC_STORE_PTR (* cached_field , varnames );
1569+ }
15541570 }
1555- * cached_field = Py_NewRef ( varnames );
1556- return varnames ;
1571+ Py_END_CRITICAL_SECTION ( );
1572+ return Py_XNewRef ( varnames ) ;
15571573}
15581574
15591575PyObject *
@@ -1652,18 +1668,26 @@ _PyCode_GetCode(PyCodeObject *co)
16521668 if (init_co_cached (co )) {
16531669 return NULL ;
16541670 }
1655- if (co -> _co_cached -> _co_code != NULL ) {
1656- return Py_NewRef (co -> _co_cached -> _co_code );
1671+
1672+ _PyCoCached * cached = co -> _co_cached ;
1673+ PyObject * code = FT_ATOMIC_LOAD_PTR (cached -> _co_code );
1674+ if (code != NULL ) {
1675+ return Py_NewRef (code );
16571676 }
1658- PyObject * code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
1659- _PyCode_NBYTES (co ));
1677+
1678+ Py_BEGIN_CRITICAL_SECTION (co );
1679+ code = cached -> _co_code ;
16601680 if (code == NULL ) {
1661- return NULL ;
1681+ code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
1682+ _PyCode_NBYTES (co ));
1683+ if (code != NULL ) {
1684+ deopt_code (co , (_Py_CODEUNIT * )PyBytes_AS_STRING (code ));
1685+ assert (cached -> _co_code == NULL );
1686+ FT_ATOMIC_STORE_PTR (cached -> _co_code , code );
1687+ }
16621688 }
1663- deopt_code (co , (_Py_CODEUNIT * )PyBytes_AS_STRING (code ));
1664- assert (co -> _co_cached -> _co_code == NULL );
1665- co -> _co_cached -> _co_code = Py_NewRef (code );
1666- return code ;
1689+ Py_END_CRITICAL_SECTION ();
1690+ return Py_XNewRef (code );
16671691}
16681692
16691693PyObject *
0 commit comments