mirror of
https://github.com/python/cpython.git
synced 2026-01-04 14:32:21 +00:00
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>
This commit is contained in:
parent
74330d992b
commit
8810e286fa
8 changed files with 108 additions and 29 deletions
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
9
Python/executor_cases.c.h
generated
9
Python/executor_cases.c.h
generated
|
|
@ -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());
|
||||
|
|
|
|||
9
Python/generated_cases.c.h
generated
9
Python/generated_cases.c.h
generated
|
|
@ -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());
|
||||
|
|
|
|||
8
Python/optimizer_cases.c.h
generated
8
Python/optimizer_cases.c.h
generated
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue