summaryrefslogtreecommitdiffstats
path: root/Python/optimizer_analysis.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/optimizer_analysis.c')
-rw-r--r--Python/optimizer_analysis.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c
index 18e3382..0f25527 100644
--- a/Python/optimizer_analysis.c
+++ b/Python/optimizer_analysis.c
@@ -154,10 +154,10 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
/* These values represent stacks of booleans (one bool per bit).
* Pushing a frame shifts left, popping a frame shifts right. */
- uint32_t builtins_checked = 0;
+ uint32_t function_checked = 0;
uint32_t builtins_watched = 0;
- uint32_t globals_checked = 0;
uint32_t globals_watched = 0;
+ uint32_t prechecked_function_version = 0;
if (interp->dict_state.watchers[GLOBALS_WATCHER_ID] == NULL) {
interp->dict_state.watchers[GLOBALS_WATCHER_ID] = globals_watcher_callback;
}
@@ -176,13 +176,13 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
PyDict_Watch(BUILTINS_WATCHER_ID, builtins);
builtins_watched |= 1;
}
- if (builtins_checked & 1) {
+ if (function_checked & 1) {
buffer[pc].opcode = NOP;
}
else {
- buffer[pc].opcode = _CHECK_BUILTINS;
+ buffer[pc].opcode = _CHECK_FUNCTION;
buffer[pc].operand = (uintptr_t)builtins;
- builtins_checked |= 1;
+ function_checked |= 1;
}
break;
case _GUARD_GLOBALS_VERSION:
@@ -198,36 +198,39 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
_Py_BloomFilter_Add(dependencies, globals);
globals_watched |= 1;
}
- if (globals_checked & 1) {
+ if (function_checked & 1) {
buffer[pc].opcode = NOP;
}
else {
- buffer[pc].opcode = _CHECK_GLOBALS;
+ buffer[pc].opcode = _CHECK_FUNCTION;
buffer[pc].operand = (uintptr_t)globals;
- globals_checked |= 1;
+ function_checked |= 1;
}
break;
case _LOAD_GLOBAL_BUILTINS:
- if (globals_checked & builtins_checked & globals_watched & builtins_watched & 1) {
+ if (function_checked & globals_watched & builtins_watched & 1) {
convert_global_to_const(inst, builtins);
}
break;
case _LOAD_GLOBAL_MODULE:
- if (globals_checked & globals_watched & 1) {
+ if (function_checked & globals_watched & 1) {
convert_global_to_const(inst, globals);
}
break;
case _PUSH_FRAME:
{
- globals_checked <<= 1;
- globals_watched <<= 1;
- builtins_checked <<= 1;
builtins_watched <<= 1;
+ globals_watched <<= 1;
+ function_checked <<= 1;
PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand;
if (func == NULL) {
return 1;
}
assert(PyFunction_Check(func));
+ if (prechecked_function_version == func->func_version) {
+ function_checked |= 1;
+ }
+ prechecked_function_version = 0;
globals = func->func_globals;
builtins = func->func_builtins;
if (builtins != interp->builtins) {
@@ -237,16 +240,18 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
}
case _POP_FRAME:
{
- globals_checked >>= 1;
- globals_watched >>= 1;
- builtins_checked >>= 1;
builtins_watched >>= 1;
+ globals_watched >>= 1;
+ function_checked >>= 1;
PyFunctionObject *func = (PyFunctionObject *)buffer[pc].operand;
assert(PyFunction_Check(func));
globals = func->func_globals;
builtins = func->func_builtins;
break;
}
+ case _CHECK_FUNCTION_EXACT_ARGS:
+ prechecked_function_version = (uint32_t)buffer[pc].operand;
+ break;
default:
if (op_is_end(opcode)) {
return 1;