Skip to content

Commit dc19c16

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

File tree

1 file changed

+35
-12
lines changed

1 file changed

+35
-12
lines changed

Python/specialize.c

Lines changed: 35 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 */
@@ -832,22 +844,33 @@ specialize_dict_access(
832844
return 0;
833845
}
834846
// We found an instance with a __dict__.
847+
int res;
848+
Py_BEGIN_CRITICAL_SECTION(dict);
849+
835850
if (dict->ma_values) {
836851
SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
837-
return 0;
852+
res = 0;
853+
goto exit;
838854
}
855+
839856
Py_ssize_t index =
840857
_PyDict_LookupIndex(dict, name);
841858
if (index != (uint16_t)index) {
842859
SPECIALIZATION_FAIL(base_op,
843860
index == DKIX_EMPTY ?
844861
SPEC_FAIL_ATTR_NOT_IN_DICT :
845862
SPEC_FAIL_OUT_OF_RANGE);
846-
return 0;
863+
res = 0;
864+
goto exit;
847865
}
848866
cache->index = (uint16_t)index;
849867
write_u32(cache->version, type->tp_version_tag);
850868
instr->op.code = hint_op;
869+
870+
res = 1;
871+
exit:
872+
Py_END_CRITICAL_SECTION();
873+
return res;
851874
}
852875
return 1;
853876
}

0 commit comments

Comments
 (0)