Skip to content

Commit 2490721

Browse files
markshannonadorilson
authored andcommitted
pythonGH-113710: Fix optimization of globals using _CHECK_FUNCTION (pythonGH-116460)
1 parent 18ee215 commit 2490721

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

Python/bytecodes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4096,8 +4096,9 @@ dummy_func(
40964096
null = NULL;
40974097
}
40984098

4099-
tier2 op(_CHECK_FUNCTION, (func/4 -- )) {
4100-
DEOPT_IF(frame->f_funcobj != func);
4099+
tier2 op(_CHECK_FUNCTION, (func_version/2 -- )) {
4100+
assert(PyFunction_Check(frame->f_funcobj));
4101+
DEOPT_IF(((PyFunctionObject *)frame->f_funcobj)->func_version != func_version);
41014102
}
41024103

41034104
/* Internal -- for testing executors */

Python/executor_cases.c.h

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer_analysis.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
141141
return 1;
142142
}
143143
PyObject *globals = frame->f_globals;
144-
assert(PyFunction_Check(((PyFunctionObject *)frame->f_funcobj)));
145-
assert(((PyFunctionObject *)frame->f_funcobj)->func_builtins == builtins);
146-
assert(((PyFunctionObject *)frame->f_funcobj)->func_globals == globals);
144+
PyFunctionObject *function = (PyFunctionObject *)frame->f_funcobj;
145+
assert(PyFunction_Check(function));
146+
assert(function->func_builtins == builtins);
147+
assert(function->func_globals == globals);
148+
uint32_t function_version = _PyFunction_GetVersionForCurrentState(function);
147149
/* In order to treat globals as constants, we need to
148150
* know that the globals dict is the one we expected, and
149151
* that it hasn't changed
@@ -181,7 +183,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
181183
}
182184
else {
183185
buffer[pc].opcode = _CHECK_FUNCTION;
184-
buffer[pc].operand = (uintptr_t)builtins;
186+
buffer[pc].operand = function_version;
185187
function_checked |= 1;
186188
}
187189
break;
@@ -203,7 +205,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
203205
}
204206
else {
205207
buffer[pc].opcode = _CHECK_FUNCTION;
206-
buffer[pc].operand = (uintptr_t)globals;
208+
buffer[pc].operand = function_version;
207209
function_checked |= 1;
208210
}
209211
break;
@@ -227,7 +229,8 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
227229
return 1;
228230
}
229231
assert(PyFunction_Check(func));
230-
if (prechecked_function_version == func->func_version) {
232+
function_version = func->func_version;
233+
if (prechecked_function_version == function_version) {
231234
function_checked |= 1;
232235
}
233236
prechecked_function_version = 0;
@@ -245,6 +248,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
245248
function_checked >>= 1;
246249
PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand;
247250
assert(PyFunction_Check(func));
251+
function_version = func->func_version;
248252
globals = func->func_globals;
249253
builtins = func->func_builtins;
250254
break;

0 commit comments

Comments
 (0)