@@ -1071,40 +1071,39 @@ dummy_func(void) {
10711071 op (_CHECK_OBJECT , (type_version /2 , callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
10721072 PyObject * probable_callable = sym_get_probable_value (callable );
10731073 assert (probable_callable != NULL );
1074- PyTypeObject * tp = (PyTypeObject * )probable_callable ;
1075- if (tp -> tp_version_tag == type_version ) {
1076- // If the type version has not changed since we last saw it,
1077- // then we know this __init__ is definitely the same one as in the cache.
1078- // We can promote callable to a known constant. This does not need a
1079- // type watcher, as we do not remove this _CHECK_AND_ALLOCATE_OBJECT guard.
1080- if (sym_is_null (self_or_null ) && sym_matches_type (callable , & PyType_Type )) {
1074+ PyObject * const_callable = sym_get_const (ctx , callable );
1075+ bool is_probable = const_callable == NULL && probable_callable != NULL ;
1076+ PyObject * callable_o = const_callable != NULL ? const_callable : probable_callable ;
1077+ if (sym_is_null (self_or_null ) &&
1078+ callable_o != NULL &&
1079+ PyType_Check (callable_o ) &&
1080+ ((PyTypeObject * )callable_o )-> tp_version_tag == type_version ) {
1081+ // Probable types need the guard.
1082+ if (!is_probable ) {
10811083 ADD_OP (_NOP , 0 , 0 );
10821084 }
1083- PyHeapTypeObject * cls = (PyHeapTypeObject * )probable_callable ;
1085+ else {
1086+ // Promote the probable type, as we have
1087+ // guarded on it.
1088+ sym_set_const (callable , callable_o );
1089+ }
1090+ PyHeapTypeObject * cls = (PyHeapTypeObject * )callable_o ;
10841091 PyObject * init = cls -> _spec_cache .init ;
10851092 assert (init != NULL );
10861093 assert (PyFunction_Check (init ));
1087- sym_set_const (callable , init );
1094+ callable = sym_new_const (ctx , init );
1095+ PyType_Watch (TYPE_WATCHER_ID , callable_o );
1096+ _Py_BloomFilter_Add (dependencies , callable_o );;
10881097 }
10891098 else {
1090- // add watcher so that whenever the type changes we invalidate this
1091- PyTypeObject * type = _PyType_LookupByVersion (type_version );
1092- // if the type is null, it was not found in the cache (there was a conflict)
1093- // with the key, in which case we can't trust the version
1094- if (type ) {
1095- // if the type version was set properly, then add a watcher
1096- // if it wasn't this means that the type version was previously set to something else
1097- // and we set the callable to bottom, so we don't need to add a watcher because we must have
1098- // already added one earlier.
1099- if (sym_set_type_version (callable , type_version )) {
1100- PyType_Watch (TYPE_WATCHER_ID , (PyObject * )type );
1101- _Py_BloomFilter_Add (dependencies , type );
1102- }
1103- }
1104- self_or_null = sym_new_not_null (ctx );
1099+ callable = sym_new_not_null (ctx );
11051100 }
11061101 }
11071102
1103+ op (_ALLOCATE_OBJECT , (callable , self_or_null , unused [oparg ] -- callable , self_or_null , unused [oparg ])) {
1104+ self_or_null = sym_new_not_null (ctx );
1105+ }
1106+
11081107 op (_CREATE_INIT_FRAME , (init , self , args [oparg ] -- init_frame )) {
11091108 ctx -> frame -> stack_pointer = stack_pointer - oparg - 2 ;
11101109 _Py_UOpsAbstractFrame * shim = frame_new (ctx , (PyCodeObject * )& _Py_InitCleanup , NULL , 0 );
0 commit comments