gh-143414: Implement unique reference tracking for JIT, optimize unpacking of such tuples (GH-144300)

Co-authored-by: Ken Jin <kenjin4096@gmail.com>
This commit is contained in:
reiden 2026-03-23 00:57:23 +08:00 committed by GitHub
parent 1ceb1fb284
commit e36f8db7e5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1414 additions and 911 deletions

View file

@ -33,7 +33,7 @@
#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs
#include "pycore_stackref.h"
#include "pycore_template.h" // _PyTemplate_Build()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
#include "pycore_tuple.h" // _PyStolenTuple_Free(), _PyTuple_ITEMS()
#include "pycore_typeobject.h" // _PySuper_Lookup()
#include "pycore_dict.h"
@ -1739,6 +1739,25 @@ dummy_func(
PyStackRef_CLOSE(seq);
}
op(_UNPACK_SEQUENCE_UNIQUE_TWO_TUPLE, (seq -- val1, val0)) {
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectSteal(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectSteal(PyTuple_GET_ITEM(seq_o, 1));
PyObject_GC_UnTrack(seq_o);
_PyStolenTuple_Free(seq_o);
}
op(_UNPACK_SEQUENCE_UNIQUE_THREE_TUPLE, (seq -- val2, val1, val0)) {
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
STAT_INC(UNPACK_SEQUENCE, hit);
val0 = PyStackRef_FromPyObjectSteal(PyTuple_GET_ITEM(seq_o, 0));
val1 = PyStackRef_FromPyObjectSteal(PyTuple_GET_ITEM(seq_o, 1));
val2 = PyStackRef_FromPyObjectSteal(PyTuple_GET_ITEM(seq_o, 2));
PyObject_GC_UnTrack(seq_o);
_PyStolenTuple_Free(seq_o);
}
macro(UNPACK_SEQUENCE_TUPLE) =
_GUARD_TOS_TUPLE + unused/1 + _UNPACK_SEQUENCE_TUPLE;
@ -1754,6 +1773,20 @@ dummy_func(
DECREF_INPUTS();
}
op(_UNPACK_SEQUENCE_UNIQUE_TUPLE, (seq -- values[oparg])) {
PyObject *seq_o = PyStackRef_AsPyObjectSteal(seq);
assert(PyTuple_CheckExact(seq_o));
assert(PyTuple_GET_SIZE(seq_o) == oparg);
assert(_PyObject_IsUniquelyReferenced(seq_o));
STAT_INC(UNPACK_SEQUENCE, hit);
PyObject **items = _PyTuple_ITEMS(seq_o);
for (int i = oparg; --i >= 0; ) {
*values++ = PyStackRef_FromPyObjectSteal(items[i]);
}
PyObject_GC_UnTrack(seq_o);
_PyStolenTuple_Free(seq_o);
}
macro(UNPACK_SEQUENCE_LIST) =
_GUARD_TOS_LIST + unused/1 + _UNPACK_SEQUENCE_LIST;