|
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 */
|
@@ -836,18 +848,34 @@ specialize_dict_access(
|
836 | 848 | SPECIALIZATION_FAIL(base_op, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT);
|
837 | 849 | return 0;
|
838 | 850 | }
|
| 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 | + |
839 | 861 | Py_ssize_t index =
|
840 | 862 | _PyDict_LookupIndex(dict, name);
|
841 | 863 | if (index != (uint16_t)index) {
|
842 | 864 | SPECIALIZATION_FAIL(base_op,
|
843 | 865 | index == DKIX_EMPTY ?
|
844 | 866 | SPEC_FAIL_ATTR_NOT_IN_DICT :
|
845 | 867 | SPEC_FAIL_OUT_OF_RANGE);
|
846 |
| - return 0; |
| 868 | + res = 0; |
| 869 | + goto exit; |
847 | 870 | }
|
848 | 871 | cache->index = (uint16_t)index;
|
849 |
| - write_u32(cache->version, type->tp_version_tag); |
| 872 | + write_u32(cache->version, version); |
850 | 873 | instr->op.code = hint_op;
|
| 874 | + |
| 875 | + res = 1; |
| 876 | +exit: |
| 877 | + Py_END_CRITICAL_SECTION(); |
| 878 | + return res; |
851 | 879 | }
|
852 | 880 | return 1;
|
853 | 881 | }
|
|
0 commit comments