diff --git a/Python/bytecodes.c b/Python/bytecodes.c index cb88ba74f9a5fe..b650613650cf36 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -272,7 +272,6 @@ dummy_func( inst(LOAD_FAST_AND_CLEAR, (-- value)) { value = GETLOCAL(oparg); - // do not use SETLOCAL here, it decrefs the old value GETLOCAL(oparg) = PyStackRef_NULL; } @@ -328,8 +327,10 @@ dummy_func( } replicate(8) inst(STORE_FAST, (value --)) { - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; DEAD(value); + PyStackRef_XCLOSE(tmp); } pseudo(STORE_FAST_MAYBE_NULL, (unused --)) = { @@ -339,18 +340,24 @@ dummy_func( inst(STORE_FAST_LOAD_FAST, (value1 -- value2)) { uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; - SETLOCAL(oparg1, value1); + _PyStackRef tmp = GETLOCAL(oparg1); + GETLOCAL(oparg1) = value1; DEAD(value1); value2 = PyStackRef_DUP(GETLOCAL(oparg2)); + PyStackRef_XCLOSE(tmp); } inst(STORE_FAST_STORE_FAST, (value2, value1 --)) { uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; - SETLOCAL(oparg1, value1); + _PyStackRef tmp = GETLOCAL(oparg1); + GETLOCAL(oparg1) = value1; DEAD(value1); - SETLOCAL(oparg2, value2); + PyStackRef_XCLOSE(tmp); + tmp = GETLOCAL(oparg2); + GETLOCAL(oparg2) = value2; DEAD(value2); + PyStackRef_XCLOSE(tmp); } pure inst(POP_TOP, (value --)) { @@ -1775,7 +1782,9 @@ dummy_func( ); ERROR_IF(1, error); } - SETLOCAL(oparg, PyStackRef_NULL); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_NULL; + PyStackRef_XCLOSE(tmp); } inst(MAKE_CELL, (--)) { @@ -1786,7 +1795,9 @@ dummy_func( if (cell == NULL) { ERROR_NO_POP(); } - SETLOCAL(oparg, PyStackRef_FromPyObjectSteal(cell)); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_FromPyObjectSteal(cell); + PyStackRef_XCLOSE(tmp); } inst(DELETE_DEREF, (--)) { diff --git a/Python/ceval.c b/Python/ceval.c index 11518684c136bd..4f628fdbabddbb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -194,6 +194,7 @@ lltrace_instruction(_PyInterpreterFrame *frame, } fflush(stdout); } + static void lltrace_resume_frame(_PyInterpreterFrame *frame) { diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h index c2fc38f3c18e53..b6d9df32953892 100644 --- a/Python/ceval_macros.h +++ b/Python/ceval_macros.h @@ -221,15 +221,6 @@ GETITEM(PyObject *v, Py_ssize_t i) { #define LOCALS_ARRAY (frame->localsplus) #define GETLOCAL(i) (frame->localsplus[i]) -/* The SETLOCAL() macro must not DECREF the local variable in-place and - then store the new value; it must copy the old value to a temporary - value, then store the new value, and then DECREF the temporary value. - This is because it is possible that during the DECREF the frame is - accessed by other code (e.g. a __del__ method or gc.collect()) and the - variable would be pointing to already-freed memory. */ -#define SETLOCAL(i, value) do { _PyStackRef tmp = GETLOCAL(i); \ - GETLOCAL(i) = value; \ - PyStackRef_XCLOSE(tmp); } while (0) #ifdef Py_STATS #define UPDATE_MISS_STATS(INSTNAME) \ diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 5b19ec182b5805..22d11059fcadb8 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -205,7 +205,6 @@ _PyStackRef value; oparg = CURRENT_OPARG(); value = GETLOCAL(oparg); - // do not use SETLOCAL here, it decrefs the old value GETLOCAL(oparg) = PyStackRef_NULL; stack_pointer[0] = value; stack_pointer += 1; @@ -307,9 +306,13 @@ oparg = 0; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -318,9 +321,13 @@ oparg = 1; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -329,9 +336,13 @@ oparg = 2; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -340,9 +351,13 @@ oparg = 3; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -351,9 +366,13 @@ oparg = 4; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -362,9 +381,13 @@ oparg = 5; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -373,9 +396,13 @@ oparg = 6; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -384,9 +411,13 @@ oparg = 7; assert(oparg == CURRENT_OPARG()); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -394,9 +425,13 @@ _PyStackRef value; oparg = CURRENT_OPARG(); value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -2255,7 +2290,11 @@ stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } - SETLOCAL(oparg, PyStackRef_NULL); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_NULL; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -2268,7 +2307,11 @@ if (cell == NULL) { JUMP_TO_ERROR(); } - SETLOCAL(oparg, PyStackRef_FromPyObjectSteal(cell)); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_FromPyObjectSteal(cell); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); break; } @@ -6314,7 +6357,9 @@ #endif if (exit->executor && !exit->executor->vm_data.valid) { exit->temperature = initial_temperature_backoff_counter(); + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(exit->executor); + stack_pointer = _PyFrame_GetStackPointer(frame); } if (exit->executor == NULL) { _Py_BackoffCounter temperature = exit->temperature; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 0bc92f30bfded2..5820147ff712a9 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1082,7 +1082,9 @@ frame, this_instr, callable_o, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(res_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -1842,7 +1844,9 @@ frame, this_instr, func, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(result_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -2163,7 +2167,9 @@ frame, this_instr, callable_o, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(res_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -3837,7 +3843,11 @@ stack_pointer = _PyFrame_GetStackPointer(frame); goto error; } - SETLOCAL(oparg, PyStackRef_NULL); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_NULL; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -4781,7 +4791,9 @@ frame, this_instr, callable_o, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(res_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -4920,7 +4932,9 @@ frame, this_instr, func, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(result_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -5155,7 +5169,9 @@ frame, this_instr, callable_o, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(res_o); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -5421,7 +5437,9 @@ frame, this_instr, global_super, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(super); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -6858,7 +6876,6 @@ INSTRUCTION_STATS(LOAD_FAST_AND_CLEAR); _PyStackRef value; value = GETLOCAL(oparg); - // do not use SETLOCAL here, it decrefs the old value GETLOCAL(oparg) = PyStackRef_NULL; stack_pointer[0] = value; stack_pointer += 1; @@ -7338,7 +7355,9 @@ frame, this_instr, global_super, arg); stack_pointer = _PyFrame_GetStackPointer(frame); if (err < 0) { + _PyFrame_SetStackPointer(frame, stack_pointer); Py_CLEAR(super); + stack_pointer = _PyFrame_GetStackPointer(frame); } } } @@ -7472,7 +7491,11 @@ if (cell == NULL) { goto error; } - SETLOCAL(oparg, PyStackRef_FromPyObjectSteal(cell)); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = PyStackRef_FromPyObjectSteal(cell); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -8545,9 +8568,13 @@ INSTRUCTION_STATS(STORE_FAST); _PyStackRef value; value = stack_pointer[-1]; - SETLOCAL(oparg, value); + _PyStackRef tmp = GETLOCAL(oparg); + GETLOCAL(oparg) = value; stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -8560,9 +8587,13 @@ value1 = stack_pointer[-1]; uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; - SETLOCAL(oparg1, value1); + _PyStackRef tmp = GETLOCAL(oparg1); + GETLOCAL(oparg1) = value1; value2 = PyStackRef_DUP(GETLOCAL(oparg2)); stack_pointer[-1] = value2; + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } @@ -8576,10 +8607,20 @@ value2 = stack_pointer[-2]; uint32_t oparg1 = oparg >> 4; uint32_t oparg2 = oparg & 15; - SETLOCAL(oparg1, value1); - SETLOCAL(oparg2, value2); - stack_pointer += -2; + _PyStackRef tmp = GETLOCAL(oparg1); + GETLOCAL(oparg1) = value1; + stack_pointer += -1; assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); + tmp = GETLOCAL(oparg2); + GETLOCAL(oparg2) = value2; + stack_pointer += -1; + assert(WITHIN_STACK_BOUNDS()); + _PyFrame_SetStackPointer(frame, stack_pointer); + PyStackRef_XCLOSE(tmp); + stack_pointer = _PyFrame_GetStackPointer(frame); DISPATCH(); } diff --git a/Tools/cases_generator/analyzer.py b/Tools/cases_generator/analyzer.py index 724fba5f953a4e..11a559bca474b0 100644 --- a/Tools/cases_generator/analyzer.py +++ b/Tools/cases_generator/analyzer.py @@ -607,7 +607,6 @@ def has_error_without_pop(op: parser.CodeDef) -> bool: "PyUnicode_GET_LENGTH", "PyUnicode_READ_CHAR", "Py_ARRAY_LENGTH", - "Py_CLEAR", "Py_FatalError", "Py_INCREF", "Py_IS_TYPE", @@ -859,13 +858,7 @@ def compute_properties(op: parser.CodeDef) -> Properties: ) error_with_pop = has_error_with_pop(op) error_without_pop = has_error_without_pop(op) - escapes = ( - bool(escaping_calls) or - variable_used(op, "Py_DECREF") or - variable_used(op, "Py_XDECREF") or - variable_used(op, "Py_CLEAR") or - variable_used(op, "SETLOCAL") - ) + escapes = bool(escaping_calls) pure = False if isinstance(op, parser.LabelDef) else "pure" in op.annotations no_save_ip = False if isinstance(op, parser.LabelDef) else "no_save_ip" in op.annotations return Properties( @@ -883,8 +876,7 @@ def compute_properties(op: parser.CodeDef) -> Properties: stores_sp=variable_used(op, "SYNC_SP"), uses_co_consts=variable_used(op, "FRAME_CO_CONSTS"), uses_co_names=variable_used(op, "FRAME_CO_NAMES"), - uses_locals=(variable_used(op, "GETLOCAL") or variable_used(op, "SETLOCAL")) - and not has_free, + uses_locals=variable_used(op, "GETLOCAL") and not has_free, uses_opcode=variable_used(op, "opcode"), has_free=has_free, pure=pure,