Skip to content

Commit 25a91aa

Browse files
committed
small stack size doubled + small edits
1 parent 4575b6c commit 25a91aa

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

Diff for: Modules/_functoolsmodule.c

+13-11
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,13 @@ partial_vectorcall(PyObject *self, PyObject *const *args,
419419
PyObject *pto_kw_merged = NULL; // pto_kw with duplicates merged (if any)
420420
PyObject *tot_kwnames;
421421

422-
/* Allocate Stack */
423-
PyObject **tmp_stack, **stack, *small_stack[_PY_FASTCALL_SMALL_STACK];
422+
/* Allocate Stack
423+
* Note, _PY_FASTCALL_SMALL_STACK is optimal for positional only
424+
* This case might have keyword arguments
425+
* furthermore, it might use extra stack space for temporary key storage
426+
* thus, double small_stack size is used, which is 10 * 8 = 80 bytes */
427+
PyObject *small_stack[_PY_FASTCALL_SMALL_STACK * 2];
428+
PyObject **tmp_stack, **stack;
424429
Py_ssize_t init_stack_size = tot_nargskw;
425430
if (pto_nkwds) {
426431
// If pto_nkwds, allocate additional space for temporary new keys
@@ -430,7 +435,6 @@ partial_vectorcall(PyObject *self, PyObject *const *args,
430435
stack = small_stack;
431436
}
432437
else {
433-
/* NOTE, in theory size * elsize could overflow */
434438
stack = PyMem_Malloc(init_stack_size * sizeof(PyObject *));
435439
if (stack == NULL) {
436440
return PyErr_NoMemory();
@@ -482,36 +486,34 @@ partial_vectorcall(PyObject *self, PyObject *const *args,
482486
}
483487
Py_ssize_t n_merges = nkwds - n_tail;
484488

485-
/* Create tot_kwnames */
486-
tot_kwnames = PyTuple_New(pto_nkwds + n_tail);
489+
/* Create total kwnames */
490+
tot_kwnames = PyTuple_New(tot_nkwds - n_merges);
487491
for (Py_ssize_t i = 0; i < n_tail; ++i) {
488492
key = Py_NewRef(stack[tot_nargskw + i]);
489493
PyTuple_SET_ITEM(tot_kwnames, pto_nkwds + i, key);
490494
}
491495

492-
/* Copy pto_kw_merged to stack */
496+
/* Copy pto_keywords with overlapping call keywords merged */
493497
Py_ssize_t pos = 0, i = 0;
494498
while (PyDict_Next(n_merges ? pto_kw_merged : pto->kw, &pos, &key, &val)) {
495499
PyTuple_SET_ITEM(tot_kwnames, i, Py_NewRef(key));
496500
stack[tot_nargs + i] = val;
497501
i++;
498502
}
503+
Py_XDECREF(pto_kw_merged);
499504

500-
/* Resize Stack */
501-
if (n_merges && stack != small_stack) {
505+
/* Resize Stack if the call has keywords */
506+
if (nkwds && stack != small_stack) {
502507
tmp_stack = PyMem_Realloc(stack, (tot_nargskw - n_merges) * sizeof(PyObject *));
503508
if (tmp_stack == NULL) {
504509
Py_DECREF(tot_kwnames);
505-
Py_XDECREF(pto_kw_merged);
506510
if (stack != small_stack) {
507511
PyMem_Free(stack);
508512
}
509513
return PyErr_NoMemory();
510514
}
511515
stack = tmp_stack;
512516
}
513-
514-
Py_XDECREF(pto_kw_merged);
515517
}
516518

517519
/* Copy Positionals to stack */

0 commit comments

Comments
 (0)