-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
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
Disabling the uop optimizer leads to crashes #127083
Comments
For what it's worth, there seem to be a number of tests which cause this failure. Below is a list of tests, and the final UOp that fails to be added, with the message Note that a few of the tests don't seem to show this kind of error, but instead underflow the trace stack.
|
Here's a simpler (if slightly cursed) reproducer: # foo.py
def foo():
# Padding to increase number of UOps in trace
_ = reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
reversed(list(reversed(list(reversed(list(reversed(list(reversed(list(
[0]
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))
for _ in range(4096): #Minimum value
foo() ./configure --enable-experimental-jit --with-pydebug
make
PYTHON_UOPS_OPTIMIZE=0 PYTHON_LLTRACE=1 ./python foo.py
|
Thanks @JeffersGlass! I talked with @markshannon, and we think it's probably worth reworking Here's some pseudocode to capture the general idea: buffer = [None] * MAX_TRACE_LENGTH
space_remaining = MAX_TRACE_LENGTH
last_complete = 0
index = 0
def add_uop(uop):
if space_remaining <= 0:
raise OutOfSpace
buffer[index] = uop
space_remaining -= 1
index += 1
# Save room for final _CHECK_VALIDITY_AND_SET_IP + _EXIT_TRACE:
space_remaining -= 2
add_uop(_START_EXECUTOR)
add_uop(_MAKE_WARM)
try:
for instruction in bytecode:
if has_error(instruction):
# Save room for error stub:
space_remaining -= 1
if has_exit(instruction):
# Save room for exit stub:
space_remaining -= 1
add_uop(_CHECK_VALIDITY_AND_SET_IP)
for uop in uop_expansion(instruction):
add_uop(uop)
# Successfully translated the entire instruction:
last_complete = index - 1
except OutOfSpace:
index = last_complete
add_uop(_CHECK_VALIDITY_AND_SET_IP)
add_uop(_EXIT_TRACE) |
Crash report
When running:
On a debug build, we get an assertion failure:
On a non-debug build, we get a buffer overflow:
It looks like the optimizer just happens to do enough useful work that adding error and exit stubs doesn't put us over
UOP_MAX_TRACE_LENGTH
anymore. My hunch is that the real bug is intranslate_bytecode_to_trace
, where we're not reserving enough space for some instruction(s).CC @Fidget-Spinner and @markshannon.
The text was updated successfully, but these errors were encountered: