Skip to content

Commit 9807521

Browse files
committed
Remove explicit loops for clearing array inputs
1 parent 1fb15e3 commit 9807521

File tree

4 files changed

+186
-204
lines changed

4 files changed

+186
-204
lines changed

Python/bytecodes.c

Lines changed: 42 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,9 +1885,8 @@ dummy_func(
18851885
if (err == 0) {
18861886
err = PySet_Add(set_o, PyStackRef_AsPyObjectBorrow(values[i]));
18871887
}
1888-
PyStackRef_CLOSE(values[i]);
18891888
}
1890-
DEAD(values);
1889+
DECREF_INPUTS();
18911890
if (err != 0) {
18921891
Py_DECREF(set_o);
18931892
ERROR_IF(true, error);
@@ -3435,8 +3434,9 @@ dummy_func(
34353434

34363435
// oparg counts all of the args, but *not* self:
34373436
int total_args = oparg;
3437+
_PyStackRef *arguments = args;
34383438
if (!PyStackRef_IsNull(self_or_null[0])) {
3439-
args--;
3439+
arguments--;
34403440
total_args++;
34413441
}
34423442
// Check if the call can be inlined or not
@@ -3448,7 +3448,7 @@ dummy_func(
34483448
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
34493449
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
34503450
tstate, callable[0], locals,
3451-
args, total_args, NULL, frame
3451+
arguments, total_args, NULL, frame
34523452
);
34533453
// Manipulate stack directly since we leave using DISPATCH_INLINED().
34543454
SYNC_SP();
@@ -3461,13 +3461,9 @@ dummy_func(
34613461
DISPATCH_INLINED(new_frame);
34623462
}
34633463
/* Callable is not a normal Python function */
3464-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
3464+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
34653465
if (CONVERSION_FAILED(args_o)) {
3466-
for (int i = 0; i < total_args; i++) {
3467-
PyStackRef_CLOSE(args[i]);
3468-
}
3469-
DEAD(self_or_null);
3470-
PyStackRef_CLOSE(callable[0]);
3466+
DECREF_INPUTS();
34713467
ERROR_IF(true, error);
34723468
}
34733469
PyObject *res_o = PyObject_Vectorcall(
@@ -3477,7 +3473,7 @@ dummy_func(
34773473
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
34783474
if (opcode == INSTRUMENTED_CALL) {
34793475
PyObject *arg = total_args == 0 ?
3480-
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(args[0]);
3476+
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
34813477
if (res_o == NULL) {
34823478
_Py_call_instrumentation_exc2(
34833479
tstate, PY_MONITORING_EVENT_C_RAISE,
@@ -3493,11 +3489,7 @@ dummy_func(
34933489
}
34943490
}
34953491
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
3496-
for (int i = 0; i < total_args; i++) {
3497-
PyStackRef_CLOSE(args[i]);
3498-
}
3499-
DEAD(self_or_null);
3500-
PyStackRef_CLOSE(callable[0]);
3492+
DECREF_INPUTS();
35013493
ERROR_IF(res_o == NULL, error);
35023494
res = PyStackRef_FromPyObjectSteal(res_o);
35033495
}
@@ -3617,12 +3609,13 @@ dummy_func(
36173609
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
36183610

36193611
int total_args = oparg;
3612+
_PyStackRef *arguments = args;
36203613
if (!PyStackRef_IsNull(self_or_null[0])) {
3621-
args--;
3614+
arguments--;
36223615
total_args++;
36233616
}
36243617
/* Callable is not a normal Python function */
3625-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
3618+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
36263619
if (CONVERSION_FAILED(args_o)) {
36273620
DECREF_INPUTS();
36283621
ERROR_IF(true, error);
@@ -3633,11 +3626,7 @@ dummy_func(
36333626
NULL);
36343627
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
36353628
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
3636-
for (int i = 0; i < total_args; i++) {
3637-
PyStackRef_CLOSE(args[i]);
3638-
}
3639-
DEAD(self_or_null);
3640-
PyStackRef_CLOSE(callable[0]);
3629+
DECREF_INPUTS();
36413630
ERROR_IF(res_o == NULL, error);
36423631
res = PyStackRef_FromPyObjectSteal(res_o);
36433632
}
@@ -3877,15 +3866,9 @@ dummy_func(
38773866
DECREF_INPUTS();
38783867
ERROR_IF(true, error);
38793868
}
3880-
DEAD(self_or_null);
38813869
PyObject *res_o = tp->tp_vectorcall((PyObject *)tp, args_o, total_args, NULL);
38823870
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
3883-
/* Free the arguments. */
3884-
for (int i = 0; i < total_args; i++) {
3885-
PyStackRef_CLOSE(arguments[i]);
3886-
}
3887-
DEAD(args);
3888-
PyStackRef_CLOSE(callable[0]);
3871+
DECREF_INPUTS();
38893872
ERROR_IF(res_o == NULL, error);
38903873
res = PyStackRef_FromPyObjectSteal(res_o);
38913874
}
@@ -3952,20 +3935,13 @@ dummy_func(
39523935
DECREF_INPUTS();
39533936
ERROR_IF(true, error);
39543937
}
3955-
DEAD(self_or_null);
39563938
PyObject *res_o = ((PyCFunctionFast)(void(*)(void))cfunc)(
39573939
PyCFunction_GET_SELF(callable_o),
39583940
args_o,
39593941
total_args);
39603942
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
39613943
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
3962-
3963-
/* Free the arguments. */
3964-
for (int i = 0; i < total_args; i++) {
3965-
PyStackRef_CLOSE(arguments[i]);
3966-
}
3967-
DEAD(args);
3968-
PyStackRef_CLOSE(callable[0]);
3944+
DECREF_INPUTS();
39693945
ERROR_IF(res_o == NULL, error);
39703946
res = PyStackRef_FromPyObjectSteal(res_o);
39713947
}
@@ -3981,34 +3957,28 @@ dummy_func(
39813957
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
39823958

39833959
int total_args = oparg;
3960+
_PyStackRef *arguments = args;
39843961
if (!PyStackRef_IsNull(self_or_null[0])) {
3985-
args--;
3962+
arguments--;
39863963
total_args++;
39873964
}
39883965
DEOPT_IF(!PyCFunction_CheckExact(callable_o));
39893966
DEOPT_IF(PyCFunction_GET_FLAGS(callable_o) != (METH_FASTCALL | METH_KEYWORDS));
39903967
STAT_INC(CALL, hit);
3991-
/* res = func(self, args, nargs, kwnames) */
3968+
/* res = func(self, arguments, nargs, kwnames) */
39923969
PyCFunctionFastWithKeywords cfunc =
39933970
(PyCFunctionFastWithKeywords)(void(*)(void))
39943971
PyCFunction_GET_FUNCTION(callable_o);
39953972

3996-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
3973+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
39973974
if (CONVERSION_FAILED(args_o)) {
39983975
DECREF_INPUTS();
39993976
ERROR_IF(true, error);
40003977
}
40013978
PyObject *res_o = cfunc(PyCFunction_GET_SELF(callable_o), args_o, total_args, NULL);
40023979
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
4003-
40043980
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4005-
4006-
/* Free the arguments. */
4007-
for (int i = 0; i < total_args; i++) {
4008-
PyStackRef_CLOSE(args[i]);
4009-
}
4010-
DEAD(self_or_null);
4011-
PyStackRef_CLOSE(callable[0]);
3981+
DECREF_INPUTS();
40123982
ERROR_IF(res_o == NULL, error);
40133983
res = PyStackRef_FromPyObjectSteal(res_o);
40143984
}
@@ -4147,21 +4117,22 @@ dummy_func(
41474117
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
41484118

41494119
int total_args = oparg;
4120+
_PyStackRef *arguments = args;
41504121
if (!PyStackRef_IsNull(self_or_null[0])) {
4151-
args--;
4122+
arguments--;
41524123
total_args++;
41534124
}
41544125
PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o;
41554126
EXIT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type));
41564127
PyMethodDef *meth = method->d_method;
41574128
EXIT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS));
41584129
PyTypeObject *d_type = method->d_common.d_type;
4159-
PyObject *self = PyStackRef_AsPyObjectBorrow(args[0]);
4130+
PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]);
41604131
EXIT_IF(!Py_IS_TYPE(self, d_type));
41614132
STAT_INC(CALL, hit);
41624133
int nargs = total_args - 1;
41634134

4164-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
4135+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
41654136
if (CONVERSION_FAILED(args_o)) {
41664137
DECREF_INPUTS();
41674138
ERROR_IF(true, error);
@@ -4171,13 +4142,7 @@ dummy_func(
41714142
PyObject *res_o = cfunc(self, (args_o + 1), nargs, NULL);
41724143
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
41734144
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4174-
4175-
/* Free the arguments. */
4176-
for (int i = 0; i < total_args; i++) {
4177-
PyStackRef_CLOSE(args[i]);
4178-
}
4179-
DEAD(self_or_null);
4180-
PyStackRef_CLOSE(callable[0]);
4145+
DECREF_INPUTS();
41814146
ERROR_IF(res_o == NULL, error);
41824147
res = PyStackRef_FromPyObjectSteal(res_o);
41834148
}
@@ -4231,21 +4196,22 @@ dummy_func(
42314196
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
42324197

42334198
int total_args = oparg;
4199+
_PyStackRef *arguments = args;
42344200
if (!PyStackRef_IsNull(self_or_null[0])) {
4235-
args--;
4201+
arguments--;
42364202
total_args++;
42374203
}
42384204
PyMethodDescrObject *method = (PyMethodDescrObject *)callable_o;
42394205
/* Builtin METH_FASTCALL methods, without keywords */
42404206
EXIT_IF(!Py_IS_TYPE(method, &PyMethodDescr_Type));
42414207
PyMethodDef *meth = method->d_method;
42424208
EXIT_IF(meth->ml_flags != METH_FASTCALL);
4243-
PyObject *self = PyStackRef_AsPyObjectBorrow(args[0]);
4209+
PyObject *self = PyStackRef_AsPyObjectBorrow(arguments[0]);
42444210
EXIT_IF(!Py_IS_TYPE(self, method->d_common.d_type));
42454211
STAT_INC(CALL, hit);
42464212
int nargs = total_args - 1;
42474213

4248-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
4214+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
42494215
if (CONVERSION_FAILED(args_o)) {
42504216
DECREF_INPUTS();
42514217
ERROR_IF(true, error);
@@ -4255,13 +4221,7 @@ dummy_func(
42554221
PyObject *res_o = cfunc(self, (args_o + 1), nargs);
42564222
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
42574223
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4258-
4259-
/* Clear the stack of the arguments. */
4260-
for (int i = 0; i < total_args; i++) {
4261-
PyStackRef_CLOSE(args[i]);
4262-
}
4263-
DEAD(self_or_null);
4264-
PyStackRef_CLOSE(callable[0]);
4224+
DECREF_INPUTS();
42654225
ERROR_IF(res_o == NULL, error);
42664226
res = PyStackRef_FromPyObjectSteal(res_o);
42674227
}
@@ -4313,8 +4273,9 @@ dummy_func(
43134273

43144274
// oparg counts all of the args, but *not* self:
43154275
int total_args = oparg;
4276+
_PyStackRef *arguments = args;
43164277
if (!PyStackRef_IsNull(self_or_null[0])) {
4317-
args--;
4278+
arguments--;
43184279
total_args++;
43194280
}
43204281
int positional_args = total_args - (int)PyTuple_GET_SIZE(kwnames_o);
@@ -4327,7 +4288,7 @@ dummy_func(
43274288
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
43284289
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit(
43294290
tstate, callable[0], locals,
4330-
args, positional_args, kwnames_o, frame
4291+
arguments, positional_args, kwnames_o, frame
43314292
);
43324293
PyStackRef_CLOSE(kwnames);
43334294
// Sync stack explicitly since we leave using DISPATCH_INLINED().
@@ -4342,7 +4303,7 @@ dummy_func(
43424303
DISPATCH_INLINED(new_frame);
43434304
}
43444305
/* Callable is not a normal Python function */
4345-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
4306+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
43464307
if (CONVERSION_FAILED(args_o)) {
43474308
DECREF_INPUTS();
43484309
ERROR_IF(true, error);
@@ -4354,7 +4315,7 @@ dummy_func(
43544315
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
43554316
if (opcode == INSTRUMENTED_CALL_KW) {
43564317
PyObject *arg = total_args == 0 ?
4357-
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(args[0]);
4318+
&_PyInstrumentation_MISSING : PyStackRef_AsPyObjectBorrow(arguments[0]);
43584319
if (res_o == NULL) {
43594320
_Py_call_instrumentation_exc2(
43604321
tstate, PY_MONITORING_EVENT_C_RAISE,
@@ -4369,13 +4330,7 @@ dummy_func(
43694330
}
43704331
}
43714332
}
4372-
PyStackRef_CLOSE(kwnames);
4373-
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4374-
for (int i = 0; i < total_args; i++) {
4375-
PyStackRef_CLOSE(args[i]);
4376-
}
4377-
DEAD(self_or_null);
4378-
PyStackRef_CLOSE(callable[0]);
4333+
DECREF_INPUTS();
43794334
ERROR_IF(res_o == NULL, error);
43804335
res = PyStackRef_FromPyObjectSteal(res_o);
43814336
}
@@ -4385,8 +4340,9 @@ dummy_func(
43854340

43864341
// oparg counts all of the args, but *not* self:
43874342
int total_args = oparg;
4343+
_PyStackRef *arguments = args;
43884344
if (!PyStackRef_IsNull(self_or_null[0])) {
4389-
args--;
4345+
arguments--;
43904346
total_args++;
43914347
}
43924348
PyObject *kwnames_o = PyStackRef_AsPyObjectBorrow(kwnames);
@@ -4396,7 +4352,7 @@ dummy_func(
43964352
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable_o));
43974353
_PyInterpreterFrame *temp = _PyEvalFramePushAndInit(
43984354
tstate, callable[0], locals,
4399-
args, positional_args, kwnames_o, frame
4355+
arguments, positional_args, kwnames_o, frame
44004356
);
44014357
PyStackRef_CLOSE(kwnames);
44024358
// The frame has stolen all the arguments from the stack,
@@ -4487,12 +4443,13 @@ dummy_func(
44874443
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
44884444

44894445
int total_args = oparg;
4446+
_PyStackRef *arguments = args;
44904447
if (!PyStackRef_IsNull(self_or_null[0])) {
4491-
args--;
4448+
arguments--;
44924449
total_args++;
44934450
}
44944451
/* Callable is not a normal Python function */
4495-
STACKREFS_TO_PYOBJECTS(args, total_args, args_o);
4452+
STACKREFS_TO_PYOBJECTS(arguments, total_args, args_o);
44964453
if (CONVERSION_FAILED(args_o)) {
44974454
DECREF_INPUTS();
44984455
ERROR_IF(true, error);
@@ -4506,11 +4463,7 @@ dummy_func(
45064463
PyStackRef_CLOSE(kwnames);
45074464
STACKREFS_TO_PYOBJECTS_CLEANUP(args_o);
45084465
assert((res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
4509-
for (int i = 0; i < total_args; i++) {
4510-
PyStackRef_CLOSE(args[i]);
4511-
}
4512-
DEAD(self_or_null);
4513-
PyStackRef_CLOSE(callable[0]);
4466+
DECREF_INPUTS();
45144467
ERROR_IF(res_o == NULL, error);
45154468
res = PyStackRef_FromPyObjectSteal(res_o);
45164469
}

0 commit comments

Comments
 (0)