gh-117657: Disable the function/code cache in free-threaded builds (#118301)

This is only used by the specializing interpreter and the tier 2
optimizer, both of which are disabled in free-threaded builds.
This commit is contained in:
mpage 2024-05-03 13:21:04 -07:00 committed by GitHub
parent 5248596781
commit 37d0950022
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 1 deletions

View File

@ -4,6 +4,8 @@
extern "C" { extern "C" {
#endif #endif
#include "pycore_lock.h"
#ifndef Py_BUILD_CORE #ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define" # error "this header requires Py_BUILD_CORE define"
#endif #endif
@ -24,6 +26,11 @@ struct _func_version_cache_item {
}; };
struct _py_func_state { struct _py_func_state {
#ifdef Py_GIL_DISABLED
// Protects next_version
PyMutex mutex;
#endif
uint32_t next_version; uint32_t next_version;
// Borrowed references to function and code objects whose // Borrowed references to function and code objects whose
// func_version % FUNC_VERSION_CACHE_SIZE // func_version % FUNC_VERSION_CACHE_SIZE

View File

@ -416,10 +416,16 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con)
co->co_ncellvars = ncellvars; co->co_ncellvars = ncellvars;
co->co_nfreevars = nfreevars; co->co_nfreevars = nfreevars;
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
#ifdef Py_GIL_DISABLED
PyMutex_Lock(&interp->func_state.mutex);
#endif
co->co_version = interp->func_state.next_version; co->co_version = interp->func_state.next_version;
if (interp->func_state.next_version != 0) { if (interp->func_state.next_version != 0) {
interp->func_state.next_version++; interp->func_state.next_version++;
} }
#ifdef Py_GIL_DISABLED
PyMutex_Unlock(&interp->func_state.mutex);
#endif
co->_co_monitoring = NULL; co->_co_monitoring = NULL;
co->_co_instrumentation_version = 0; co->_co_instrumentation_version = 0;
/* not set */ /* not set */

View File

@ -287,6 +287,7 @@ functions is running.
void void
_PyFunction_SetVersion(PyFunctionObject *func, uint32_t version) _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version)
{ {
#ifndef Py_GIL_DISABLED
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
if (func->func_version != 0) { if (func->func_version != 0) {
struct _func_version_cache_item *slot = struct _func_version_cache_item *slot =
@ -297,7 +298,9 @@ _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version)
// Leave slot->code alone, there may be use for it. // Leave slot->code alone, there may be use for it.
} }
} }
#endif
func->func_version = version; func->func_version = version;
#ifndef Py_GIL_DISABLED
if (version != 0) { if (version != 0) {
struct _func_version_cache_item *slot = struct _func_version_cache_item *slot =
interp->func_state.func_version_cache interp->func_state.func_version_cache
@ -305,11 +308,13 @@ _PyFunction_SetVersion(PyFunctionObject *func, uint32_t version)
slot->func = func; slot->func = func;
slot->code = func->func_code; slot->code = func->func_code;
} }
#endif
} }
void void
_PyFunction_ClearCodeByVersion(uint32_t version) _PyFunction_ClearCodeByVersion(uint32_t version)
{ {
#ifndef Py_GIL_DISABLED
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
struct _func_version_cache_item *slot = struct _func_version_cache_item *slot =
interp->func_state.func_version_cache interp->func_state.func_version_cache
@ -322,11 +327,15 @@ _PyFunction_ClearCodeByVersion(uint32_t version)
slot->func = NULL; slot->func = NULL;
} }
} }
#endif
} }
PyFunctionObject * PyFunctionObject *
_PyFunction_LookupByVersion(uint32_t version, PyObject **p_code) _PyFunction_LookupByVersion(uint32_t version, PyObject **p_code)
{ {
#ifdef Py_GIL_DISABLED
return NULL;
#else
PyInterpreterState *interp = _PyInterpreterState_GET(); PyInterpreterState *interp = _PyInterpreterState_GET();
struct _func_version_cache_item *slot = struct _func_version_cache_item *slot =
interp->func_state.func_version_cache interp->func_state.func_version_cache
@ -346,6 +355,7 @@ _PyFunction_LookupByVersion(uint32_t version, PyObject **p_code)
return slot->func; return slot->func;
} }
return NULL; return NULL;
#endif
} }
uint32_t uint32_t

View File

@ -15,7 +15,6 @@ race:_add_to_weak_set
race:_in_weak_set race:_in_weak_set
race:_mi_heap_delayed_free_partial race:_mi_heap_delayed_free_partial
race:_PyEval_EvalFrameDefault race:_PyEval_EvalFrameDefault
race:_PyFunction_SetVersion
race:_PyImport_AcquireLock race:_PyImport_AcquireLock
race:_PyImport_ReleaseLock race:_PyImport_ReleaseLock
race:_PyInterpreterState_SetNotRunningMain race:_PyInterpreterState_SetNotRunningMain