From 05cee5d6225e7bd0baf106d594fe7be2201de0b7 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 2 Nov 2023 22:47:35 +0900 Subject: [PATCH 1/3] gh-107265: Fix _PyFrame_OpAlreadyRan for ENTER_EXECUTOR case --- Objects/frameobject.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 698e88483569d1..1c0871229c3806 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1090,13 +1090,27 @@ static int _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) { // This only works when opcode is a non-quickened form: + assert(opcode != ENTER_EXECUTOR); assert(_PyOpcode_Deopt[opcode] == opcode); int check_oparg = 0; + PyCodeObject *code = _PyFrame_GetCode(frame); for (_Py_CODEUNIT *instruction = _PyCode_CODE(_PyFrame_GetCode(frame)); instruction < frame->instr_ptr; instruction++) { - int check_opcode = _PyOpcode_Deopt[instruction->op.code]; - check_oparg |= instruction->op.arg; + int check_opcode = -1; + if (instruction->op.code == ENTER_EXECUTOR) { + int exec_index = instruction->op.arg; + _PyExecutorObject *exec = code->co_executors->executors[exec_index]; + check_opcode = exec->vm_data.opcode; + check_oparg |= exec->vm_data.oparg; + } + else { + check_opcode = _PyOpcode_Deopt[instruction->op.code]; + check_oparg |= instruction->op.arg; + } + + assert(check_opcode != ENTER_EXECUTOR); + if (check_opcode == opcode && check_oparg == oparg) { return 1; } From 27138c9494cd94c8d0352e7f24a9df6d34d9003f Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 2 Nov 2023 22:52:40 +0900 Subject: [PATCH 2/3] Add _PyOpcode_Deopt for exec->vm_data.opcode --- Objects/frameobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 1c0871229c3806..e3aa1b66996a6e 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1101,7 +1101,7 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) if (instruction->op.code == ENTER_EXECUTOR) { int exec_index = instruction->op.arg; _PyExecutorObject *exec = code->co_executors->executors[exec_index]; - check_opcode = exec->vm_data.opcode; + check_opcode = _PyOpcode_Deopt[exec->vm_data.opcode]; check_oparg |= exec->vm_data.oparg; } else { From db105b9e0eeb321c920c482ea86e17526a630f94 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Thu, 2 Nov 2023 22:53:27 +0900 Subject: [PATCH 3/3] nit --- Objects/frameobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index e3aa1b66996a6e..1bc63f6b43adc7 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -1094,7 +1094,7 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) assert(_PyOpcode_Deopt[opcode] == opcode); int check_oparg = 0; PyCodeObject *code = _PyFrame_GetCode(frame); - for (_Py_CODEUNIT *instruction = _PyCode_CODE(_PyFrame_GetCode(frame)); + for (_Py_CODEUNIT *instruction = _PyCode_CODE(code); instruction < frame->instr_ptr; instruction++) { int check_opcode = -1;