From 366f4ee4da4420842eac26b3fa00c2b01d4515a6 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 1 Dec 2016 14:43:22 +0100 Subject: Replace PyObject_CallFunctionObjArgs() with fastcall * PyObject_CallFunctionObjArgs(func, NULL) => _PyObject_CallNoArg(func) * PyObject_CallFunctionObjArgs(func, arg, NULL) => _PyObject_CallArg1(func, arg) PyObject_CallFunctionObjArgs() allocates 40 bytes on the C stack and requires extra work to "parse" C arguments to build a C array of PyObject*. _PyObject_CallNoArg() and _PyObject_CallArg1() are simpler and don't allocate memory on the C stack. This change is part of the fastcall project. The change on listsort() is related to the issue #23507. --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 6cfae77f12..a4ce7d1925 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -415,7 +415,7 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message, if (msg == NULL) goto error; - res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL); + res = _PyObject_CallArg1(show_fn, msg); Py_DECREF(show_fn); Py_DECREF(msg); -- cgit v1.2.1 From 3f6ef1e99f7c517a21d4f53c63b0aeef7e5b5b2c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 1 Dec 2016 14:51:04 +0100 Subject: Replace PyObject_CallFunction() with fastcall Replace PyObject_CallFunction(func, "O", arg) and PyObject_CallFunction(func, "O", arg, NULL) with _PyObject_CallArg1(func, arg) Replace PyObject_CallFunction(func, NULL) with _PyObject_CallNoArg(func) _PyObject_CallNoArg() and _PyObject_CallArg1() are simpler and don't allocate memory on the C stack. --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index a4ce7d1925..1b2c6cdfd4 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -476,7 +476,7 @@ warn_explicit(PyObject *category, PyObject *message, } else { text = message; - message = PyObject_CallFunction(category, "O", message); + message = _PyObject_CallArg1(category, message); if (message == NULL) goto cleanup; } -- cgit v1.2.1 From 39ae5bedd90f9caf9a78efa82f4d11e838933b3a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sun, 4 Dec 2016 22:59:09 +0100 Subject: Backed out changeset b9c9691c72c5 Issue #28858: The change b9c9691c72c5 introduced a regression. It seems like _PyObject_CallArg1() uses more stack memory than PyObject_CallFunctionObjArgs(). --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 1b2c6cdfd4..cecc8ad588 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -415,7 +415,7 @@ call_show_warning(PyObject *category, PyObject *text, PyObject *message, if (msg == NULL) goto error; - res = _PyObject_CallArg1(show_fn, msg); + res = PyObject_CallFunctionObjArgs(show_fn, msg, NULL); Py_DECREF(show_fn); Py_DECREF(msg); -- cgit v1.2.1 From 40273ec4f37c65c13a09d0ac23b08c99ebe2f1a3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 5 Dec 2016 17:04:32 +0100 Subject: Issue #28858: Remove _PyObject_CallArg1() macro Replace _PyObject_CallArg1(func, arg) with PyObject_CallFunctionObjArgs(func, arg, NULL) Using the _PyObject_CallArg1() macro increases the usage of the C stack, which was unexpected and unwanted. PyObject_CallFunctionObjArgs() doesn't have this issue. --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index cecc8ad588..189bf70431 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -476,7 +476,7 @@ warn_explicit(PyObject *category, PyObject *message, } else { text = message; - message = _PyObject_CallArg1(category, message); + message = PyObject_CallFunctionObjArgs(category, message, NULL); if (message == NULL) goto cleanup; } -- cgit v1.2.1 From e29cd26d1dfebb2d8ba06fdad88223dec0762cba Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 9 Dec 2016 16:09:30 +0100 Subject: Use _PyObject_CallMethodIdObjArgs() Issue #28915: Replace _PyObject_CallMethodId() with _PyObject_CallMethodIdObjArgs() in various modules when the format string was only made of "O" formats, PyObject* arguments. _PyObject_CallMethodIdObjArgs() avoids the creation of a temporary tuple and doesn't have to parse a format string. --- Python/_warnings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 189bf70431..588fabb1f9 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -26,7 +26,7 @@ check_matched(PyObject *obj, PyObject *arg) if (obj == Py_None) return 1; - result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg); + result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL); if (result == NULL) return -1; -- cgit v1.2.1 From d32d791b5a6c44070e173243929c484ed1bcf6f7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 9 Dec 2016 18:08:18 +0100 Subject: Issue #20185: Convert _warnings.warn() to Argument Clinic Fix warn_explicit(): interpret source=None as source=NULL. --- Python/_warnings.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'Python/_warnings.c') diff --git a/Python/_warnings.c b/Python/_warnings.c index 588fabb1f9..67f4c6bbe0 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1,5 +1,6 @@ #include "Python.h" #include "frameobject.h" +#include "clinic/_warnings.c.h" #define MODULE_NAME "_warnings" @@ -485,6 +486,10 @@ warn_explicit(PyObject *category, PyObject *message, if (lineno_obj == NULL) goto cleanup; + if (source == Py_None) { + source = NULL; + } + /* Create key. */ key = PyTuple_Pack(3, text, category, lineno_obj); if (key == NULL) @@ -805,22 +810,26 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, return res; } -static PyObject * -warnings_warn(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kw_list[] = {"message", "category", "stacklevel", - "source", NULL}; - PyObject *message, *category = NULL, *source = NULL; - Py_ssize_t stack_level = 1; +/*[clinic input] +warn as warnings_warn - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OnO:warn", kw_list, - &message, &category, &stack_level, &source)) - return NULL; + message: object + category: object = None + stacklevel: Py_ssize_t = 1 + source: object = None +Issue a warning, or maybe ignore it or raise an exception. +[clinic start generated code]*/ + +static PyObject * +warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, + Py_ssize_t stacklevel, PyObject *source) +/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/ +{ category = get_category(message, category); if (category == NULL) return NULL; - return do_warn(message, category, stack_level, source); + return do_warn(message, category, stacklevel, source); } static PyObject * @@ -1098,15 +1107,11 @@ exit: } -PyDoc_STRVAR(warn_doc, -"Issue a warning, or maybe ignore it or raise an exception."); - PyDoc_STRVAR(warn_explicit_doc, "Low-level inferface to warnings functionality."); static PyMethodDef warnings_functions[] = { - {"warn", (PyCFunction)warnings_warn, METH_VARARGS | METH_KEYWORDS, - warn_doc}, + WARNINGS_WARN_METHODDEF {"warn_explicit", (PyCFunction)warnings_warn_explicit, METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, -- cgit v1.2.1