Skip to content
44 changes: 34 additions & 10 deletions Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "pycore_object.h" // _PyObject_GC_TRACK
#include "pycore_pymem.h" // PYMEM_CLEANBYTE
#include "pycore_strhex.h" // _Py_strhex_with_sep()
#include "pycore_pyatomic_ft_wrappers.h"

#include <stddef.h>

Expand Down Expand Up @@ -51,6 +52,27 @@
}


static inline void
set_ob_shash(PyBytesObject *a, Py_hash_t hash)
{
#ifdef Py_GIL_DISABLED
_Py_atomic_store_int_relaxed((int *)&a->ob_shash, (int)hash);
#else
a->ob_shash = hash;

Check warning on line 61 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Address sanitizer (ubuntu-24.04)

‘ob_shash’ is deprecated [-Wdeprecated-declarations]

Check warning on line 61 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Hypothesis tests on Ubuntu

‘ob_shash’ is deprecated [-Wdeprecated-declarations]

Check warning on line 61 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu / build and test (ubuntu-24.04)

‘ob_shash’ is deprecated [-Wdeprecated-declarations]
#endif
}

static inline Py_hash_t
get_ob_shash(PyBytesObject *a)
{
#ifdef Py_GIL_DISABLED
return (Py_hash_t)_Py_atomic_load_int_relaxed((int *)&a->ob_shash);
#else
return a->ob_shash;

Check warning on line 71 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Address sanitizer (ubuntu-24.04)

‘ob_shash’ is deprecated [-Wdeprecated-declarations]

Check warning on line 71 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Hypothesis tests on Ubuntu

‘ob_shash’ is deprecated [-Wdeprecated-declarations]

Check warning on line 71 in Objects/bytesobject.c

View workflow job for this annotation

GitHub Actions / Ubuntu / build and test (ubuntu-24.04)

‘ob_shash’ is deprecated [-Wdeprecated-declarations]
#endif
}


/*
For PyBytes_FromString(), the parameter 'str' points to a null-terminated
string containing exactly 'size' bytes.
Expand Down Expand Up @@ -100,7 +122,7 @@
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
op->ob_shash = -1;
set_ob_shash(op, -1);
_Py_COMP_DIAG_POP
if (!use_calloc) {
op->ob_sval[size] = '\0';
Expand Down Expand Up @@ -167,7 +189,7 @@
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
op->ob_shash = -1;
set_ob_shash(op, -1);
_Py_COMP_DIAG_POP
memcpy(op->ob_sval, str, size+1);
return (PyObject *) op;
Expand Down Expand Up @@ -1487,7 +1509,7 @@
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
op->ob_shash = -1;
set_ob_shash(op, -1);
_Py_COMP_DIAG_POP
op->ob_sval[size] = '\0';

Expand Down Expand Up @@ -1599,11 +1621,13 @@
PyBytesObject *a = _PyBytes_CAST(self);
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
if (a->ob_shash == -1) {
Py_hash_t hash = get_ob_shash(a);
if (hash == -1) {
/* Can't fail */
a->ob_shash = Py_HashBuffer(a->ob_sval, Py_SIZE(a));
hash = Py_HashBuffer(a->ob_sval, Py_SIZE(a));
set_ob_shash(a, hash);
}
return a->ob_shash;
return hash;
_Py_COMP_DIAG_POP
}

Expand Down Expand Up @@ -3006,7 +3030,7 @@
}
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
obj->ob_shash = -1;
set_ob_shash(obj, -1);
_Py_COMP_DIAG_POP
return (PyObject*)obj;
}
Expand All @@ -3026,8 +3050,8 @@
PyBytes_AS_STRING(tmp), n+1);
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
((PyBytesObject *)pnew)->ob_shash =
((PyBytesObject *)tmp)->ob_shash;
set_ob_shash((PyBytesObject *)pnew,
get_ob_shash((PyBytesObject *)tmp));
_Py_COMP_DIAG_POP
}
return pnew;
Expand Down Expand Up @@ -3223,7 +3247,7 @@
sv->ob_sval[newsize] = '\0';
_Py_COMP_DIAG_PUSH
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
sv->ob_shash = -1; /* invalidate cached hash value */
set_ob_shash(sv, -1); /* invalidate cached hash value */
_Py_COMP_DIAG_POP
return 0;
}
Expand Down
Loading