Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Include/internal/pycore_optimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ PyJitRef_Wrap(JitOptSymbol *sym)
return (JitOptRef){.bits=(uintptr_t)sym};
}

static inline JitOptRef
PyJitRef_StripReferenceInfo(JitOptRef ref)
{
return PyJitRef_Wrap(PyJitRef_Unwrap(ref));
}

static inline JitOptRef
PyJitRef_Borrow(JitOptRef ref)
{
Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2501,6 +2501,22 @@ def testfunc(n):
# For now... until we constant propagate it away.
self.assertIn("_BINARY_OP", uops)

def test_reference_tracking_across_call_doesnt_crash(self):

def f1():
for _ in range(TIER2_THRESHOLD + 1):
# Choose a value that won't occur elsewhere to avoid sharing
str("value that won't occur elsewhere to avoid sharing")

f1()

def f2():
for _ in range(TIER2_THRESHOLD + 1):
# Choose a value that won't occur elsewhere to avoid sharing
tuple((31, -17, 25, "won't occur elsewhere"))

f2()


def global_identity(x):
return x
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug in the JIT optimizer when round-tripping strings and tuples.
13 changes: 8 additions & 5 deletions Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,9 +762,8 @@ dummy_func(void) {
}

op(_RETURN_VALUE, (retval -- res)) {
// We wrap and unwrap the value to mimic PyStackRef_MakeHeapSafe
// in bytecodes.c
JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
// Mimics PyStackRef_MakeHeapSafe in the interpreter.
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
DEAD(retval);
SAVE_STACK();
ctx->frame->stack_pointer = stack_pointer;
Expand Down Expand Up @@ -925,7 +924,9 @@ dummy_func(void) {
op(_CALL_STR_1, (unused, unused, arg -- res)) {
if (sym_matches_type(arg, &PyUnicode_Type)) {
// e.g. str('foo') or str(foo) where foo is known to be a string
res = arg;
// Note: we must strip the reference information because it goes
// through str() which strips the reference information from it.
res = PyJitRef_StripReferenceInfo(arg);
}
else {
res = sym_new_type(ctx, &PyUnicode_Type);
Expand Down Expand Up @@ -1065,7 +1066,9 @@ dummy_func(void) {
op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
if (sym_matches_type(arg, &PyTuple_Type)) {
// e.g. tuple((1, 2)) or tuple(foo) where foo is known to be a tuple
res = arg;
// Note: we must strip the reference information because it goes
// through tuple() which strips the reference information from it.
res = PyJitRef_StripReferenceInfo(arg);
}
else {
res = sym_new_type(ctx, &PyTuple_Type);
Expand Down
6 changes: 3 additions & 3 deletions Python/optimizer_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading