diff options
author | Dennis Sweeney <36520290+sweeneyde@users.noreply.github.com> | 2022-05-31 20:32:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-31 20:32:30 (GMT) |
commit | f425f3bb27e826d25aac05139360cc6aa279126e (patch) | |
tree | 221a478440fd429943409605bbf8dcaf9bb9c6ee /Objects/frameobject.c | |
parent | 8a5e3c2ec6254b2ce06d17545f58a6719e0c8fdb (diff) | |
download | cpython-f425f3bb27e826d25aac05139360cc6aa279126e.zip cpython-f425f3bb27e826d25aac05139360cc6aa279126e.tar.gz cpython-f425f3bb27e826d25aac05139360cc6aa279126e.tar.bz2 |
gh-93143: Avoid NULL check in LOAD_FAST based on analysis in the compiler (GH-93144)
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r-- | Objects/frameobject.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 60f0f2f..a448ba3 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -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 |