mirror of
https://github.com/python/cpython.git
synced 2025-11-01 14:11:41 +00:00
gh-138431: JIT Optimizer --- Fix round-tripping references for str and tuple (GH-138458)
Co-authored-by: Mark Shannon <9448417+markshannon@users.noreply.github.com>
This commit is contained in:
parent
0d1f4e1639
commit
2402f84665
5 changed files with 34 additions and 8 deletions
|
|
@ -251,6 +251,12 @@ PyJitRef_Wrap(JitOptSymbol *sym)
|
||||||
return (JitOptRef){.bits=(uintptr_t)sym};
|
return (JitOptRef){.bits=(uintptr_t)sym};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline JitOptRef
|
||||||
|
PyJitRef_StripReferenceInfo(JitOptRef ref)
|
||||||
|
{
|
||||||
|
return PyJitRef_Wrap(PyJitRef_Unwrap(ref));
|
||||||
|
}
|
||||||
|
|
||||||
static inline JitOptRef
|
static inline JitOptRef
|
||||||
PyJitRef_Borrow(JitOptRef ref)
|
PyJitRef_Borrow(JitOptRef ref)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2501,6 +2501,22 @@ def testfunc(n):
|
||||||
# For now... until we constant propagate it away.
|
# For now... until we constant propagate it away.
|
||||||
self.assertIn("_BINARY_OP", uops)
|
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):
|
def global_identity(x):
|
||||||
return x
|
return x
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Fix a bug in the JIT optimizer when round-tripping strings and tuples.
|
||||||
|
|
@ -762,9 +762,8 @@ dummy_func(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
op(_RETURN_VALUE, (retval -- res)) {
|
op(_RETURN_VALUE, (retval -- res)) {
|
||||||
// We wrap and unwrap the value to mimic PyStackRef_MakeHeapSafe
|
// Mimics PyStackRef_MakeHeapSafe in the interpreter.
|
||||||
// in bytecodes.c
|
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
|
||||||
JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
|
|
||||||
DEAD(retval);
|
DEAD(retval);
|
||||||
SAVE_STACK();
|
SAVE_STACK();
|
||||||
ctx->frame->stack_pointer = stack_pointer;
|
ctx->frame->stack_pointer = stack_pointer;
|
||||||
|
|
@ -925,7 +924,9 @@ dummy_func(void) {
|
||||||
op(_CALL_STR_1, (unused, unused, arg -- res)) {
|
op(_CALL_STR_1, (unused, unused, arg -- res)) {
|
||||||
if (sym_matches_type(arg, &PyUnicode_Type)) {
|
if (sym_matches_type(arg, &PyUnicode_Type)) {
|
||||||
// e.g. str('foo') or str(foo) where foo is known to be a string
|
// 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 {
|
else {
|
||||||
res = sym_new_type(ctx, &PyUnicode_Type);
|
res = sym_new_type(ctx, &PyUnicode_Type);
|
||||||
|
|
@ -1065,7 +1066,9 @@ dummy_func(void) {
|
||||||
op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
|
op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
|
||||||
if (sym_matches_type(arg, &PyTuple_Type)) {
|
if (sym_matches_type(arg, &PyTuple_Type)) {
|
||||||
// e.g. tuple((1, 2)) or tuple(foo) where foo is known to be a tuple
|
// 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 {
|
else {
|
||||||
res = sym_new_type(ctx, &PyTuple_Type);
|
res = sym_new_type(ctx, &PyTuple_Type);
|
||||||
|
|
|
||||||
6
Python/optimizer_cases.c.h
generated
6
Python/optimizer_cases.c.h
generated
|
|
@ -1060,7 +1060,7 @@
|
||||||
JitOptRef retval;
|
JitOptRef retval;
|
||||||
JitOptRef res;
|
JitOptRef res;
|
||||||
retval = stack_pointer[-1];
|
retval = stack_pointer[-1];
|
||||||
JitOptRef temp = PyJitRef_Wrap(PyJitRef_Unwrap(retval));
|
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
|
||||||
stack_pointer += -1;
|
stack_pointer += -1;
|
||||||
assert(WITHIN_STACK_BOUNDS());
|
assert(WITHIN_STACK_BOUNDS());
|
||||||
ctx->frame->stack_pointer = stack_pointer;
|
ctx->frame->stack_pointer = stack_pointer;
|
||||||
|
|
@ -2496,7 +2496,7 @@
|
||||||
JitOptRef res;
|
JitOptRef res;
|
||||||
arg = stack_pointer[-1];
|
arg = stack_pointer[-1];
|
||||||
if (sym_matches_type(arg, &PyUnicode_Type)) {
|
if (sym_matches_type(arg, &PyUnicode_Type)) {
|
||||||
res = arg;
|
res = PyJitRef_StripReferenceInfo(arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = sym_new_type(ctx, &PyUnicode_Type);
|
res = sym_new_type(ctx, &PyUnicode_Type);
|
||||||
|
|
@ -2522,7 +2522,7 @@
|
||||||
JitOptRef res;
|
JitOptRef res;
|
||||||
arg = stack_pointer[-1];
|
arg = stack_pointer[-1];
|
||||||
if (sym_matches_type(arg, &PyTuple_Type)) {
|
if (sym_matches_type(arg, &PyTuple_Type)) {
|
||||||
res = arg;
|
res = PyJitRef_StripReferenceInfo(arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res = sym_new_type(ctx, &PyTuple_Type);
|
res = sym_new_type(ctx, &PyTuple_Type);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue