Skip to content

Commit ba19770

Browse files
Partially address review
Co-Authored-By: Sam Gross <[email protected]>
1 parent c3448d9 commit ba19770

File tree

5 files changed

+35
-23
lines changed

5 files changed

+35
-23
lines changed

Include/internal/pycore_dict.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ PyAPI_FUNC(int) _PyDict_SetItem_KnownHash_LockHeld(PyDictObject *mp, PyObject *k
121121
PyAPI_FUNC(int) _PyDict_GetItemRef_KnownHash_LockHeld(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result);
122122
extern int _PyDict_GetItemRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, PyObject **result);
123123
extern int _PyDict_GetItemRef_Unicode_LockHeld(PyDictObject *op, PyObject *key, PyObject **result);
124-
extern int _PyDict_GetItem_KnownHash_StackRef(PyDictObject *op, PyObject *key, Py_hash_t hash, _PyStackRef *result);
124+
extern int _PyDict_GetItemStackRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, _PyStackRef *result);
125125
extern int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr, PyObject *name, PyObject *value);
126126
extern int _PyDict_GetItemStackRef(PyObject *op, PyObject *key, _PyStackRef *result);
127127

Include/internal/pycore_object.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,24 @@ _Py_TryXGetRef(PyObject **ptr)
623623
return NULL;
624624
}
625625

626+
// This belongs here rather than pycore_stackref.h because including pycore_object.h
627+
// there causes a circular include.
628+
static inline _PyStackRef
629+
_Py_TryXGetStackRef(PyObject **ptr)
630+
{
631+
PyObject *value = _Py_atomic_load_ptr(ptr);
632+
if (value == NULL) {
633+
return PyStackRef_NULL;
634+
}
635+
if (_Py_IsImmortal(value) || _PyObject_HasDeferredRefcount(value)) {
636+
return (_PyStackRef){ .bits = (uintptr_t)value | Py_TAG_DEFERRED };
637+
}
638+
if (_Py_TryIncrefCompare(ptr, value)) {
639+
return PyStackRef_FromPyObjectSteal(value);
640+
}
641+
return PyStackRef_NULL;
642+
}
643+
626644
/* Like Py_NewRef but also optimistically sets _Py_REF_MAYBE_WEAKREF
627645
on objects owned by a different thread. */
628646
static inline PyObject *

Objects/dictobject.c

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,7 +2337,7 @@ _PyDict_GetItemRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, Py
23372337
}
23382338

23392339
int
2340-
_PyDict_GetItem_KnownHash_StackRef(PyDictObject *op, PyObject *key, Py_hash_t hash, _PyStackRef *result)
2340+
_PyDict_GetItemStackRef_KnownHash(PyDictObject *op, PyObject *key, Py_hash_t hash, _PyStackRef *result)
23412341
{
23422342
Py_ssize_t ix = _Py_dict_lookup_threadsafe_stackref(op, key, hash, result);
23432343
assert(ix >= 0 || PyStackRef_IsNull(*result));
@@ -2384,7 +2384,7 @@ _PyDict_GetItemStackRef(PyObject *op, PyObject *key, _PyStackRef *result)
23842384
return -1;
23852385
}
23862386

2387-
return _PyDict_GetItem_KnownHash_StackRef((PyDictObject *)op, key, hash, result);
2387+
return _PyDict_GetItemStackRef_KnownHash((PyDictObject *)op, key, hash, result);
23882388
}
23892389

23902390
int
@@ -7148,14 +7148,8 @@ _PyObject_TryGetInstanceAttributeStackRef(PyObject *obj, PyObject *name, _PyStac
71487148
}
71497149

71507150
#ifdef Py_GIL_DISABLED
7151-
PyObject *value = _Py_atomic_load_ptr_acquire(&values->values[ix]);
7152-
if (value == NULL) {
7153-
*attr = PyStackRef_NULL;
7154-
}
7155-
else {
7156-
*attr = PyStackRef_FromPyObjectNew(value);
7157-
}
7158-
if (value == _Py_atomic_load_ptr_acquire(&values->values[ix])) {
7151+
*attr = _Py_TryXGetStackRef(&values->values[ix]);
7152+
if (PyStackRef_AsPyObjectBorrow(*attr) == _Py_atomic_load_ptr_acquire(&values->values[ix])) {
71597153
return true;
71607154
}
71617155

@@ -7170,13 +7164,7 @@ _PyObject_TryGetInstanceAttributeStackRef(PyObject *obj, PyObject *name, _PyStac
71707164
if (dict == NULL) {
71717165
// Still no dict, we can read from the values
71727166
assert(values->valid);
7173-
value = values->values[ix];
7174-
if (value != NULL) {
7175-
*attr = PyStackRef_FromPyObjectNew(value);
7176-
}
7177-
else {
7178-
*attr = PyStackRef_NULL;
7179-
}
7167+
*attr = _Py_TryXGetStackRef(&values->values[ix]);
71807168
success = true;
71817169
}
71827170

@@ -7195,8 +7183,7 @@ _PyObject_TryGetInstanceAttributeStackRef(PyObject *obj, PyObject *name, _PyStac
71957183
Py_BEGIN_CRITICAL_SECTION(dict);
71967184

71977185
if (dict->ma_values == values && FT_ATOMIC_LOAD_UINT8(values->valid)) {
7198-
value = _Py_atomic_load_ptr_relaxed(&values->values[ix]);
7199-
*attr = PyStackRef_FromPyObjectNew(value);
7186+
*attr = _Py_TryXGetStackRef(&values->values[ix]);
72007187
success = true;
72017188
} else {
72027189
// Caller needs to lookup from the dictionary

Objects/object.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,13 @@ _PyObject_GetMethodStackRef(PyObject *obj, PyObject *name, _PyStackRef *method)
16361636
}
16371637

16381638
if (tp->tp_getattro != PyObject_GenericGetAttr || !PyUnicode_CheckExact(name)) {
1639-
*method = PyStackRef_FromPyObjectSteal(PyObject_GetAttr(obj, name));
1639+
PyObject *attr_o = PyObject_GetAttr(obj, name);
1640+
if (attr_o != NULL) {
1641+
*method = PyStackRef_FromPyObjectSteal(attr_o);
1642+
}
1643+
else {
1644+
*method = PyStackRef_NULL;
1645+
}
16401646
return 0;
16411647
}
16421648

Objects/typeobject.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5489,11 +5489,12 @@ find_name_in_mro_stackref(PyTypeObject *type, PyObject *name, int *error, _PySta
54895489
PyObject *base = PyTuple_GET_ITEM(mro, i);
54905490
PyObject *dict = lookup_tp_dict(_PyType_CAST(base));
54915491
assert(dict && PyDict_Check(dict));
5492-
if (_PyDict_GetItem_KnownHash_StackRef((PyDictObject *)dict, name, hash, result) < 0) {
5492+
int code = _PyDict_GetItemStackRef_KnownHash((PyDictObject *)dict, name, hash, result);
5493+
if (code < 0) {
54935494
*error = -1;
54945495
goto done;
54955496
}
5496-
if (!PyStackRef_IsNull(*result)) {
5497+
if (code == 1) {
54975498
break;
54985499
}
54995500
}

0 commit comments

Comments
 (0)