-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-121459: Deferred LOAD_GLOBAL #123128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-121459: Deferred LOAD_GLOBAL #123128
Changes from 17 commits
803e9f7
b213b6f
11d2fb6
ea8d855
af0c032
1a431de
48bebe9
6e948b4
e23567a
dbbebf9
dbdee10
6d176c0
4ff9f17
c644ebf
64f932a
bfd4400
0c1ee7e
ad33dd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -1448,8 +1448,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 | ||||||
|
@@ -1507,10 +1507,9 @@ dummy_func( | |||||
|
||||||
op(_LOAD_GLOBAL, ( -- res, 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, &STACK_ENTRY(res)); | ||||||
|
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, &STACK_ENTRY(res)); | |
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, &res[0])); |
Can we go back to the earlier design of making res
an array?
Please also add a comment explaining why we res
needs to be trated specially (we need pass a pointer to _PyEval_LoadGlobalStackRef
).
The code generator already understands arrays, and it avoids confusion as to where it should insert stack spills for fully deferred reference counting.
You'll able to remove def stack_entry
below.
Sorry for the back and forth on this.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,6 +77,7 @@ def __init__(self, out: CWriter): | |
"DECREF_INPUTS": self.decref_inputs, | ||
"SYNC_SP": self.sync_sp, | ||
"PyStackRef_FromPyObjectNew": self.py_stack_ref_from_py_object_new, | ||
"STACK_ENTRY": self.stack_entry, | ||
} | ||
self.out = out | ||
|
||
|
@@ -211,6 +212,37 @@ def py_stack_ref_from_py_object_new( | |
# unused portions of the stack to NULL. | ||
stack.flush_single_var(self.out, target, uop.stack.outputs) | ||
|
||
def stack_entry( | ||
|
||
self, | ||
tkn: Token, | ||
tkn_iter: Iterator[Token], | ||
uop: Uop, | ||
stack: Stack, | ||
inst: Instruction | None, | ||
) -> None: | ||
emit_to(self.out, tkn_iter, "LPAREN") | ||
target = next(tkn_iter) | ||
size = "0" | ||
for output in uop.stack.inputs: | ||
size += f" - {output.size or 1}" | ||
for output in uop.stack.outputs: | ||
if output.name == target.text: | ||
self.out.emit(f"stack_pointer[{size}]") | ||
break | ||
size += f" + {output.size or 1}" | ||
else: | ||
raise analysis_error("STACK_ENTRY operand is not a stack output", target) | ||
|
||
next(tkn_iter) # Consume ) | ||
# Emit all the way to SEMI | ||
for tkn in tkn_iter: | ||
self.out.emit(tkn) | ||
if tkn.kind == "SEMI": | ||
break | ||
self.emit("\n") | ||
# Update the variable | ||
self.out.emit(f"{target.text} = stack_pointer[{size}];\n") | ||
|
||
def emit_tokens( | ||
self, | ||
uop: Uop, | ||
|
Uh oh!
There was an error while loading. Please reload this page.