Skip to content

Commit 8cc4cc6

Browse files
author
aleksandr.tseluyko
committed
gh-145860: Eliminate unnecessary refcount ops in BUILD_INTERPOLATION/BUILD_TEMPLATE
Make _PyInterpolation_Build and _PyTemplate_Build steal references to their arguments instead of borrowing and incref'ing them. This avoids redundant incref/decref pairs in the bytecode handlers, matching the pattern already used by all other BUILD instructions.
1 parent 5e9d90b commit 8cc4cc6

7 files changed

Lines changed: 56 additions & 141 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Eliminate unnecessary reference count operations in ``BUILD_INTERPOLATION``
2+
and ``BUILD_TEMPLATE`` bytecode instructions by making
3+
:c:func:`!_PyInterpolation_Build` and :c:func:`!_PyTemplate_Build` steal
4+
references to their arguments.

Modules/_testinternalcapi/test_cases.c.h

Lines changed: 10 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/interpolationobject.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,15 @@ _PyInterpolation_Build(PyObject *value, PyObject *str, int conversion, PyObject
190190
{
191191
interpolationobject *interpolation = PyObject_GC_New(interpolationobject, &_PyInterpolation_Type);
192192
if (!interpolation) {
193+
Py_DECREF(value);
194+
Py_DECREF(str);
195+
Py_DECREF(format_spec);
193196
return NULL;
194197
}
195198

196-
interpolation->value = Py_NewRef(value);
197-
interpolation->expression = Py_NewRef(str);
198-
interpolation->format_spec = Py_NewRef(format_spec);
199+
interpolation->value = value;
200+
interpolation->expression = str;
201+
interpolation->format_spec = format_spec;
199202
interpolation->conversion = NULL;
200203

201204
if (conversion == 0) {

Objects/templateobject.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,7 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
176176
PyTuple_SET_ITEM(strings, stringsidx++, &_Py_STR(empty));
177177
}
178178

179-
PyObject *template = _PyTemplate_Build(strings, interpolations);
180-
Py_DECREF(strings);
181-
Py_DECREF(interpolations);
182-
return template;
179+
return _PyTemplate_Build(strings, interpolations);
183180
}
184181

185182
static void
@@ -292,10 +289,7 @@ template_concat_templates(templateobject *self, templateobject *other)
292289
return NULL;
293290
}
294291

295-
PyObject *newtemplate = _PyTemplate_Build(newstrings, newinterpolations);
296-
Py_DECREF(newstrings);
297-
Py_DECREF(newinterpolations);
298-
return newtemplate;
292+
return _PyTemplate_Build(newstrings, newinterpolations);
299293
}
300294

301295
PyObject *
@@ -402,11 +396,13 @@ _PyTemplate_Build(PyObject *strings, PyObject *interpolations)
402396
{
403397
templateobject *template = PyObject_GC_New(templateobject, &_PyTemplate_Type);
404398
if (template == NULL) {
399+
Py_DECREF(strings);
400+
Py_DECREF(interpolations);
405401
return NULL;
406402
}
407403

408-
template->strings = Py_NewRef(strings);
409-
template->interpolations = Py_NewRef(interpolations);
404+
template->strings = strings;
405+
template->interpolations = interpolations;
410406
PyObject_GC_Track(template);
411407
return (PyObject *) template;
412408
}

Python/bytecodes.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,35 +2329,31 @@ dummy_func(
23292329
}
23302330

23312331
inst(BUILD_INTERPOLATION, (value, str, format[oparg & 1] -- interpolation)) {
2332-
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
2333-
PyObject *str_o = PyStackRef_AsPyObjectBorrow(str);
2332+
PyObject *value_o = PyStackRef_AsPyObjectSteal(value);
2333+
DEAD(value);
2334+
PyObject *str_o = PyStackRef_AsPyObjectSteal(str);
2335+
DEAD(str);
23342336
int conversion = oparg >> 2;
23352337
PyObject *format_o;
23362338
if (oparg & 1) {
2337-
format_o = PyStackRef_AsPyObjectBorrow(format[0]);
2338-
}
2339-
else {
2340-
format_o = &_Py_STR(empty);
2341-
}
2342-
PyObject *interpolation_o = _PyInterpolation_Build(value_o, str_o, conversion, format_o);
2343-
if (oparg & 1) {
2344-
PyStackRef_CLOSE(format[0]);
2339+
format_o = PyStackRef_AsPyObjectSteal(format[0]);
2340+
DEAD(format);
23452341
}
23462342
else {
2343+
format_o = Py_NewRef(&_Py_STR(empty));
23472344
DEAD(format);
23482345
}
2349-
PyStackRef_CLOSE(str);
2350-
PyStackRef_CLOSE(value);
2346+
PyObject *interpolation_o = _PyInterpolation_Build(value_o, str_o, conversion, format_o);
23512347
ERROR_IF(interpolation_o == NULL);
23522348
interpolation = PyStackRef_FromPyObjectSteal(interpolation_o);
23532349
}
23542350

23552351
inst(BUILD_TEMPLATE, (strings, interpolations -- template)) {
2356-
PyObject *strings_o = PyStackRef_AsPyObjectBorrow(strings);
2357-
PyObject *interpolations_o = PyStackRef_AsPyObjectBorrow(interpolations);
2352+
PyObject *strings_o = PyStackRef_AsPyObjectSteal(strings);
2353+
DEAD(strings);
2354+
PyObject *interpolations_o = PyStackRef_AsPyObjectSteal(interpolations);
2355+
DEAD(interpolations);
23582356
PyObject *template_o = _PyTemplate_Build(strings_o, interpolations_o);
2359-
PyStackRef_CLOSE(interpolations);
2360-
PyStackRef_CLOSE(strings);
23612357
ERROR_IF(template_o == NULL);
23622358
template = PyStackRef_FromPyObjectSteal(template_o);
23632359
}

Python/executor_cases.c.h

Lines changed: 8 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 10 additions & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)