diff options
author | Michael Droettboom <mdboom@gmail.com> | 2025-03-27 09:57:06 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-27 09:57:06 -0400 |
commit | 8614f86b7163b1c39798b481902dbb511292a537 (patch) | |
tree | 2bf6a46b432df3d6bf01a4176f3a614a01c48566 /Include/internal/pycore_tuple.h | |
parent | cf5e438c0297954c4411c1c3ae4ba67a48b134ea (diff) | |
download | cpython-8614f86b7163b1c39798b481902dbb511292a537.tar.gz cpython-8614f86b7163b1c39798b481902dbb511292a537.zip |
gh-131525: Cache the result of tuple_hash (#131529)
* gh-131525: Cache the result of tuple_hash
* Fix debug builds
* Add blurb
* Fix formatting
* Pre-compute empty tuple singleton
* Mostly set the cache within tuple_alloc
* Fixes for TSAN
* Pre-compute empty tuple singleton
* Fix for 32-bit platforms
* Assert that op != NULL in _PyTuple_RESET_HASH_CACHE
* Use FT_ATOMIC_STORE_SSIZE_RELAXED macro
* Update Include/internal/pycore_tuple.h
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
* Fix alignment
* atomic load
* Update Objects/tupleobject.c
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
---------
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
Diffstat (limited to 'Include/internal/pycore_tuple.h')
-rw-r--r-- | Include/internal/pycore_tuple.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index da6754ff7db..acf1bec4602 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -8,6 +8,7 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_object.h" // _PyObject_GC_IS_TRACKED #include "pycore_structs.h" // _PyStackRef extern void _PyTuple_MaybeUntrack(PyObject *); @@ -32,6 +33,42 @@ typedef struct { PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ } _PyTupleIterObject; +#define _PyTuple_RESET_HASH_CACHE(op) \ + do { \ + assert(op != NULL); \ + _PyTuple_CAST(op)->ob_hash = -1; \ + } while (0) + +/* bpo-42536: If reusing a tuple object, this should be called to re-track it + with the garbage collector and reset its hash cache. */ +static inline void +_PyTuple_Recycle(PyObject *op) +{ + _PyTuple_RESET_HASH_CACHE(op); + if (!_PyObject_GC_IS_TRACKED(op)) { + _PyObject_GC_TRACK(op); + } +} + +/* Below are the official constants from the xxHash specification. Optimizing + compilers should emit a single "rotate" instruction for the + _PyTuple_HASH_XXROTATE() expansion. If that doesn't happen for some important + platform, the macro could be changed to expand to a platform-specific rotate + spelling instead. +*/ +#if SIZEOF_PY_UHASH_T > 4 +#define _PyTuple_HASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) +#define _PyTuple_HASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) +#define _PyTuple_HASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) +#define _PyTuple_HASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ +#else +#define _PyTuple_HASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) +#define _PyTuple_HASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) +#define _PyTuple_HASH_XXPRIME_5 ((Py_uhash_t)374761393UL) +#define _PyTuple_HASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ +#endif +#define _PyTuple_HASH_EMPTY (_PyTuple_HASH_XXPRIME_5 + (_PyTuple_HASH_XXPRIME_5 ^ 3527539UL)) + #ifdef __cplusplus } #endif |