8000 Lock dict when specializing module lookup · python/cpython@a857147 · GitHub
[go: up one dir, main page]

Skip to content

Commit a857147

Browse files
committed
Lock dict when specializing module lookup
1 parent dc4cd2c commit a857147

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

Python/specialize.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "opcode.h"
44

55
#include "pycore_code.h"
6+
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
67
#include "pycore_descrobject.h" // _PyMethodWrapper_Type
78
#include "pycore_dict.h" // DICT_KEYS_UNICODE
89
#include "pycore_function.h" // _PyFunction_GetVersionForCurrentState()
@@ -600,17 +601,11 @@ static uint32_t function_get_version(PyObject *o, int opcode);
600601
static uint32_t type_get_version(PyTypeObject *t, int opcode);
601602

602603
static int
603-
specialize_module_load_attr(
604-
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name
605-
) {
604+
specialize_module_load_attr_lock_held(
605+
PyDictObject *dict, _Py_CODEUNIT *instr, PyObject *name
606+
)
607+
{
606608
_PyAttrCache *cache = (_PyAttrCache *)(instr + 1);
607-
PyModuleObject *m = (PyModuleObject *)owner;
608-
assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
609-
PyDictObject *dict = (PyDictObject *)m->md_dict;
610-
if (dict == NULL) {
611-
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT);
612-
return -1;
613-
}
614609
if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) {
615610
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
616611
return -1;
@@ -642,6 +637,23 @@ specialize_module_load_attr(
642637
return 0;
643638
}
644639

640+
static int
641+
specialize_module_load_attr(
642+
PyObject *owner, _Py_CODEUNIT *instr, PyObject *name
643+
) {
644+
PyModuleObject *m = (PyModuleObject *)owner;
645+
assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0);
646+
PyDictObject *dict = (PyDictObject *)m->md_dict;
647+
if (dict == NULL) {
648+
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT);
649+
return -1;
650+
}
651+
int res;
652+
Py_BEGIN_CRITICAL_SECTION(dict);
653+
res = specialize_module_load_attr_lock_held(dict, instr, name);
654+
Py_END_CRITICAL_SECTION();
655+
return res;
656+
}
645657

646658

647659
/* Attribute specialization */
@@ -836,18 +848,34 @@ specialize_dict_access(
836848
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
837849
return 0;
838850
}
851+
852+
#ifdef Py_GIL_DISABLED
853+
unsigned int version = _Py_atomic_load_uint(&type->tp_version_tag);
854+
#else
855+
unsigned int version = dict->ma_version_tag;
856+
#endif
857+
858+
int res;
859+
Py_BEGIN_CRITICAL_SECTION(dict);
860+
839861
Py_ssize_t index =
840862
_PyDict_LookupIndex(dict, name);
841863
if (index != (uint16_t)index) {
842864
SPECIALIZATION_FAIL(base_op,
843865
index == DKIX_EMPTY ?
844866
SPEC_FAIL_ATTR_NOT_IN_DICT :
845867
SPEC_FAIL_OUT_OF_RANGE);
846-
return 0;
868+
res = 0;
869+
goto exit;
847870
}
848871
cache->index = (uint16_t)index;
849-
write_u32(cache->version, type->tp_version_tag);
872+
write_u32(cache->version, version);
850873
instr->op.code = hint_op;
874+
875+
res = 1;
876+
exit:
877+
Py_END_CRITICAL_SECTION();
878+
return res;
851879
}
852880
return 1;
853881
}

0 commit comments

Comments
 (0)
0