@@ -302,21 +302,32 @@ validate_and_copy_tuple(PyObject *tup)
302
302
}
303
303
304
304
static 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 ) {
309
317
PyErr_NoMemory ();
310
- return -1 ;
311
318
}
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
+ }
316
326
}
317
- return 0 ;
318
-
327
+ Py_END_CRITICAL_SECTION () ;
328
+ return cached != NULL ? 0 : -1 ;
319
329
}
330
+
320
331
/******************
321
332
* _PyCode_New()
322
333
******************/
@@ -1571,16 +1582,21 @@ get_cached_locals(PyCodeObject *co, PyObject **cached_field,
1571
1582
{
1572
1583
assert (cached_field != NULL );
1573
1584
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 );
1576
1588
}
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 ;
1579
1592
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
+ }
1581
1597
}
1582
- * cached_field = Py_NewRef ( varnames );
1583
- return varnames ;
1598
+ Py_END_CRITICAL_SECTION ( );
1599
+ return Py_XNewRef ( varnames ) ;
1584
1600
}
1585
1601
1586
1602
PyObject *
@@ -1674,18 +1690,26 @@ _PyCode_GetCode(PyCodeObject *co)
1674
1690
if (init_co_cached (co )) {
1675
1691
return NULL ;
1676
1692
}
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 );
1679
1698
}
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 ;
1682
1702
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
+ }
1684
1710
}
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 );
1689
1713
}
1690
1714
1691
1715
PyObject *
0 commit comments