Skip to content

Commit 7bb2c20

Browse files
committed
use s_arena to save slots mapping
1 parent dfd99d7 commit 7bb2c20

File tree

2 files changed

+58
-15
lines changed

2 files changed

+58
-15
lines changed

Include/internal/pycore_optimizer_types.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ extern "C" {
1616

1717
#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * 5)
1818

19+
// Maximum slots per object tracked symbolically
20+
#define MAX_SYMBOLIC_SLOTS_SIZE 16
21+
#define SLOTS_ARENA_SIZE (MAX_SYMBOLIC_SLOTS_SIZE * 100)
22+
1923
// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH())
2024
#define MAX_ABSTRACT_FRAME_DEPTH (16)
2125

@@ -77,8 +81,6 @@ typedef struct {
7781
uint8_t tag;
7882
} JitOptCompactInt;
7983

80-
#define MAX_SYMBOLIC_SLOTS_SIZE 4
81-
8284
typedef struct {
8385
uint16_t slot_index;
8486
uint16_t symbol;
@@ -88,7 +90,7 @@ typedef struct _jit_opt_slots {
8890
uint8_t tag;
8991
uint8_t num_slots;
9092
uint32_t type_version;
91-
JitOptSlotMapping slots[MAX_SYMBOLIC_SLOTS_SIZE];
93+
JitOptSlotMapping *slots;
9294
} JitOptSlotsObject;
9395

9496
typedef union _jit_opt_symbol {
@@ -128,6 +130,12 @@ typedef struct ty_arena {
128130
JitOptSymbol arena[TY_ARENA_SIZE];
129131
} ty_arena;
130132

133+
typedef struct slots_arena {
134+
int slots_curr_number;
135+
int slots_max_number;
136+
JitOptSlotMapping arena[SLOTS_ARENA_SIZE];
137+
} slots_arena;
138+
131139
typedef struct _JitOptContext {
132140
char done;
133141
char out_of_space;
@@ -142,6 +150,9 @@ typedef struct _JitOptContext {
142150
// Arena for the symbolic types.
143151
ty_arena t_arena;
144152

153+
// Arena for slots mappings.
154+
slots_arena s_arena;
155+
145156
JitOptRef *n_consumed;
146157
JitOptRef *limit;
147158
JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];

Python/optimizer_symbols.c

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
915930
void
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

Comments
 (0)