From 5d858465b6ebdafa05f86309457848cc26913b6a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 20 Nov 2016 10:16:47 +0200 Subject: Added the const qualifier to char* variables that refer to readonly internal UTF-8 represenatation of Unicode objects. --- Modules/_elementtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 59375204ee..71245c23d9 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -3613,7 +3613,7 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, for (i = 0; i < PySequence_Size(events_seq); ++i) { PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i); - char *event_name = NULL; + const char *event_name = NULL; if (PyUnicode_Check(event_name_obj)) { event_name = PyUnicode_AsUTF8(event_name_obj); } else if (PyBytes_Check(event_name_obj)) { -- cgit v1.2.1 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. --- Modules/_elementtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 71245c23d9..f3e1e9f227 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2457,7 +2457,7 @@ treebuilder_append_event(TreeBuilderObject *self, PyObject *action, PyObject *event = PyTuple_Pack(2, action, node); if (event == NULL) return -1; - res = PyObject_CallFunctionObjArgs(self->events_append, event, NULL); + res = _PyObject_CallArg1(self->events_append, event); Py_DECREF(event); if (res == NULL) return -1; -- 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. --- Modules/_elementtree.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index f3e1e9f227..bafcaa5402 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2831,7 +2831,7 @@ expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, if (errmsg == NULL) return; - error = PyObject_CallFunction(st->parseerror_obj, "O", errmsg); + error = _PyObject_CallArg1(st->parseerror_obj, errmsg); Py_DECREF(errmsg); if (!error) return; @@ -2894,7 +2894,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, (TreeBuilderObject*) self->target, value ); else if (self->handle_data) - res = PyObject_CallFunction(self->handle_data, "O", value); + res = _PyObject_CallArg1(self->handle_data, value); else res = NULL; Py_XDECREF(res); @@ -3004,7 +3004,7 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) - res = PyObject_CallFunction(self->handle_data, "O", data); + res = _PyObject_CallArg1(self->handle_data, data); else res = NULL; @@ -3031,7 +3031,7 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) else if (self->handle_end) { tag = makeuniversal(self, tag_in); if (tag) { - res = PyObject_CallFunction(self->handle_end, "O", tag); + res = _PyObject_CallArg1(self->handle_end, tag); Py_DECREF(tag); } } @@ -3090,7 +3090,7 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (self->handle_comment) { comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); if (comment) { - res = PyObject_CallFunction(self->handle_comment, "O", comment); + res = _PyObject_CallArg1(self->handle_comment, comment); Py_XDECREF(res); Py_DECREF(comment); } -- 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(). --- Modules/_elementtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index bafcaa5402..3837ff125a 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2457,7 +2457,7 @@ treebuilder_append_event(TreeBuilderObject *self, PyObject *action, PyObject *event = PyTuple_Pack(2, action, node); if (event == NULL) return -1; - res = _PyObject_CallArg1(self->events_append, event); + res = PyObject_CallFunctionObjArgs(self->events_append, event, NULL); Py_DECREF(event); if (res == NULL) return -1; -- 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. --- Modules/_elementtree.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 3837ff125a..2e0cda7bcb 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2831,7 +2831,7 @@ expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, if (errmsg == NULL) return; - error = _PyObject_CallArg1(st->parseerror_obj, errmsg); + error = PyObject_CallFunctionObjArgs(st->parseerror_obj, errmsg, NULL); Py_DECREF(errmsg); if (!error) return; @@ -2894,7 +2894,7 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, (TreeBuilderObject*) self->target, value ); else if (self->handle_data) - res = _PyObject_CallArg1(self->handle_data, value); + res = PyObject_CallFunctionObjArgs(self->handle_data, value, NULL); else res = NULL; Py_XDECREF(res); @@ -3004,7 +3004,7 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) - res = _PyObject_CallArg1(self->handle_data, data); + res = PyObject_CallFunctionObjArgs(self->handle_data, data, NULL); else res = NULL; @@ -3031,7 +3031,7 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) else if (self->handle_end) { tag = makeuniversal(self, tag_in); if (tag) { - res = _PyObject_CallArg1(self->handle_end, tag); + res = PyObject_CallFunctionObjArgs(self->handle_end, tag, NULL); Py_DECREF(tag); } } @@ -3090,7 +3090,8 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (self->handle_comment) { comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict"); if (comment) { - res = _PyObject_CallArg1(self->handle_comment, comment); + res = PyObject_CallFunctionObjArgs(self->handle_comment, + comment, NULL); Py_XDECREF(res); Py_DECREF(comment); } -- cgit v1.2.1 From 5335358887dcb19631f86e6c7c37110fae201566 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 9 Dec 2016 15:26:00 +0100 Subject: Use _PyObject_CallMethodIdObjArgs() in _elementtree Issue #28915: Replace _PyObject_CallMethodId() with _PyObject_CallMethodIdObjArgs() 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. --- Modules/_elementtree.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 2e0cda7bcb..8678c0a370 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1171,8 +1171,8 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, if (checkpath(path) || namespaces != Py_None) { _Py_IDENTIFIER(find); - return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_find, "OOO", self, path, namespaces + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_find, self, path, namespaces, NULL ); } @@ -1216,8 +1216,9 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, elementtreestate *st = ET_STATE_GLOBAL; if (checkpath(path) || namespaces != Py_None) - return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_findtext, "OOOO", self, path, default_value, namespaces + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_findtext, + self, path, default_value, namespaces, NULL ); if (!self->extra) { @@ -1271,8 +1272,8 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, if (checkpath(tag) || namespaces != Py_None) { _Py_IDENTIFIER(findall); - return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_findall, "OOO", self, tag, namespaces + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_findall, self, tag, namespaces, NULL ); } @@ -1318,8 +1319,8 @@ _elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, _Py_IDENTIFIER(iterfind); elementtreestate *st = ET_STATE_GLOBAL; - return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces); + return _PyObject_CallMethodIdObjArgs( + st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); } /*[clinic input] @@ -2440,7 +2441,7 @@ treebuilder_add_subelement(PyObject *element, PyObject *child) } else { PyObject *res; - res = _PyObject_CallMethodId(element, &PyId_append, "O", child); + res = _PyObject_CallMethodIdObjArgs(element, &PyId_append, child, NULL); if (res == NULL) return -1; Py_DECREF(res); -- cgit v1.2.1 From 26fbec2e01a2eeac7a59ea585f6fa35e175224de Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 9 Dec 2016 16:22:32 +0100 Subject: Use PyObject_CallFunctionObjArgs() Issue #28915: Replace PyObject_CallFunction() with PyObject_CallFunctionObjArgs() when the format string was only made of "O" formats, PyObject* arguments. PyObject_CallFunctionObjArgs() avoids the creation of a temporary tuple and doesn't have to parse a format string. --- Modules/_elementtree.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 8678c0a370..ba827e667f 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2496,11 +2496,13 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, attrib = PyDict_New(); if (!attrib) return NULL; - node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); Py_DECREF(attrib); } else { - node = PyObject_CallFunction(self->element_factory, "OO", tag, attrib); + node = PyObject_CallFunctionObjArgs(self->element_factory, + tag, attrib, NULL); } if (!node) { return NULL; @@ -2977,7 +2979,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, return; } } - res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); + res = PyObject_CallFunctionObjArgs(self->handle_start, + tag, attrib, NULL); } else res = NULL; @@ -3143,8 +3146,9 @@ expat_start_doctype_handler(XMLParserObject *self, /* If the target has a handler for doctype, call it. */ if (self->handle_doctype) { - res = PyObject_CallFunction(self->handle_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); + res = PyObject_CallFunctionObjArgs(self->handle_doctype, + doctype_name_obj, pubid_obj, + sysid_obj, NULL); Py_CLEAR(res); } else { @@ -3163,8 +3167,9 @@ expat_start_doctype_handler(XMLParserObject *self, if (!res) goto clear; Py_DECREF(res); - res = PyObject_CallFunction(parser_doctype, "OOO", - doctype_name_obj, pubid_obj, sysid_obj); + res = PyObject_CallFunctionObjArgs(parser_doctype, + doctype_name_obj, pubid_obj, + sysid_obj, NULL); Py_CLEAR(res); } } @@ -3191,7 +3196,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict"); data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict"); if (target && data) { - res = PyObject_CallFunction(self->handle_pi, "OO", target, data); + res = PyObject_CallFunctionObjArgs(self->handle_pi, + target, data, NULL); Py_XDECREF(res); Py_DECREF(data); Py_DECREF(target); -- cgit v1.2.1 From f22b56b777f7134b5c4e6c9caa9249e92c4f4fd9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 16 Dec 2016 16:18:57 +0200 Subject: Issue #28959: Added private macro PyDict_GET_SIZE for retrieving the size of dict. --- Modules/_elementtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index ba827e667f..9e6f63b91c 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -150,7 +150,7 @@ list_join(PyObject* list) static int is_empty_dict(PyObject *obj) { - return PyDict_CheckExact(obj) && PyDict_Size(obj) == 0; + return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0; } -- cgit v1.2.1 From 104cb4a3bacdf9764f9f8670a80da16390231337 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 17 Jan 2017 02:21:47 +0100 Subject: Run Argument Clinic: METH_VARARGS=>METH_FASTCALL Issue #29286. Run Argument Clinic to get the new faster METH_FASTCALL calling convention for functions using "boring" positional arguments. Manually fix _elementtree: _elementtree_XMLParser_doctype() must remain consistent with the clinic code. --- Modules/_elementtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Modules/_elementtree.c') diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 5d63913b0a..2d623dc262 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -2743,7 +2743,7 @@ typedef struct { } XMLParserObject; static PyObject* -_elementtree_XMLParser_doctype(XMLParserObject* self, PyObject* args); +_elementtree_XMLParser_doctype(XMLParserObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames); static PyObject * _elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name, PyObject *pubid, PyObject *system); -- cgit v1.2.1