@@ -1075,9 +1075,7 @@ specialize_attr_loadclassattr(PyObject *owner, _Py_CODEUNIT *instr,
10751075 unsigned int tp_version ,
10761076 DescriptorClassification kind , bool is_method ,
10771077 uint32_t shared_keys_version );
1078- #ifndef Py_GIL_DISABLED
10791078static int specialize_class_load_attr (PyObject * owner , _Py_CODEUNIT * instr , PyObject * name );
1080- #endif
10811079
10821080/* Returns true if instances of obj's class are
10831081 * likely to have `name` in their __dict__.
@@ -1334,12 +1332,7 @@ _Py_Specialize_LoadAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *nam
13341332 fail = specialize_module_load_attr (owner , instr , name );
13351333 }
13361334 else if (PyType_Check (owner )) {
1337- #ifdef Py_GIL_DISABLED
1338- SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_EXPECTED_ERROR );
1339- fail = true;
1340- #else
13411335 fail = specialize_class_load_attr (owner , instr , name );
1342- #endif
13431336 }
13441337 else {
13451338 fail = specialize_instance_load_attr (owner , instr , name );
@@ -1457,8 +1450,6 @@ _Py_Specialize_StoreAttr(_PyStackRef owner_st, _Py_CODEUNIT *instr, PyObject *na
14571450 Py_XDECREF (descr );
14581451}
14591452
1460- #ifndef Py_GIL_DISABLED
1461-
14621453#ifdef Py_STATS
14631454static int
14641455load_attr_fail_kind (DescriptorClassification kind )
@@ -1507,8 +1498,10 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15071498 SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_METACLASS_OVERRIDDEN );
15081499 return -1 ;
15091500 }
1510- PyObject * metadescriptor = _PyType_Lookup (Py_TYPE (cls ), name );
1501+ unsigned int meta_version ;
1502+ PyObject * metadescriptor = _PyType_LookupRefAndVersion (Py_TYPE (cls ), name , & meta_version );
15111503 DescriptorClassification metakind = classify_descriptor (metadescriptor , false);
1504+ Py_XDECREF (metadescriptor );
15121505 switch (metakind ) {
15131506 case METHOD :
15141507 case NON_DESCRIPTOR :
@@ -1525,14 +1518,16 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15251518 DescriptorClassification kind = 0 ;
15261519 unsigned int tp_version ;
15271520 kind = analyze_descriptor (cls , name , & descr , & tp_version , 0 );
1528- if (type_get_version (cls , LOAD_ATTR ) == 0 ) {
1521+ if (tp_version == 0 ) {
1522+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_VERSIONS );
15291523 Py_XDECREF (descr );
15301524 return -1 ;
15311525 }
15321526 bool metaclass_check = false;
15331527 if ((Py_TYPE (cls )-> tp_flags & Py_TPFLAGS_IMMUTABLETYPE ) == 0 ) {
15341528 metaclass_check = true;
1535- if (type_get_version (Py_TYPE (cls ), LOAD_ATTR ) == 0 ) {
1529+ if (meta_version == 0 ) {
1530+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_OUT_OF_VERSIONS );
15361531 Py_XDECREF (descr );
15371532 return -1 ;
15381533 }
@@ -1544,10 +1539,17 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15441539 return -1 ;
15451540 case METHOD :
15461541 case NON_DESCRIPTOR :
1547- write_u32 (cache -> type_version , cls -> tp_version_tag );
1542+ #ifdef Py_GIL_DISABLED
1543+ if (!_PyObject_HasDeferredRefcount (descr )) {
1544+ SPECIALIZATION_FAIL (LOAD_ATTR , SPEC_FAIL_ATTR_DESCR_NOT_DEFERRED );
1545+ Py_XDECREF (descr );
1546+ return -1 ;
1547+ }
1548+ #endif
1549+ write_u32 (cache -> type_version , tp_version );
15481550 write_obj (cache -> descr , descr );
15491551 if (metaclass_check ) {
1550- write_u32 (cache -> keys_version , Py_TYPE ( cls ) -> tp_version_tag );
1552+ write_u32 (cache -> keys_version , meta_version );
15511553 specialize (instr , LOAD_ATTR_CLASS_WITH_METACLASS_CHECK );
15521554 }
15531555 else {
@@ -1568,8 +1570,6 @@ specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr,
15681570 }
15691571}
15701572
1571- #endif // Py_GIL_DISABLED
1572-
15731573// Please collect stats carefully before and after modifying. A subtle change
15741574// can cause a significant drop in cache hits. A possible test is
15751575// python.exe -m test_typing test_re test_dis test_zlib.
0 commit comments