@@ -974,6 +974,7 @@ _Py_uop_sym_new_slots_object(JitOptContext *ctx, unsigned int type_version)
974974 res -> slots .num_slots = 0 ;
975975 res -> slots .slots = NULL ;
976976 res -> slots .type_version = type_version ;
977+ res -> slots .last_modified_index = uop_buffer_length (& ctx -> out_buffer );
977978 return PyJitRef_Wrap (res );
978979}
979980
@@ -982,7 +983,13 @@ _Py_uop_sym_slots_getattr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index
982983{
983984 JitOptSymbol * sym = PyJitRef_Unwrap (ref );
984985
985- if (sym -> tag == JIT_SYM_SLOTS_TAG && sym -> slots .slots != NULL ) {
986+ // Only return tracked slot values if:
987+ // 1. Symbol is a slots object with mappings allocated
988+ // 2. No escape has occurred since last modification (state is fresh)
989+ if (sym -> tag == JIT_SYM_SLOTS_TAG &&
990+ sym -> slots .slots != NULL &&
991+ sym -> slots .last_modified_index >= ctx -> last_escape_index )
992+ {
986993 for (int i = 0 ; i < sym -> slots .num_slots ; i ++ ) {
987994 if (sym -> slots .slots [i ].slot_index == slot_index ) {
988995 return PyJitRef_Wrap (allocation_base (ctx ) + sym -> slots .slots [i ].symbol );
@@ -993,13 +1000,13 @@ _Py_uop_sym_slots_getattr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index
9931000 return _Py_uop_sym_new_not_null (ctx );
9941001}
9951002
996- static JitOptSlotMapping *
1003+ static JitOptDescrMapping *
9971004slots_arena_alloc (JitOptContext * ctx )
9981005{
9991006 if (ctx -> s_arena .slots_curr_number + MAX_SYMBOLIC_SLOTS_SIZE > ctx -> s_arena .slots_max_number ) {
10001007 return NULL ;
10011008 }
1002- JitOptSlotMapping * slots = & ctx -> s_arena .arena [ctx -> s_arena .slots_curr_number ];
1009+ JitOptDescrMapping * slots = & ctx -> s_arena .arena [ctx -> s_arena .slots_curr_number ];
10031010 ctx -> s_arena .slots_curr_number += MAX_SYMBOLIC_SLOTS_SIZE ;
10041011 return slots ;
10051012}
@@ -1008,30 +1015,18 @@ void
10081015_Py_uop_sym_slots_setattr (JitOptContext * ctx , JitOptRef ref , uint16_t slot_index , JitOptRef value )
10091016{
10101017 JitOptSymbol * sym = PyJitRef_Unwrap (ref );
1018+ int curr_index = uop_buffer_length (& ctx -> out_buffer );
10111019
1012- if (sym -> tag == JIT_SYM_TYPE_VERSION_TAG ) {
1013- uint32_t version = sym -> version .version ;
1014- sym -> tag = JIT_SYM_SLOTS_TAG ;
1015- sym -> slots .type_version = version ;
1016- sym -> slots .num_slots = 0 ;
1017- sym -> slots .slots = slots_arena_alloc (ctx );
1018- if (sym -> slots .slots == NULL ) {
1019- return ;
1020- }
1020+ if (sym -> tag != JIT_SYM_SLOTS_TAG ) {
1021+ return ;
10211022 }
1022- else if (sym -> tag == JIT_SYM_KNOWN_CLASS_TAG ) {
1023- uint32_t version = sym -> cls .version ;
1024- sym -> tag = JIT_SYM_SLOTS_TAG ;
1025- sym -> slots .type_version = version ;
1023+
1024+ // Check escape
1025+ if (sym -> slots .last_modified_index < ctx -> last_escape_index ) {
10261026 sym -> slots .num_slots = 0 ;
1027- sym -> slots .slots = slots_arena_alloc (ctx );
1028- if (sym -> slots .slots == NULL ) {
1029- return ;
1030- }
1031- }
1032- else if (sym -> tag != JIT_SYM_SLOTS_TAG ) {
1033- return ;
10341027 }
1028+ // Update the last modified timestamp
1029+ sym -> slots .last_modified_index = curr_index ;
10351030 // Check if have arena space allocated
10361031 if (sym -> slots .slots == NULL ) {
10371032 sym -> slots .slots = slots_arena_alloc (ctx );
@@ -1157,6 +1152,7 @@ _Py_uop_abstractcontext_init(JitOptContext *ctx)
11571152 ctx -> out_of_space = false;
11581153 ctx -> contradiction = false;
11591154 ctx -> builtins_watched = false;
1155+ ctx -> last_escape_index = 0 ;
11601156}
11611157
11621158int
0 commit comments