SF patch #578297:
Change the parser and compiler to use PyMalloc.
Only the files implementing processes that will request memory
allocations small enough for PyMalloc to be a win have been
changed, which are:-
- Python/compile.c
- Parser/acceler.c
- Parser/node.c
- Parser/parsetok.c
This augments the aggressive overallocation strategy implemented by
Tim Peters in PyNode_AddChild() [Parser/node.c], in reducing the
impact of platform malloc()/realloc()/free() corner case behaviour.
Such corner cases are known to be triggered by test_longexp and
test_import.
Jeremy Hylton, in accepting this patch, recommended this as a
bugfix candidate for 2.2. While the changes to Python/compile.c
and Parser/node.c backport easily (and could go in), the changes
to Parser/acceler.c and Parser/parsetok.c require other not
insignificant changes as a result of the differences in the memory
APIs between 2.3 and 2.2, which I'm not in a position to work
through at the moment. This is a pity, as the Parser/parsetok.c
changes are the most important after the Parser/node.c changes, due
to the size of the memory requests involved and their frequency.
diff --git a/Parser/node.c b/Parser/node.c
index 780c230..75900ce 100644
--- a/Parser/node.c
+++ b/Parser/node.c
@@ -7,7 +7,7 @@
node *
PyNode_New(int type)
{
- node *n = PyMem_NEW(node, 1);
+ node *n = (node *) PyObject_MALLOC(1 * sizeof(node));
if (n == NULL)
return NULL;
n->n_type = type;
@@ -92,7 +92,8 @@
return E_OVERFLOW;
if (current_capacity < required_capacity) {
n = n1->n_child;
- PyMem_RESIZE(n, node, required_capacity);
+ n = (node *) PyObject_REALLOC(n,
+ required_capacity * sizeof(node));
if (n == NULL)
return E_NOMEM;
n1->n_child = n;
@@ -116,7 +117,7 @@
{
if (n != NULL) {
freechildren(n);
- PyMem_DEL(n);
+ PyObject_FREE(n);
}
}
@@ -127,7 +128,7 @@
for (i = NCH(n); --i >= 0; )
freechildren(CHILD(n, i));
if (n->n_child != NULL)
- PyMem_DEL(n->n_child);
+ PyObject_FREE(n->n_child);
if (STR(n) != NULL)
- PyMem_DEL(STR(n));
+ PyObject_FREE(STR(n));
}