gh-144569: Avoid creating temporary objects in BINARY_SLICE for list, tuple, and unicode (GH-144590)

* Scalar replacement of BINARY_SLICE for list, tuple, and unicode
This commit is contained in:
Hai Zhu 2026-03-03 01:02:38 +08:00 committed by GitHub
parent 1cf5abedeb
commit 107863ee17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 256 additions and 77 deletions

View file

@ -866,19 +866,30 @@ dummy_func(
}
op(_BINARY_SLICE, (container, start, stop -- res)) {
PyObject *slice = _PyBuildSlice_ConsumeRefs(PyStackRef_AsPyObjectSteal(start),
PyStackRef_AsPyObjectSteal(stop));
PyObject *container_o = PyStackRef_AsPyObjectBorrow(container);
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
PyObject *res_o;
// Can't use ERROR_IF() here, because we haven't
// DECREF'ed container yet, and we still own slice.
if (slice == NULL) {
res_o = NULL;
if (PyList_CheckExact(container_o)) {
res_o = _PyList_BinarySlice(container_o, start_o, stop_o);
}
else if (PyTuple_CheckExact(container_o)) {
res_o = _PyTuple_BinarySlice(container_o, start_o, stop_o);
}
else if (PyUnicode_CheckExact(container_o)) {
res_o = _PyUnicode_BinarySlice(container_o, start_o, stop_o);
}
else {
res_o = PyObject_GetItem(PyStackRef_AsPyObjectBorrow(container), slice);
Py_DECREF(slice);
PyObject *slice = PySlice_New(start_o, stop_o, NULL);
if (slice == NULL) {
res_o = NULL;
}
else {
res_o = PyObject_GetItem(container_o, slice);
Py_DECREF(slice);
}
}
PyStackRef_CLOSE(container);
DECREF_INPUTS();
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}