summaryrefslogtreecommitdiffstats
path: root/Include/internal
diff options
context:
space:
mode:
authormpage <mpage@meta.com>2024-12-03 19:20:20 (GMT)
committerGitHub <noreply@github.com>2024-12-03 19:20:20 (GMT)
commitdabcecfd6dadb9430733105ba36925b290343d31 (patch)
tree56bd2af5b31dbc182c6cd7c81a33745112871391 /Include/internal
parentfc5a0dc22483a35068888e828c65796d7a792c14 (diff)
downloadcpython-dabcecfd6dadb9430733105ba36925b290343d31.zip
cpython-dabcecfd6dadb9430733105ba36925b290343d31.tar.gz
cpython-dabcecfd6dadb9430733105ba36925b290343d31.tar.bz2
gh-115999: Enable specialization of `CALL` instructions in free-threaded builds (#127123)
The CALL family of instructions were mostly thread-safe already and only required a small number of changes, which are documented below. A few changes were needed to make CALL_ALLOC_AND_ENTER_INIT thread-safe: Added _PyType_LookupRefAndVersion, which returns the type version corresponding to the returned ref. Added _PyType_CacheInitForSpecialization, which takes an init method and the corresponding type version and only populates the specialization cache if the current type version matches the supplied version. This prevents potentially caching a stale value in free-threaded builds if we race with an update to __init__. Only cache __init__ functions that are deferred in free-threaded builds. This ensures that the reference to __init__ that is stored in the specialization cache is valid if the type version guard in _CHECK_AND_ALLOCATE_OBJECT passes. Fix a bug in _CREATE_INIT_FRAME where the frame is pushed to the stack on failure. A few other miscellaneous changes were also needed: Use {LOCK,UNLOCK}_OBJECT in LIST_APPEND. This ensures that the list's per-object lock is held while we are appending to it. Add missing co_tlbc for _Py_InitCleanup. Stop/start the world around setting the eval frame hook. This allows us to read interp->eval_frame non-atomically and preserves the behavior of _CHECK_PEP_523 documented below.
Diffstat (limited to 'Include/internal')
-rw-r--r--Include/internal/pycore_object.h14
1 files changed, 14 insertions, 0 deletions
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index c52ed8f..ce876b0 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -835,6 +835,20 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj,
PyObject *name, PyObject *value);
extern bool _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name,
PyObject **attr);
+extern PyObject *_PyType_LookupRefAndVersion(PyTypeObject *, PyObject *,
+ unsigned int *);
+
+// Cache the provided init method in the specialization cache of type if the
+// provided type version matches the current version of the type.
+//
+// The cached value is borrowed and is only valid if guarded by a type
+// version check. In free-threaded builds the init method must also use
+// deferred reference counting.
+//
+// Returns 1 if the value was cached or 0 otherwise.
+extern int _PyType_CacheInitForSpecialization(PyHeapTypeObject *type,
+ PyObject *init,
+ unsigned int tp_version);
#ifdef Py_GIL_DISABLED
# define MANAGED_DICT_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-1)