diff options
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 |