summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorKen Jin <kenjin@python.org>2024-09-13 16:23:51 (GMT)
committerGitHub <noreply@github.com>2024-09-13 16:23:51 (GMT)
commit8810e286fa48876422d1b230208911decbead294 (patch)
tree0d171d70418884104b8681e0e7492d136b8b6778 /Python
parent74330d992be26829dba65ab83d698d42b2f2a2ee (diff)
downloadcpython-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.c12
-rw-r--r--Python/ceval.c20
-rw-r--r--Python/executor_cases.c.h9
-rw-r--r--Python/generated_cases.c.h9
-rw-r--r--Python/optimizer_cases.c.h8
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());