@@ -302,21 +302,32 @@ validate_and_copy_tuple(PyObject *tup)
302302}
303303
304304static int
305- init_co_cached (PyCodeObject * self ) {
306- if (self -> _co_cached == NULL ) {
307- self -> _co_cached = PyMem_New (_PyCoCached , 1 );
308- if (self -> _co_cached == NULL ) {
305+ init_co_cached (PyCodeObject * self )
306+ {
307+ _PyCoCached * cached = FT_ATOMIC_LOAD_PTR (self -> _co_cached );
308+ if (cached != NULL ) {
309+ return 0 ;
310+ }
311+
312+ Py_BEGIN_CRITICAL_SECTION (self );
313+ cached = self -> _co_cached ;
314+ if (cached == NULL ) {
315+ cached = PyMem_New (_PyCoCached , 1 );
316+ if (cached == NULL ) {
309317 PyErr_NoMemory ();
310- return -1 ;
311318 }
312- self -> _co_cached -> _co_code = NULL ;
313- self -> _co_cached -> _co_cellvars = NULL ;
314- self -> _co_cached -> _co_freevars = NULL ;
315- self -> _co_cached -> _co_varnames = NULL ;
319+ else {
320+ cached -> _co_code = NULL ;
321+ cached -> _co_cellvars = NULL ;
322+ cached -> _co_freevars = NULL ;
323+ cached -> _co_varnames = NULL ;
324+ FT_ATOMIC_STORE_PTR (self -> _co_cached , cached );
325+ }
316326 }
317- return 0 ;
318-
327+ Py_END_CRITICAL_SECTION () ;
328+ return cached != NULL ? 0 : -1 ;
319329}
330+
320331/******************
321332 * _PyCode_New()
322333 ******************/
@@ -1571,16 +1582,21 @@ get_cached_locals(PyCodeObject *co, PyObject **cached_field,
15711582{
15721583 assert (cached_field != NULL );
15731584 assert (co -> _co_cached != NULL );
1574- if (* cached_field != NULL ) {
1575- return Py_NewRef (* cached_field );
1585+ PyObject * varnames = FT_ATOMIC_LOAD_PTR (* cached_field );
1586+ if (varnames != NULL ) {
1587+ return Py_NewRef (varnames );
15761588 }
1577- assert (* cached_field == NULL );
1578- PyObject * varnames = get_localsplus_names (co , kind , num );
1589+
1590+ Py_BEGIN_CRITICAL_SECTION (co );
1591+ varnames = * cached_field ;
15791592 if (varnames == NULL ) {
1580- return NULL ;
1593+ varnames = get_localsplus_names (co , kind , num );
1594+ if (varnames != NULL ) {
1595+ FT_ATOMIC_STORE_PTR (* cached_field , varnames );
1596+ }
15811597 }
1582- * cached_field = Py_NewRef ( varnames );
1583- return varnames ;
1598+ Py_END_CRITICAL_SECTION ( );
1599+ return Py_XNewRef ( varnames ) ;
15841600}
15851601
15861602PyObject *
@@ -1674,18 +1690,26 @@ _PyCode_GetCode(PyCodeObject *co)
16741690 if (init_co_cached (co )) {
16751691 return NULL ;
16761692 }
1677- if (co -> _co_cached -> _co_code != NULL ) {
1678- return Py_NewRef (co -> _co_cached -> _co_code );
1693+
1694+ _PyCoCached * cached = co -> _co_cached ;
1695+ PyObject * code = FT_ATOMIC_LOAD_PTR (cached -> _co_code );
1696+ if (code != NULL ) {
1697+ return Py_NewRef (code );
16791698 }
1680- PyObject * code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
1681- _PyCode_NBYTES (co ));
1699+
1700+ Py_BEGIN_CRITICAL_SECTION (co );
1701+ code = cached -> _co_code ;
16821702 if (code == NULL ) {
1683- return NULL ;
1703+ code = PyBytes_FromStringAndSize ((const char * )_PyCode_CODE (co ),
1704+ _PyCode_NBYTES (co ));
1705+ if (code != NULL ) {
1706+ deopt_code (co , (_Py_CODEUNIT * )PyBytes_AS_STRING (code ));
1707+ assert (cached -> _co_code == NULL );
1708+ FT_ATOMIC_STORE_PTR (cached -> _co_code , code );
1709+ }
16841710 }
1685- deopt_code (co , (_Py_CODEUNIT * )PyBytes_AS_STRING (code ));
1686- assert (co -> _co_cached -> _co_code == NULL );
1687- co -> _co_cached -> _co_code = Py_NewRef (code );
1688- return code ;
1711+ Py_END_CRITICAL_SECTION ();
1712+ return Py_XNewRef (code );
16891713}
16901714
16911715PyObject *
0 commit comments