diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 68ef8254b494a4..4dfbc08d993a83 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -164,10 +164,6 @@ abstractcontext_fini(_Py_UOpsAbstractInterpContext *ctx) return; } ctx->curr_frame_depth = 0; - int tys = ctx->t_arena.ty_curr_number; - for (int i = 0; i < tys; i++) { - Py_CLEAR(ctx->t_arena.arena[i].const_val); - } } static int @@ -218,7 +214,8 @@ ctx_frame_pop( } -// Takes a borrowed reference to const_val, turns that into a strong reference. +// Only accepts immortal constants or borrowed constants that will be kept alive +// elsewhere. static _Py_UOpsSymType* sym_new(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) @@ -230,13 +227,9 @@ sym_new(_Py_UOpsAbstractInterpContext *ctx, return NULL; } ctx->t_arena.ty_curr_number++; - self->const_val = NULL; self->typ = NULL; self->flags = 0; - - if (const_val != NULL) { - self->const_val = Py_NewRef(const_val); - } + self->const_val = const_val; return self; } @@ -331,7 +324,7 @@ sym_new_known_type(_Py_UOpsAbstractInterpContext *ctx, return res; } -// Takes a borrowed reference to const_val. +// Decrefs const_val if it is not immortal and discards it. static inline _Py_UOpsSymType* sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) { @@ -344,9 +337,33 @@ sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) return NULL; } sym_set_type(temp, Py_TYPE(const_val)); - sym_set_flag(temp, TRUE_CONST); - sym_set_flag(temp, KNOWN); - sym_set_flag(temp, NOT_NULL); + sym_set_flag(temp, KNOWN | NOT_NULL); + // If the constant is not immortal, discard it. + if (_Py_IsImmortal(const_val)) { + sym_set_flag(temp, TRUE_CONST); + } + else { + Py_DECREF(const_val); + temp->const_val = NULL; + } + return temp; +} + +// Same as sym_new_const, but borrows const_val, assuming it will be kept alive. +// Only safe if we know const_val has a strong reference elsewhere. +static inline _Py_UOpsSymType* +sym_new_const_borrow(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) +{ + assert(const_val != NULL); + _Py_UOpsSymType *temp = sym_new( + ctx, + const_val + ); + if (temp == NULL) { + return NULL; + } + sym_set_type(temp, Py_TYPE(const_val)); + sym_set_flag(temp, KNOWN | NOT_NULL | TRUE_CONST); return temp; } diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index ff2b9a42272863..d0bb5dcc172eb2 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -205,7 +205,7 @@ dummy_func(void) { } op(_LOAD_CONST_INLINE, (ptr/4 -- value)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = sym_new_const_borrow(ctx, ptr)); } op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) { @@ -213,7 +213,7 @@ dummy_func(void) { } op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = sym_new_const_borrow(ctx, ptr)); OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 58c11b7a1c87e0..1472e3d05313fb 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -1725,7 +1725,7 @@ case _LOAD_CONST_INLINE: { _Py_UOpsSymType *value; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = sym_new_const_borrow(ctx, ptr)); stack_pointer[0] = value; stack_pointer += 1; break; @@ -1744,7 +1744,7 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *null; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = sym_new_const_borrow(ctx, ptr)); OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); stack_pointer[0] = value; stack_pointer[1] = null;