Skip to content

Commit e4d0303

Browse files
[3.13] pythongh-128133: use relaxed atomics for hash of bytes (pythonGH-128412) (python#130022)
(cherry picked from commit 0706bab) Co-authored-by: Abhijeet <[email protected]>
1 parent ee12a34 commit e4d0303

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

Objects/bytesobject.c

Lines changed: 39 additions & 31 deletions
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
}
@@ -1475,10 +1496,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n)
14751496
return PyErr_NoMemory();
14761497
}
14771498
_PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
1478-
_Py_COMP_DIAG_PUSH
1479-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
1480-
op->ob_shash = -1;
1481-
_Py_COMP_DIAG_POP
1499+
set_ob_shash(op, -1);
14821500
op->ob_sval[size] = '\0';
14831501

14841502
_PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a));
@@ -1583,14 +1601,13 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
15831601
static Py_hash_t
15841602
bytes_hash(PyBytesObject *a)
15851603
{
1586-
_Py_COMP_DIAG_PUSH
1587-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
1588-
if (a->ob_shash == -1) {
1604+
Py_hash_t hash = get_ob_shash(a);
1605+
if (hash == -1) {
15891606
/* Can't fail */
1590-
a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a));
1607+
hash = _Py_HashBytes(a->ob_sval, Py_SIZE(a));
1608+
set_ob_shash(a, hash);
15911609
}
1592-
return a->ob_shash;
1593-
_Py_COMP_DIAG_POP
1610+
return hash;
15941611
}
15951612

15961613
static PyObject*
@@ -2970,10 +2987,7 @@ bytes_alloc(PyTypeObject *self, Py_ssize_t nitems)
29702987
if (obj == NULL) {
29712988
return NULL;
29722989
}
2973-
_Py_COMP_DIAG_PUSH
2974-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
2975-
obj->ob_shash = -1;
2976-
_Py_COMP_DIAG_POP
2990+
set_ob_shash(obj, -1);
29772991
return (PyObject*)obj;
29782992
}
29792993

@@ -2990,11 +3004,8 @@ bytes_subtype_new(PyTypeObject *type, PyObject *tmp)
29903004
if (pnew != NULL) {
29913005
memcpy(PyBytes_AS_STRING(pnew),
29923006
PyBytes_AS_STRING(tmp), n+1);
2993-
_Py_COMP_DIAG_PUSH
2994-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
2995-
((PyBytesObject *)pnew)->ob_shash =
2996-
((PyBytesObject *)tmp)->ob_shash;
2997-
_Py_COMP_DIAG_POP
3007+
set_ob_shash((PyBytesObject *)pnew,
3008+
get_ob_shash((PyBytesObject *)tmp));
29983009
}
29993010
return pnew;
30003011
}
@@ -3186,10 +3197,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
31863197
sv = (PyBytesObject *) *pv;
31873198
Py_SET_SIZE(sv, newsize);
31883199
sv->ob_sval[newsize] = '\0';
3189-
_Py_COMP_DIAG_PUSH
3190-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
3191-
sv->ob_shash = -1; /* invalidate cached hash value */
3192-
_Py_COMP_DIAG_POP
3200+
set_ob_shash(sv, -1); /* invalidate cached hash value */
31933201
return 0;
31943202
}
31953203

0 commit comments

Comments
 (0)