mirror of
https://github.com/python/cpython.git
synced 2025-11-25 21:11:09 +00:00
gh-93143: Avoid NULL check in LOAD_FAST based on analysis in the compiler (GH-93144)
This commit is contained in:
parent
8a5e3c2ec6
commit
f425f3bb27
11 changed files with 371 additions and 52 deletions
|
|
@ -455,6 +455,26 @@ _PyFrame_GetState(PyFrameObject *frame)
|
|||
Py_UNREACHABLE();
|
||||
}
|
||||
|
||||
static void
|
||||
add_load_fast_null_checks(PyCodeObject *co)
|
||||
{
|
||||
_Py_CODEUNIT *instructions = _PyCode_CODE(co);
|
||||
for (Py_ssize_t i = 0; i < Py_SIZE(co); i++) {
|
||||
switch (_Py_OPCODE(instructions[i])) {
|
||||
case LOAD_FAST:
|
||||
case LOAD_FAST__LOAD_FAST:
|
||||
case LOAD_FAST__LOAD_CONST:
|
||||
_Py_SET_OPCODE(instructions[i], LOAD_FAST_CHECK);
|
||||
break;
|
||||
case LOAD_CONST__LOAD_FAST:
|
||||
_Py_SET_OPCODE(instructions[i], LOAD_CONST);
|
||||
break;
|
||||
case STORE_FAST__LOAD_FAST:
|
||||
_Py_SET_OPCODE(instructions[i], STORE_FAST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Setter for f_lineno - you can set f_lineno from within a trace function in
|
||||
* order to jump to a given line of code, subject to some restrictions. Most
|
||||
|
|
@ -545,6 +565,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
|||
return -1;
|
||||
}
|
||||
|
||||
add_load_fast_null_checks(f->f_frame->f_code);
|
||||
|
||||
/* PyCode_NewWithPosOnlyArgs limits co_code to be under INT_MAX so this
|
||||
* should never overflow. */
|
||||
int len = (int)Py_SIZE(f->f_frame->f_code);
|
||||
|
|
@ -1047,6 +1069,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
|
|||
}
|
||||
fast = _PyFrame_GetLocalsArray(frame);
|
||||
co = frame->f_code;
|
||||
bool added_null_checks = false;
|
||||
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
|
|
@ -1066,6 +1089,10 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear)
|
|||
}
|
||||
}
|
||||
PyObject *oldvalue = fast[i];
|
||||
if (!added_null_checks && oldvalue != NULL && value == NULL) {
|
||||
add_load_fast_null_checks(co);
|
||||
added_null_checks = true;
|
||||
}
|
||||
PyObject *cell = NULL;
|
||||
if (kind == CO_FAST_FREE) {
|
||||
// The cell was set when the frame was created from
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue