diff options
author | Ken Jin <kenjin@python.org> | 2024-09-13 16:23:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-13 16:23:51 (GMT) |
commit | 8810e286fa48876422d1b230208911decbead294 (patch) | |
tree | 0d171d70418884104b8681e0e7492d136b8b6778 /Python | |
parent | 74330d992be26829dba65ab83d698d42b2f2a2ee (diff) | |
download | cpython-8810e286fa48876422d1b230208911decbead294.zip cpython-8810e286fa48876422d1b230208911decbead294.tar.gz cpython-8810e286fa48876422d1b230208911decbead294.tar.bz2 |
gh-121459: Deferred LOAD_GLOBAL (GH-123128)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Sam Gross <655866+colesbury@users.noreply.github.com>
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 12 | ||||
-rw-r--r-- | Python/ceval.c | 20 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 9 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 9 | ||||
-rw-r--r-- | Python/optimizer_cases.c.h | 8 |
5 files changed, 30 insertions, 28 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 078f06d..846404e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1469,8 +1469,8 @@ dummy_func( && PyDict_CheckExact(BUILTINS())) { v_o = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); + (PyDictObject *)BUILTINS(), + name); if (v_o == NULL) { if (!_PyErr_Occurred(tstate)) { /* _PyDict_LoadGlobal() returns NULL without raising @@ -1526,12 +1526,12 @@ dummy_func( #endif /* ENABLE_SPECIALIZATION */ } - op(_LOAD_GLOBAL, ( -- res, null if (oparg & 1))) { + // res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef + op(_LOAD_GLOBAL, ( -- res[1], null if (oparg & 1))) { PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - PyObject *res_o = _PyEval_LoadGlobal(GLOBALS(), BUILTINS(), name); - ERROR_IF(res_o == NULL, error); + _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); + ERROR_IF(PyStackRef_IsNull(*res), error); null = PyStackRef_NULL; - res = PyStackRef_FromPyObjectSteal(res_o); } macro(LOAD_GLOBAL) = diff --git a/Python/ceval.c b/Python/ceval.c index 252833a..6236c66 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3110,15 +3110,14 @@ _PyEval_GetANext(PyObject *aiter) return awaitable; } -PyObject * -_PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name) +void +_PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name, _PyStackRef *writeto) { - PyObject *res; if (PyDict_CheckExact(globals) && PyDict_CheckExact(builtins)) { - res = _PyDict_LoadGlobal((PyDictObject *)globals, + _PyDict_LoadGlobalStackRef((PyDictObject *)globals, (PyDictObject *)builtins, - name); - if (res == NULL && !PyErr_Occurred()) { + name, writeto); + if (PyStackRef_IsNull(*writeto) && !PyErr_Occurred()) { /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ _PyEval_FormatExcCheckArg(PyThreadState_GET(), PyExc_NameError, @@ -3128,13 +3127,16 @@ _PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name) else { /* Slow-path if globals or builtins is not a dict */ /* namespace 1: globals */ + PyObject *res; if (PyMapping_GetOptionalItem(globals, name, &res) < 0) { - return NULL; + *writeto = PyStackRef_NULL; + return; } if (res == NULL) { /* namespace 2: builtins */ if (PyMapping_GetOptionalItem(builtins, name, &res) < 0) { - return NULL; + *writeto = PyStackRef_NULL; + return; } if (res == NULL) { _PyEval_FormatExcCheckArg( @@ -3142,8 +3144,8 @@ _PyEval_LoadGlobal(PyObject *globals, PyObject *builtins, PyObject *name) NAME_ERROR_MSG, name); } } + *writeto = PyStackRef_FromPyObjectSteal(res); } - return res; } PyObject * diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index b36fff9..93ab068 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1661,15 +1661,14 @@ } case _LOAD_GLOBAL: { - _PyStackRef res; + _PyStackRef *res; _PyStackRef null = PyStackRef_NULL; oparg = CURRENT_OPARG(); + res = &stack_pointer[0]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - PyObject *res_o = _PyEval_LoadGlobal(GLOBALS(), BUILTINS(), name); - if (res_o == NULL) JUMP_TO_ERROR(); + _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); + if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR(); null = PyStackRef_NULL; - res = PyStackRef_FromPyObjectSteal(res_o); - stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + (oparg & 1); assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 3e9f039..6d902e2 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5674,7 +5674,7 @@ PREDICTED(LOAD_GLOBAL); _Py_CODEUNIT *this_instr = next_instr - 5; (void)this_instr; - _PyStackRef res; + _PyStackRef *res; _PyStackRef null = PyStackRef_NULL; // _SPECIALIZE_LOAD_GLOBAL { @@ -5696,13 +5696,12 @@ /* Skip 1 cache entry */ // _LOAD_GLOBAL { + res = &stack_pointer[0]; PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); - PyObject *res_o = _PyEval_LoadGlobal(GLOBALS(), BUILTINS(), name); - if (res_o == NULL) goto error; + _PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res); + if (PyStackRef_IsNull(*res)) goto error; null = PyStackRef_NULL; - res = PyStackRef_FromPyObjectSteal(res_o); } - stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + (oparg & 1); assert(WITHIN_STACK_BOUNDS()); diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index e89c969..a6cfa27 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -829,11 +829,13 @@ } case _LOAD_GLOBAL: { - _Py_UopsSymbol *res; + _Py_UopsSymbol **res; _Py_UopsSymbol *null = NULL; - res = sym_new_not_null(ctx); + res = &stack_pointer[0]; + for (int _i = 1; --_i >= 0;) { + res[_i] = sym_new_not_null(ctx); + } null = sym_new_null(ctx); - stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; stack_pointer += 1 + (oparg & 1); assert(WITHIN_STACK_BOUNDS()); |