@@ -304,21 +304,32 @@ validate_and_copy_tuple(PyObject *tup)
304
304
}
305
305
306
306
static 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 ) {
311
319
PyErr_NoMemory ();
312
- return -1 ;
313
320
}
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
+ }
318
328
}
319
- return 0 ;
320
-
329
+ Py_END_CRITICAL_SECTION () ;
330
+ return cached != NULL ? 0 : -1 ;
321
331
}
332
+
322
333
/******************
323
334
* _PyCode_New()
324
335
******************/
@@ -1544,16 +1555,21 @@ get_cached_locals(PyCodeObject *co, PyObject **cached_field,
1544
1555
{
1545
1556
assert (cached_field != NULL );
1546
1557
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 );
1549
1561
}
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 ;
1552
1565
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
+ }
1554
1570
}
1555
- * cached_field = Py_NewRef ( varnames );
1556
- return varnames ;
1571
+ Py_END_CRITICAL_SECTION ( );
1572
+ return Py_XNewRef ( varnames ) ;
1557
1573
}
1558
1574
1559
1575
PyObject *
@@ -1652,18 +1668,26 @@ _PyCode_GetCode(PyCodeObject *co)
1652
1668
if (init_co_cached (co )) {
1653
1669
return NULL ;
1654
1670
}
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 );
1657
1676
}
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 ;
1660
1680
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
+ }
1662
1688
}
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 );
1667
1691
}
1668
1692
1669
1693
PyObject *
0 commit comments