Skip to content

Commit 0706bab

Browse files
gh-128133: use relaxed atomics for hash of bytes (#128412)
1 parent b49c68a commit 0706bab

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

Objects/bytesobject.c

+39-31
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,33 @@ static inline PyObject* bytes_get_empty(void)
5151
}
5252

5353

54+
static inline void
55+
set_ob_shash(PyBytesObject *a, Py_hash_t hash)
56+
{
57+
_Py_COMP_DIAG_PUSH
58+
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
59+
#ifdef Py_GIL_DISABLED
60+
_Py_atomic_store_ssize_relaxed(&a->ob_shash, hash);
61+
#else
62+
a->ob_shash = hash;
63+
#endif
64+
_Py_COMP_DIAG_POP
65+
}
66+
67+
static inline Py_hash_t
68+
get_ob_shash(PyBytesObject *a)
69+
{
70+
_Py_COMP_DIAG_PUSH
71+
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
72+
#ifdef Py_GIL_DISABLED
73+
return _Py_atomic_load_ssize_relaxed(&a->ob_shash);
74+
#else
75+
return a->ob_shash;
76+
#endif
77+
_Py_COMP_DIAG_POP
78+
}
79+
80+
5481
/*
5582
For PyBytes_FromString(), the parameter 'str' points to a null-terminated
5683
string containing exactly 'size' bytes.
@@ -98,10 +125,7 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc)
98125
return PyErr_NoMemory();
99126
}
100127
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
101-
_Py_COMP_DIAG_PUSH
102-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
103-
op->ob_shash = -1;
104-
_Py_COMP_DIAG_POP
128+
set_ob_shash(op, -1);
105129
if (!use_calloc) {
106130
op->ob_sval[size] = '\0';
107131
}
@@ -165,10 +189,7 @@ PyBytes_FromString(const char *str)
165189
return PyErr_NoMemory();
166190
}
167191
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
168-
_Py_COMP_DIAG_PUSH
169-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
170-
op->ob_shash = -1;
171-
_Py_COMP_DIAG_POP
192+
set_ob_shash(op, -1);
172193
memcpy(op->ob_sval, str, size+1);
173194
return (PyObject *) op;
174195
}
@@ -1485,10 +1506,7 @@ bytes_repeat(PyObject *self, Py_ssize_t n)
14851506
return PyErr_NoMemory();
14861507
}
14871508
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
1488-
_Py_COMP_DIAG_PUSH
1489-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
1490-
op->ob_shash = -1;
1491-
_Py_COMP_DIAG_POP
1509+
set_ob_shash(op, -1);
14921510
op->ob_sval[size] = '\0';
14931511

14941512
_PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a));
@@ -1597,14 +1615,13 @@ static Py_hash_t
15971615
bytes_hash(PyObject *self)
15981616
{
15991617
PyBytesObject *a = _PyBytes_CAST(self);
1600-
_Py_COMP_DIAG_PUSH
1601-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
1602-
if (a->ob_shash == -1) {
1618+
Py_hash_t hash = get_ob_shash(a);
1619+
if (hash == -1) {
16031620
/* Can't fail */
1604-
a->ob_shash = Py_HashBuffer(a->ob_sval, Py_SIZE(a));
1621+
hash = Py_HashBuffer(a->ob_sval, Py_SIZE(a));
1622+
set_ob_shash(a, hash);
16051623
}
1606-
return a->ob_shash;
1607-
_Py_COMP_DIAG_POP
1624+
return hash;
16081625
}
16091626

16101627
static PyObject*
@@ -3004,10 +3021,7 @@ bytes_alloc(PyTypeObject *self, Py_ssize_t nitems)
30043021
if (obj == NULL) {
30053022
return NULL;
30063023
}
3007-
_Py_COMP_DIAG_PUSH
3008-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3009-
obj->ob_shash = -1;
3010-
_Py_COMP_DIAG_POP
3024+
set_ob_shash(obj, -1);
30113025
return (PyObject*)obj;
30123026
}
30133027

@@ -3024,11 +3038,8 @@ bytes_subtype_new(PyTypeObject *type, PyObject *tmp)
30243038
if (pnew != NULL) {
30253039
memcpy(PyBytes_AS_STRING(pnew),
30263040
PyBytes_AS_STRING(tmp), n+1);
3027-
_Py_COMP_DIAG_PUSH
3028-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3029-
((PyBytesObject *)pnew)->ob_shash =
3030-
((PyBytesObject *)tmp)->ob_shash;
3031-
_Py_COMP_DIAG_POP
3041+
set_ob_shash((PyBytesObject *)pnew,
3042+
get_ob_shash((PyBytesObject *)tmp));
30323043
}
30333044
return pnew;
30343045
}
@@ -3221,10 +3232,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
32213232
sv = (PyBytesObject *) *pv;
32223233
Py_SET_SIZE(sv, newsize);
32233234
sv->ob_sval[newsize] = '\0';
3224-
_Py_COMP_DIAG_PUSH
3225-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3226-
sv->ob_shash = -1; /* invalidate cached hash value */
3227-
_Py_COMP_DIAG_POP
3235+
set_ob_shash(sv, -1); /* invalidate cached hash value */
32283236
return 0;
32293237
}
32303238

0 commit comments

Comments
 (0)