Py_hash_t hash,
PyObject **result);
+#ifdef Py_GIL_DISABLED
+PyAPI_FUNC(void) _PyDict_EnsureSharedOnRead(PyDictObject *mp);
+#endif
+
#define DKIX_EMPTY (-1)
#define DKIX_DUMMY (-2) /* Used internally */
#define DKIX_ERROR (-3)
Py_END_CRITICAL_SECTION();
}
}
+
+void
+_PyDict_EnsureSharedOnRead(PyDictObject *mp)
+{
+ ensure_shared_on_read(mp);
+}
#endif
static inline void
assert(Py_TYPE(owner_o)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
PyDictObject *dict = _PyObject_GetManagedDict(owner_o);
DEOPT_IF(dict == NULL);
+ PyDictKeysObject *dk = FT_ATOMIC_LOAD_PTR(dict->ma_keys);
assert(PyDict_CheckExact((PyObject *)dict));
+#ifdef Py_GIL_DISABLED
+ DEOPT_IF(!_Py_IsOwnedByCurrentThread((PyObject *)dict) && !_PyObject_GC_IS_SHARED(dict));
+#endif
PyObject *attr_o;
- if (!LOCK_OBJECT(dict)) {
+ if (hint >= (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_nentries)) {
DEOPT_IF(true);
}
- if (hint >= (size_t)dict->ma_keys->dk_nentries) {
- UNLOCK_OBJECT(dict);
- DEOPT_IF(true);
- }
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
- UNLOCK_OBJECT(dict);
+ if (dk->dk_kind != DICT_KEYS_UNICODE) {
DEOPT_IF(true);
}
- PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
- if (ep->me_key != name) {
- UNLOCK_OBJECT(dict);
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + hint;
+ if (FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_key) != name) {
DEOPT_IF(true);
}
- attr_o = ep->me_value;
+ attr_o = FT_ATOMIC_LOAD_PTR(ep->me_value);
if (attr_o == NULL) {
- UNLOCK_OBJECT(dict);
DEOPT_IF(true);
}
STAT_INC(LOAD_ATTR, hit);
+#ifdef Py_GIL_DISABLED
+ if (!_Py_TryIncrefCompareStackRef(&ep->me_value, attr_o, &attr)) {
+ DEOPT_IF(true);
+ }
+#else
attr = PyStackRef_FromPyObjectNew(attr_o);
- UNLOCK_OBJECT(dict);
+#endif
PyStackRef_CLOSE(owner);
}
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
+ PyDictKeysObject *dk = FT_ATOMIC_LOAD_PTR(dict->ma_keys);
assert(PyDict_CheckExact((PyObject *)dict));
+ #ifdef Py_GIL_DISABLED
+ if (!_Py_IsOwnedByCurrentThread((PyObject *)dict) && !_PyObject_GC_IS_SHARED(dict)) {
+ UOP_STAT_INC(uopcode, miss);
+ JUMP_TO_JUMP_TARGET();
+ }
+ #endif
PyObject *attr_o;
- if (!LOCK_OBJECT(dict)) {
+ if (hint >= (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_nentries)) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
- if (hint >= (size_t)dict->ma_keys->dk_nentries) {
- UNLOCK_OBJECT(dict);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ if (dk->dk_kind != DICT_KEYS_UNICODE) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
- UNLOCK_OBJECT(dict);
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + hint;
+ if (FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_key) != name) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
- PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
- if (ep->me_key != name) {
- UNLOCK_OBJECT(dict);
+ attr_o = FT_ATOMIC_LOAD_PTR(ep->me_value);
+ if (attr_o == NULL) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
- attr_o = ep->me_value;
- if (attr_o == NULL) {
- UNLOCK_OBJECT(dict);
+ STAT_INC(LOAD_ATTR, hit);
+ #ifdef Py_GIL_DISABLED
+ if (!_Py_TryIncrefCompareStackRef(&ep->me_value, attr_o, &attr)) {
if (true) {
UOP_STAT_INC(uopcode, miss);
JUMP_TO_JUMP_TARGET();
}
}
- STAT_INC(LOAD_ATTR, hit);
+ #else
attr = PyStackRef_FromPyObjectNew(attr_o);
- UNLOCK_OBJECT(dict);
+ #endif
stack_pointer[-1] = attr;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(owner);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
+ PyDictKeysObject *dk = FT_ATOMIC_LOAD_PTR(dict->ma_keys);
assert(PyDict_CheckExact((PyObject *)dict));
+ #ifdef Py_GIL_DISABLED
+ if (!_Py_IsOwnedByCurrentThread((PyObject *)dict) && !_PyObject_GC_IS_SHARED(dict)) {
+ UPDATE_MISS_STATS(LOAD_ATTR);
+ assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
+ JUMP_TO_PREDICTED(LOAD_ATTR);
+ }
+ #endif
PyObject *attr_o;
- if (!LOCK_OBJECT(dict)) {
+ if (hint >= (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(dk->dk_nentries)) {
if (true) {
UPDATE_MISS_STATS(LOAD_ATTR);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
}
- if (hint >= (size_t)dict->ma_keys->dk_nentries) {
- UNLOCK_OBJECT(dict);
+ PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
+ if (dk->dk_kind != DICT_KEYS_UNICODE) {
if (true) {
UPDATE_MISS_STATS(LOAD_ATTR);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
}
- PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
- if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
- UNLOCK_OBJECT(dict);
+ PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dk) + hint;
+ if (FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_key) != name) {
if (true) {
UPDATE_MISS_STATS(LOAD_ATTR);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
}
- PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint;
- if (ep->me_key != name) {
- UNLOCK_OBJECT(dict);
+ attr_o = FT_ATOMIC_LOAD_PTR(ep->me_value);
+ if (attr_o == NULL) {
if (true) {
UPDATE_MISS_STATS(LOAD_ATTR);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
}
- attr_o = ep->me_value;
- if (attr_o == NULL) {
- UNLOCK_OBJECT(dict);
+ STAT_INC(LOAD_ATTR, hit);
+ #ifdef Py_GIL_DISABLED
+ if (!_Py_TryIncrefCompareStackRef(&ep->me_value, attr_o, &attr)) {
if (true) {
UPDATE_MISS_STATS(LOAD_ATTR);
assert(_PyOpcode_Deopt[opcode] == (LOAD_ATTR));
JUMP_TO_PREDICTED(LOAD_ATTR);
}
}
- STAT_INC(LOAD_ATTR, hit);
+ #else
attr = PyStackRef_FromPyObjectNew(attr_o);
- UNLOCK_OBJECT(dict);
+ #endif
stack_pointer[-1] = attr;
_PyFrame_SetStackPointer(frame, stack_pointer);
PyStackRef_CLOSE(owner);
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
_Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(dict);
+#ifdef Py_GIL_DISABLED
+ _PyDict_EnsureSharedOnRead(dict);
+#endif
// We found an instance with a __dict__.
if (_PyDict_HasSplitTable(dict)) {