@@ -114,7 +114,12 @@ _PyUOpSymPrint(JitOptRef ref)
114114 printf ("<compact_int at %p>" , (void * )sym );
115115 break ;
116116 case JIT_SYM_SLOTS_TAG :
117- printf ("<slots[%d] v%u at %p>" , sym -> slots .num_slots , sym -> slots .type_version , (void * )sym );
117+ PyTypeObject * slots_type = _PyType_LookupByVersion (sym -> slots .type_version );
118+ if (slots_type ) {
119+ printf ("<%s slots[%d] v%u at %p>" , slots_type -> tp_name , sym -> slots .num_slots , sym -> slots .type_version , (void * )sym );
120+ } else {
121+ printf ("<slots[%d] v%u at %p>" , sym -> slots .num_slots , sym -> slots .type_version , (void * )sym );
122+ }
118123 break ;
119124 default :
120125 printf ("<tag=%d at %p>" , sym -> tag , (void * )sym );
@@ -890,6 +895,7 @@ _Py_uop_sym_new_slots_object(JitOptContext *ctx, unsigned int type_version)
890895 }
891896 res -> tag = JIT_SYM_SLOTS_TAG ;
892897 res -> slots .num_slots = 0 ;
898+ res -> slots .slots = NULL ;
893899 res -> slots .type_version = type_version ;
894900 return PyJitRef_Wrap (res );
895901}
@@ -899,19 +905,28 @@ _Py_uop_sym_slots_getattr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index
899905{
900906 JitOptSymbol * sym = PyJitRef_Unwrap (ref );
901907
902- if (sym -> tag == JIT_SYM_SLOTS_TAG ) {
903- // Linear search through the mapping array
908+ if (sym -> tag == JIT_SYM_SLOTS_TAG && sym -> slots .slots != NULL ) {
904909 for (int i = 0 ; i < sym -> slots .num_slots ; i ++ ) {
905910 if (sym -> slots .slots [i ].slot_index == slot_index ) {
906911 return PyJitRef_Wrap (allocation_base (ctx ) + sym -> slots .slots [i ].symbol );
907912 }
908913 }
909914 }
910915
911- // Not found, return not_null
912916 return _Py_uop_sym_new_not_null (ctx );
913917}
914918
919+ static JitOptSlotMapping *
920+ slots_arena_alloc (JitOptContext * ctx )
921+ {
922+ if (ctx -> s_arena .slots_curr_number + MAX_SYMBOLIC_SLOTS_SIZE > ctx -> s_arena .slots_max_number ) {
923+ return NULL ;
924+ }
925+ JitOptSlotMapping * slots = & ctx -> s_arena .arena [ctx -> s_arena .slots_curr_number ];
926+ ctx -> s_arena .slots_curr_number += MAX_SYMBOLIC_SLOTS_SIZE ;
927+ return slots ;
928+ }
929+
915930void
916931_Py_uop_sym_slots_setattr (JitOptContext * ctx , JitOptRef ref , uint16_t slot_index , JitOptRef value )
917932{
@@ -922,31 +937,44 @@ _Py_uop_sym_slots_setattr(JitOptContext *ctx, JitOptRef ref, uint16_t slot_index
922937 sym -> tag = JIT_SYM_SLOTS_TAG ;
923938 sym -> slots .type_version = version ;
924939 sym -> slots .num_slots = 0 ;
940+ sym -> slots .slots = slots_arena_alloc (ctx );
941+ if (sym -> slots .slots == NULL ) {
942+ return ;
943+ }
925944 }
926945 else if (sym -> tag == JIT_SYM_KNOWN_CLASS_TAG ) {
927946 uint32_t version = sym -> cls .version ;
928947 sym -> tag = JIT_SYM_SLOTS_TAG ;
929948 sym -> slots .type_version = version ;
930949 sym -> slots .num_slots = 0 ;
950+ sym -> slots .slots = slots_arena_alloc (ctx );
951+ if (sym -> slots .slots == NULL ) {
952+ return ;
953+ }
931954 }
932955 else if (sym -> tag != JIT_SYM_SLOTS_TAG ) {
933956 return ;
934957 }
935-
936- if (sym -> slots .num_slots >= MAX_SYMBOLIC_SLOTS_SIZE ) {
937- return ;
958+ // Check if have arena space allocated
959+ if (sym -> slots .slots == NULL ) {
960+ sym -> slots .slots = slots_arena_alloc (ctx );
961+ if (sym -> slots .slots == NULL ) {
962+ return ;
963+ }
938964 }
939-
965+ // Check if the slot already exists
940966 for (int i = 0 ; i < sym -> slots .num_slots ; i ++ ) {
941967 if (sym -> slots .slots [i ].slot_index == slot_index ) {
942968 sym -> slots .slots [i ].symbol = (uint16_t )(PyJitRef_Unwrap (value ) - allocation_base (ctx ));
943969 return ;
944970 }
945971 }
946-
947- int idx = sym -> slots .num_slots ++ ;
948- sym -> slots .slots [idx ].slot_index = slot_index ;
949- sym -> slots .slots [idx ].symbol = (uint16_t )(PyJitRef_Unwrap (value ) - allocation_base (ctx ));
972+ // Add new mapping if there's space
973+ if (sym -> slots .num_slots < MAX_SYMBOLIC_SLOTS_SIZE ) {
974+ int idx = sym -> slots .num_slots ++ ;
975+ sym -> slots .slots [idx ].slot_index = slot_index ;
976+ sym -> slots .slots [idx ].symbol = (uint16_t )(PyJitRef_Unwrap (value ) - allocation_base (ctx ));
977+ }
950978}
951979
952980// 0 on success, -1 on error.
@@ -1038,6 +1066,10 @@ _Py_uop_abstractcontext_init(JitOptContext *ctx)
10381066 ctx -> t_arena .ty_curr_number = 0 ;
10391067 ctx -> t_arena .ty_max_number = TY_ARENA_SIZE ;
10401068
1069+ // Setup the arena for slot mappings.
1070+ ctx -> s_arena .slots_curr_number = 0 ;
1071+ ctx -> s_arena .slots_max_number = SLOTS_ARENA_SIZE ;
1072+
10411073 // Frame setup
10421074 ctx -> curr_frame_depth = 0 ;
10431075
0 commit comments