From 7c7aa5a99cce256ff726654038092a333a1f0531 Mon Sep 17 00:00:00 2001 From: Ken Jin Date: Thu, 20 Jun 2024 23:55:20 +0800 Subject: [PATCH] [3.13] gh-119258: Backport optimizer frame fixes in GH-119365 (GH-120699) (cherry picked from commit 55402d3) --- Include/internal/pycore_optimizer.h | 6 +++--- Python/optimizer_analysis.c | 2 +- Python/optimizer_bytecodes.c | 13 ++++--------- Python/optimizer_cases.c.h | 12 +++--------- Python/optimizer_symbols.c | 23 ++++++++++------------- 5 files changed, 21 insertions(+), 35 deletions(-) diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index c0a76e85350..c422e2f113d 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -107,9 +107,9 @@ extern void _Py_uop_abstractcontext_fini(_Py_UOpsContext *ctx); extern _Py_UOpsAbstractFrame *_Py_uop_frame_new( _Py_UOpsContext *ctx, PyCodeObject *co, - _Py_UopsSymbol **localsplus_start, - int n_locals_already_filled, - int curr_stackentries); + int curr_stackentries, + _Py_UopsSymbol **args, + int arg_len); extern int _Py_uop_frame_pop(_Py_UOpsContext *ctx); PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored); diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 842b2e48923..03148c23a82 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -411,7 +411,7 @@ optimize_uops( if (_Py_uop_abstractcontext_init(ctx) < 0) { goto out_of_space; } - _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, co, ctx->n_consumed, 0, curr_stacklen); + _Py_UOpsAbstractFrame *frame = _Py_uop_frame_new(ctx, co, curr_stacklen, NULL, 0); if (frame == NULL) { return -1; } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index 2d61fa3b825..690c9b8bced 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -616,17 +616,12 @@ dummy_func(void) { argcount++; } - _Py_UopsSymbol **localsplus_start = ctx->n_consumed; - int n_locals_already_filled = 0; - // Can determine statically, so we interleave the new locals - // and make the current stack the new locals. - // This also sets up for true call inlining. + if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - localsplus_start = args; - n_locals_already_filled = argcount; + OUT_OF_SPACE_IF_NULL(new_frame = frame_new(ctx, co, 0, args, argcount)); + } else { + OUT_OF_SPACE_IF_NULL(new_frame = frame_new(ctx, co, 0, NULL, 0)); } - OUT_OF_SPACE_IF_NULL(new_frame = - frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); } op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) { diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index 621a48f2fc9..fb7f1edf498 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -1696,17 +1696,11 @@ args--; argcount++; } - _Py_UopsSymbol **localsplus_start = ctx->n_consumed; - int n_locals_already_filled = 0; - // Can determine statically, so we interleave the new locals - // and make the current stack the new locals. - // This also sets up for true call inlining. if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) { - localsplus_start = args; - n_locals_already_filled = argcount; + OUT_OF_SPACE_IF_NULL(new_frame = frame_new(ctx, co, 0, args, argcount)); + } else { + OUT_OF_SPACE_IF_NULL(new_frame = frame_new(ctx, co, 0, NULL, 0)); } - OUT_OF_SPACE_IF_NULL(new_frame = - frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); stack_pointer[-2 - oparg] = (_Py_UopsSymbol *)new_frame; stack_pointer += -1 - oparg; break; diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c index 4aeb04fe040..e80d15b200d 100644 --- a/Python/optimizer_symbols.c +++ b/Python/optimizer_symbols.c @@ -303,9 +303,9 @@ _Py_UOpsAbstractFrame * _Py_uop_frame_new( _Py_UOpsContext *ctx, PyCodeObject *co, - _Py_UopsSymbol **localsplus_start, - int n_locals_already_filled, - int curr_stackentries) + int curr_stackentries, + _Py_UopsSymbol **args, + int arg_len) { assert(ctx->curr_frame_depth < MAX_ABSTRACT_FRAME_DEPTH); _Py_UOpsAbstractFrame *frame = &ctx->frames[ctx->curr_frame_depth]; @@ -313,21 +313,21 @@ _Py_uop_frame_new( frame->stack_len = co->co_stacksize; frame->locals_len = co->co_nlocalsplus; - frame->locals = localsplus_start; + frame->locals = ctx->n_consumed; frame->stack = frame->locals + co->co_nlocalsplus; frame->stack_pointer = frame->stack + curr_stackentries; - ctx->n_consumed = localsplus_start + (co->co_nlocalsplus + co->co_stacksize); + ctx->n_consumed = ctx->n_consumed + (co->co_nlocalsplus + co->co_stacksize); if (ctx->n_consumed >= ctx->limit) { return NULL; } - // Initialize with the initial state of all local variables - for (int i = n_locals_already_filled; i < co->co_nlocalsplus; i++) { + for (int i = 0; i < arg_len; i++) { + frame->locals[i] = args[i]; + } + + for (int i = arg_len; i < co->co_nlocalsplus; i++) { _Py_UopsSymbol *local = _Py_uop_sym_new_unknown(ctx); - if (local == NULL) { - return NULL; - } frame->locals[i] = local; } @@ -335,9 +335,6 @@ _Py_uop_frame_new( // Initialize the stack as well for (int i = 0; i < curr_stackentries; i++) { _Py_UopsSymbol *stackvar = _Py_uop_sym_new_unknown(ctx); - if (stackvar == NULL) { - return NULL; - } frame->stack[i] = stackvar; }