|
3 | 3 | #include "opcode.h" |
4 | 4 |
|
5 | 5 | #include "pycore_code.h" |
| 6 | +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION |
6 | 7 | #include "pycore_descrobject.h" // _PyMethodWrapper_Type |
7 | 8 | #include "pycore_dict.h" // DICT_KEYS_UNICODE |
8 | 9 | #include "pycore_function.h" // _PyFunction_GetVersionForCurrentState() |
@@ -600,17 +601,11 @@ static uint32_t function_get_version(PyObject *o, int opcode); |
600 | 601 | static uint32_t type_get_version(PyTypeObject *t, int opcode); |
601 | 602 |
|
602 | 603 | 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 | +{ |
606 | 608 | _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 | | - } |
614 | 609 | if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { |
615 | 610 | SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); |
616 | 611 | return -1; |
@@ -642,6 +637,23 @@ specialize_module_load_attr( |
642 | 637 | return 0; |
643 | 638 | } |
644 | 639 |
|
| 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 | +} |
645 | 657 |
|
646 | 658 |
|
647 | 659 | /* Attribute specialization */ |
@@ -832,22 +844,33 @@ specialize_dict_access( |
832 | 844 | return 0; |
833 | 845 | } |
834 | 846 | // We found an instance with a __dict__. |
| 847 | + int res; |
| 848 | + Py_BEGIN_CRITICAL_SECTION(dict); |
| 849 | + |
835 | 850 | if (dict->ma_values) { |
836 | 851 | SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); |
837 | | - return 0; |
| 852 | + res = 0; |
| 853 | + goto exit; |
838 | 854 | } |
| 855 | + |
839 | 856 | Py_ssize_t index = |
840 | 857 | _PyDict_LookupIndex(dict, name); |
841 | 858 | if (index != (uint16_t)index) { |
842 | 859 | SPECIALIZATION_FAIL(base_op, |
843 | 860 | index == DKIX_EMPTY ? |
844 | 861 | SPEC_FAIL_ATTR_NOT_IN_DICT : |
845 | 862 | SPEC_FAIL_OUT_OF_RANGE); |
846 | | - return 0; |
| 863 | + res = 0; |
| 864 | + goto exit; |
847 | 865 | } |
848 | 866 | cache->index = (uint16_t)index; |
849 | 867 | write_u32(cache->version, type->tp_version_tag); |
850 | 868 | instr->op.code = hint_op; |
| 869 | + |
| 870 | + res = 1; |
| 871 | +exit: |
| 872 | + Py_END_CRITICAL_SECTION(); |
| 873 | + return res; |
851 | 874 | } |
852 | 875 | return 1; |
853 | 876 | } |
|
0 commit comments