mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-115999: Specialize LOAD_ATTR
for instance and class receivers in free-threaded builds (#128164)
Finish specialization for LOAD_ATTR in the free-threaded build by adding support for class and instance receivers.
This commit is contained in:
parent
1c13c56a34
commit
b5ee0258bf
18 changed files with 619 additions and 271 deletions
|
@ -1129,6 +1129,24 @@ dictkeys_generic_lookup(PyDictObject *mp, PyDictKeysObject* dk, PyObject *key, P
|
|||
return do_lookup(mp, dk, key, hash, compare_generic);
|
||||
}
|
||||
|
||||
static bool
|
||||
check_keys_unicode(PyDictKeysObject *dk, PyObject *key)
|
||||
{
|
||||
return PyUnicode_CheckExact(key) && (dk->dk_kind != DICT_KEYS_GENERAL);
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
hash_unicode_key(PyObject *key)
|
||||
{
|
||||
assert(PyUnicode_CheckExact(key));
|
||||
Py_hash_t hash = unicode_get_hash(key);
|
||||
if (hash == -1) {
|
||||
hash = PyUnicode_Type.tp_hash(key);
|
||||
assert(hash != -1);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
static Py_ssize_t
|
||||
unicodekeys_lookup_unicode_threadsafe(PyDictKeysObject* dk, PyObject *key,
|
||||
|
@ -1167,21 +1185,28 @@ unicodekeys_lookup_split(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash)
|
|||
Py_ssize_t
|
||||
_PyDictKeys_StringLookup(PyDictKeysObject* dk, PyObject *key)
|
||||
{
|
||||
DictKeysKind kind = dk->dk_kind;
|
||||
if (!PyUnicode_CheckExact(key) || kind == DICT_KEYS_GENERAL) {
|
||||
if (!check_keys_unicode(dk, key)) {
|
||||
return DKIX_ERROR;
|
||||
}
|
||||
Py_hash_t hash = unicode_get_hash(key);
|
||||
if (hash == -1) {
|
||||
hash = PyUnicode_Type.tp_hash(key);
|
||||
if (hash == -1) {
|
||||
PyErr_Clear();
|
||||
return DKIX_ERROR;
|
||||
}
|
||||
}
|
||||
Py_hash_t hash = hash_unicode_key(key);
|
||||
return unicodekeys_lookup_unicode(dk, key, hash);
|
||||
}
|
||||
|
||||
Py_ssize_t
|
||||
_PyDictKeys_StringLookupAndVersion(PyDictKeysObject *dk, PyObject *key, uint32_t *version)
|
||||
{
|
||||
if (!check_keys_unicode(dk, key)) {
|
||||
return DKIX_ERROR;
|
||||
}
|
||||
Py_ssize_t ix;
|
||||
Py_hash_t hash = hash_unicode_key(key);
|
||||
LOCK_KEYS(dk);
|
||||
ix = unicodekeys_lookup_unicode(dk, key, hash);
|
||||
*version = _PyDictKeys_GetVersionForCurrentState(_PyInterpreterState_GET(), dk);
|
||||
UNLOCK_KEYS(dk);
|
||||
return ix;
|
||||
}
|
||||
|
||||
/* Like _PyDictKeys_StringLookup() but only works on split keys. Note
|
||||
* that in free-threaded builds this locks the keys object as required.
|
||||
*/
|
||||
|
@ -1926,6 +1951,16 @@ build_indices_unicode(PyDictKeysObject *keys, PyDictUnicodeEntry *ep, Py_ssize_t
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_and_clear_inline_values(PyDictValues *values)
|
||||
{
|
||||
assert(values->embedded);
|
||||
FT_ATOMIC_STORE_UINT8(values->valid, 0);
|
||||
for (int i = 0; i < values->capacity; i++) {
|
||||
FT_ATOMIC_STORE_PTR_RELEASE(values->values[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Restructure the table by allocating a new table and reinserting all
|
||||
items again. When entries have been deleted, the new table may
|
||||
|
@ -2017,7 +2052,7 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
|
|||
if (oldvalues->embedded) {
|
||||
assert(oldvalues->embedded == 1);
|
||||
assert(oldvalues->valid == 1);
|
||||
FT_ATOMIC_STORE_UINT8(oldvalues->valid, 0);
|
||||
invalidate_and_clear_inline_values(oldvalues);
|
||||
}
|
||||
else {
|
||||
free_values(oldvalues, IS_DICT_SHARED(mp));
|
||||
|
@ -7007,7 +7042,13 @@ _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name, PyObject **attr
|
|||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyObject *value = _Py_atomic_load_ptr_acquire(&values->values[ix]);
|
||||
if (value == NULL || _Py_TryIncrefCompare(&values->values[ix], value)) {
|
||||
if (value == NULL) {
|
||||
if (FT_ATOMIC_LOAD_UINT8(values->valid)) {
|
||||
*attr = NULL;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (_Py_TryIncrefCompare(&values->values[ix], value)) {
|
||||
*attr = value;
|
||||
return true;
|
||||
}
|
||||
|
@ -7345,7 +7386,7 @@ _PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj)
|
|||
}
|
||||
mp->ma_values = values;
|
||||
|
||||
FT_ATOMIC_STORE_UINT8(_PyObject_InlineValues(obj)->valid, 0);
|
||||
invalidate_and_clear_inline_values(_PyObject_InlineValues(obj));
|
||||
|
||||
assert(_PyObject_InlineValuesConsistencyCheck(obj));
|
||||
ASSERT_CONSISTENT(mp);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue