@@ -121,6 +121,12 @@ static void make_const(JitOptSymbol *sym, PyObject *val)
121121static inline void
122122sym_set_bottom (JitOptContext * ctx , JitOptSymbol * sym )
123123{
124+ if (sym -> tag == JIT_SYM_KNOWN_VALUE_TAG ) {
125+ Py_CLEAR (sym -> value .value );
126+ }
127+ if (sym -> tag == JIT_SYM_FUNCTION_TAG ) {
128+ Py_CLEAR (sym -> function .function );
129+ }
124130 sym -> tag = JIT_SYM_BOTTOM_TAG ;
125131 ctx -> done = true;
126132 ctx -> contradiction = true;
@@ -143,19 +149,24 @@ bool
143149_Py_uop_sym_is_const (JitOptContext * ctx , JitOptRef ref )
144150{
145151 JitOptSymbol * sym = PyJitRef_Unwrap (ref );
146- if (sym -> tag == JIT_SYM_KNOWN_VALUE_TAG ) {
147- return true;
148- }
149- if (sym -> tag == JIT_SYM_TRUTHINESS_TAG ) {
150- JitOptSymbol * value = allocation_base (ctx ) + sym -> truthiness .value ;
151- int truthiness = _Py_uop_sym_truthiness (ctx , PyJitRef_Wrap (value ));
152- if (truthiness < 0 ) {
153- return false;
152+ switch (sym -> tag ) {
153+ case JIT_SYM_KNOWN_VALUE_TAG :
154+ return true;
155+ case JIT_SYM_TRUTHINESS_TAG :
156+ {
157+ JitOptSymbol * value = allocation_base (ctx ) + sym -> truthiness .value ;
158+ int truthiness = _Py_uop_sym_truthiness (ctx , PyJitRef_Wrap (value ));
159+ if (truthiness < 0 ) {
160+ return false;
161+ }
162+ make_const (sym , (truthiness ^ sym -> truthiness .invert ) ? Py_True : Py_False );
163+ return true;
154164 }
155- make_const (sym , (truthiness ^ sym -> truthiness .invert ) ? Py_True : Py_False );
156- return true;
165+ case JIT_SYM_FUNCTION_TAG :
166+ return sym -> function .function != NULL ;
167+ default :
168+ return false;
157169 }
158- return false;
159170}
160171
161172bool
@@ -182,6 +193,9 @@ _Py_uop_sym_get_const(JitOptContext *ctx, JitOptRef ref)
182193 make_const (sym , res );
183194 return res ;
184195 }
196+ if (sym -> tag == JIT_SYM_FUNCTION_TAG ) {
197+ return sym -> function .function ;
198+ }
185199 return NULL ;
186200}
187201
@@ -269,6 +283,11 @@ _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef ref, PyTypeObject *typ)
269283 sym_set_bottom (ctx , sym );
270284 }
271285 return ;
286+ case JIT_SYM_FUNCTION_TAG :
287+ if (typ != & PyFunction_Type ) {
288+ sym_set_bottom (ctx , sym );
289+ }
290+ return ;
272291 }
273292}
274293
@@ -307,6 +326,12 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef ref, unsigned int ver
307326 return false;
308327 };
309328 return true;
329+ case JIT_SYM_FUNCTION_TAG :
330+ if (PyFunction_Type .tp_version_tag != version ) {
331+ sym_set_bottom (ctx , sym );
332+ return false;
333+ };
334+ return true;
310335 case JIT_SYM_TYPE_VERSION_TAG :
311336 if (sym -> version .version != version ) {
312337 sym_set_bottom (ctx , sym );
@@ -424,6 +449,14 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef ref, PyObject *const_val)
424449 sym_set_bottom (ctx , sym );
425450 }
426451 return ;
452+ case JIT_SYM_FUNCTION_TAG :
453+ if (PyFunction_Check (const_val )) {
454+ sym -> function .function = Py_NewRef (const_val );
455+ if (((PyFunctionObject * )const_val )-> func_version != sym -> function .version ) {
456+ sym_set_bottom (ctx , sym );
457+ }
458+ }
459+ return ;
427460 }
428461}
429462
@@ -543,7 +576,8 @@ _Py_uop_sym_get_type(JitOptRef ref)
543576 return & PyBool_Type ;
544577 case JIT_SYM_COMPACT_INT :
545578 return & PyLong_Type ;
546-
579+ case JIT_SYM_FUNCTION_TAG :
580+ return & PyFunction_Type ;
547581 }
548582 Py_UNREACHABLE ();
549583}
@@ -571,6 +605,8 @@ _Py_uop_sym_get_type_version(JitOptRef ref)
571605 return PyBool_Type .tp_version_tag ;
572606 case JIT_SYM_COMPACT_INT :
573607 return PyLong_Type .tp_version_tag ;
608+ case JIT_SYM_FUNCTION_TAG :
609+ return PyFunction_Type .tp_version_tag ;
574610 }
575611 Py_UNREACHABLE ();
576612}
@@ -606,6 +642,8 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef ref)
606642 case JIT_SYM_UNKNOWN_TAG :
607643 case JIT_SYM_COMPACT_INT :
608644 return -1 ;
645+ case JIT_SYM_FUNCTION_TAG :
646+ return 1 ;
609647 case JIT_SYM_KNOWN_CLASS_TAG :
610648 /* TODO :
611649 * Instances of some classes are always
@@ -761,6 +799,7 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref)
761799 return ;
762800 case JIT_SYM_TUPLE_TAG :
763801 case JIT_SYM_TRUTHINESS_TAG :
802+ case JIT_SYM_FUNCTION_TAG :
764803 sym_set_bottom (ctx , sym );
765804 return ;
766805 case JIT_SYM_BOTTOM_TAG :
@@ -773,6 +812,72 @@ _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef ref)
773812 }
774813}
775814
815+ void
816+ _Py_uop_sym_set_function_version (JitOptContext * ctx , JitOptRef ref , uint32_t version )
817+ {
818+ JitOptSymbol * sym = PyJitRef_Unwrap (ref );
819+ JitSymType tag = sym -> tag ;
820+ switch (tag ) {
821+ case JIT_SYM_TUPLE_TAG :
822+ case JIT_SYM_TRUTHINESS_TAG :
823+ case JIT_SYM_BOTTOM_TAG :
824+ case JIT_SYM_COMPACT_INT :
825+ case JIT_SYM_NULL_TAG :
826+ sym_set_bottom (ctx , sym );
827+ return ;
828+ case JIT_SYM_KNOWN_CLASS_TAG :
829+ if (sym -> cls .type == & PyFunction_Type ) {
830+ sym -> tag = JIT_SYM_FUNCTION_TAG ;
831+ sym -> function .function = NULL ;
832+ sym -> function .version = version ;
833+ } else {
834+ sym_set_bottom (ctx , sym );
835+ }
836+ return ;
837+ case JIT_SYM_TYPE_VERSION_TAG :
838+ if (sym -> version .version == PyLong_Type .tp_version_tag ) {
839+ sym -> tag = JIT_SYM_COMPACT_INT ;
840+ }
841+ else {
842+ sym_set_bottom (ctx , sym );
843+ }
844+ return ;
845+ case JIT_SYM_KNOWN_VALUE_TAG :
846+ if (PyFunction_Check (sym -> value .value )) {
847+ sym -> tag = JIT_SYM_FUNCTION_TAG ;
848+ sym -> function .function = sym -> value .value ;
849+ sym -> function .version = version ;
850+ }
851+ else {
852+ Py_CLEAR (sym -> value .value );
853+ sym_set_bottom (ctx , sym );
854+ }
855+ return ;
856+ case JIT_SYM_NON_NULL_TAG :
857+ case JIT_SYM_UNKNOWN_TAG :
858+ sym -> tag = JIT_SYM_FUNCTION_TAG ;
859+ sym -> function .function = NULL ;
860+ sym -> function .version = version ;
861+ return ;
862+ case JIT_SYM_FUNCTION_TAG :
863+ if (sym -> function .version != version ) {
864+ Py_CLEAR (sym -> function .function );
865+ sym_set_bottom (ctx , sym );
866+ }
867+ return ;
868+ }
869+ }
870+
871+ uint32_t
872+ _Py_uop_sym_get_function_version (JitOptRef ref )
873+ {
874+ JitOptSymbol * sym = PyJitRef_Unwrap (ref );
875+ if (sym -> tag == JIT_SYM_FUNCTION_TAG ) {
876+ return sym -> function .function ;
877+ }
878+ return 0 ;
879+ }
880+
776881JitOptRef
777882_Py_uop_sym_new_truthiness (JitOptContext * ctx , JitOptRef ref , bool truthy )
778883{
@@ -827,6 +932,9 @@ _Py_uop_frame_new(
827932 frame -> locals = ctx -> n_consumed ;
828933 frame -> stack = frame -> locals + co -> co_nlocalsplus ;
829934 frame -> stack_pointer = frame -> stack + curr_stackentries ;
935+ frame -> function_checked = false;
936+ frame -> builtins_watched = false;
937+ frame -> globals_watched = false;
830938 ctx -> n_consumed = ctx -> n_consumed + (co -> co_nlocalsplus + co -> co_stacksize );
831939 if (ctx -> n_consumed >= ctx -> limit ) {
832940 ctx -> done = true;
@@ -860,13 +968,17 @@ _Py_uop_abstractcontext_fini(JitOptContext *ctx)
860968 if (ctx == NULL ) {
861969 return ;
862970 }
971+ ctx -> prechecked_function_version = 0 ;
863972 ctx -> curr_frame_depth = 0 ;
864973 int tys = ctx -> t_arena .ty_curr_number ;
865974 for (int i = 0 ; i < tys ; i ++ ) {
866975 JitOptSymbol * sym = & ctx -> t_arena .arena [i ];
867976 if (sym -> tag == JIT_SYM_KNOWN_VALUE_TAG ) {
868977 Py_CLEAR (sym -> value .value );
869978 }
979+ if (sym -> tag == JIT_SYM_FUNCTION_TAG ) {
980+ Py_CLEAR (sym -> function .function );
981+ }
870982 }
871983}
872984
0 commit comments