Commit fc8f5a6f authored by Andrew MacIntyre's avatar Andrew MacIntyre

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.
parent 21c36546
...@@ -44,7 +44,7 @@ PyGrammar_RemoveAccelerators(grammar *g) ...@@ -44,7 +44,7 @@ PyGrammar_RemoveAccelerators(grammar *g)
s = d->d_state; s = d->d_state;
for (j = 0; j < d->d_nstates; j++, s++) { for (j = 0; j < d->d_nstates; j++, s++) {
if (s->s_accel) if (s->s_accel)
PyMem_DEL(s->s_accel); PyObject_FREE(s->s_accel);
s->s_accel = NULL; s->s_accel = NULL;
} }
} }
...@@ -68,7 +68,7 @@ fixstate(grammar *g, state *s) ...@@ -68,7 +68,7 @@ fixstate(grammar *g, state *s)
int *accel; int *accel;
int nl = g->g_ll.ll_nlabels; int nl = g->g_ll.ll_nlabels;
s->s_accept = 0; s->s_accept = 0;
accel = PyMem_NEW(int, nl); accel = (int *) PyObject_MALLOC(nl * sizeof(int));
for (k = 0; k < nl; k++) for (k = 0; k < nl; k++)
accel[k] = -1; accel[k] = -1;
a = s->s_arc; a = s->s_arc;
...@@ -124,7 +124,7 @@ fixstate(grammar *g, state *s) ...@@ -124,7 +124,7 @@ fixstate(grammar *g, state *s)
k++; k++;
if (k < nl) { if (k < nl) {
int i; int i;
s->s_accel = PyMem_NEW(int, nl-k); s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int));
if (s->s_accel == NULL) { if (s->s_accel == NULL) {
fprintf(stderr, "no mem to add parser accelerators\n"); fprintf(stderr, "no mem to add parser accelerators\n");
exit(1); exit(1);
...@@ -134,5 +134,5 @@ fixstate(grammar *g, state *s) ...@@ -134,5 +134,5 @@ fixstate(grammar *g, state *s)
for (i = 0; k < nl; i++, k++) for (i = 0; k < nl; i++, k++)
s->s_accel[i] = accel[k]; s->s_accel[i] = accel[k];
} }
PyMem_DEL(accel); PyObject_FREE(accel);
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
node * node *
PyNode_New(int type) PyNode_New(int type)
{ {
node *n = PyMem_NEW(node, 1); node *n = (node *) PyObject_MALLOC(1 * sizeof(node));
if (n == NULL) if (n == NULL)
return NULL; return NULL;
n->n_type = type; n->n_type = type;
...@@ -92,7 +92,8 @@ PyNode_AddChild(register node *n1, int type, char *str, int lineno) ...@@ -92,7 +92,8 @@ PyNode_AddChild(register node *n1, int type, char *str, int lineno)
return E_OVERFLOW; return E_OVERFLOW;
if (current_capacity < required_capacity) { if (current_capacity < required_capacity) {
n = n1->n_child; n = n1->n_child;
PyMem_RESIZE(n, node, required_capacity); n = (node *) PyObject_REALLOC(n,
required_capacity * sizeof(node));
if (n == NULL) if (n == NULL)
return E_NOMEM; return E_NOMEM;
n1->n_child = n; n1->n_child = n;
...@@ -116,7 +117,7 @@ PyNode_Free(node *n) ...@@ -116,7 +117,7 @@ PyNode_Free(node *n)
{ {
if (n != NULL) { if (n != NULL) {
freechildren(n); freechildren(n);
PyMem_DEL(n); PyObject_FREE(n);
} }
} }
...@@ -127,7 +128,7 @@ freechildren(node *n) ...@@ -127,7 +128,7 @@ freechildren(node *n)
for (i = NCH(n); --i >= 0; ) for (i = NCH(n); --i >= 0; )
freechildren(CHILD(n, i)); freechildren(CHILD(n, i));
if (n->n_child != NULL) if (n->n_child != NULL)
PyMem_DEL(n->n_child); PyObject_FREE(n->n_child);
if (STR(n) != NULL) if (STR(n) != NULL)
PyMem_DEL(STR(n)); PyObject_FREE(STR(n));
} }
...@@ -133,7 +133,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, ...@@ -133,7 +133,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
else else
started = 1; started = 1;
len = b - a; /* XXX this may compute NULL - NULL */ len = b - a; /* XXX this may compute NULL - NULL */
str = PyMem_NEW(char, len + 1); str = (char *) PyObject_MALLOC(len + 1);
if (str == NULL) { if (str == NULL) {
fprintf(stderr, "no mem for next token\n"); fprintf(stderr, "no mem for next token\n");
err_ret->error = E_NOMEM; err_ret->error = E_NOMEM;
...@@ -157,7 +157,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, ...@@ -157,7 +157,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
PyParser_AddToken(ps, (int)type, str, tok->lineno, PyParser_AddToken(ps, (int)type, str, tok->lineno,
&(err_ret->expected))) != E_OK) { &(err_ret->expected))) != E_OK) {
if (err_ret->error != E_DONE) if (err_ret->error != E_DONE)
PyMem_DEL(str); PyObject_FREE(str);
break; break;
} }
} }
...@@ -178,7 +178,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, ...@@ -178,7 +178,7 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
err_ret->offset = tok->cur - tok->buf; err_ret->offset = tok->cur - tok->buf;
if (tok->buf != NULL) { if (tok->buf != NULL) {
size_t len = tok->inp - tok->buf; size_t len = tok->inp - tok->buf;
err_ret->text = PyMem_NEW(char, len + 1); err_ret->text = (char *) PyObject_MALLOC(len + 1);
if (err_ret->text != NULL) { if (err_ret->text != NULL) {
if (len > 0) if (len > 0)
strncpy(err_ret->text, tok->buf, len); strncpy(err_ret->text, tok->buf, len);
......
...@@ -719,7 +719,7 @@ com_free(struct compiling *c) ...@@ -719,7 +719,7 @@ com_free(struct compiling *c)
Py_XDECREF(c->c_cellvars); Py_XDECREF(c->c_cellvars);
Py_XDECREF(c->c_lnotab); Py_XDECREF(c->c_lnotab);
if (c->c_future) if (c->c_future)
PyMem_Free((void *)c->c_future); PyObject_FREE((void *)c->c_future);
} }
static void static void
...@@ -2020,7 +2020,7 @@ com_factor(struct compiling *c, node *n) ...@@ -2020,7 +2020,7 @@ com_factor(struct compiling *c, node *n)
return; return;
} }
if (childtype == MINUS) { if (childtype == MINUS) {
char *s = PyMem_Malloc(strlen(STR(pnum)) + 2); char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2);
if (s == NULL) { if (s == NULL) {
com_error(c, PyExc_MemoryError, ""); com_error(c, PyExc_MemoryError, "");
com_addbyte(c, 255); com_addbyte(c, 255);
...@@ -2028,7 +2028,7 @@ com_factor(struct compiling *c, node *n) ...@@ -2028,7 +2028,7 @@ com_factor(struct compiling *c, node *n)
} }
s[0] = '-'; s[0] = '-';
strcpy(s + 1, STR(pnum)); strcpy(s + 1, STR(pnum));
PyMem_Free(STR(pnum)); PyObject_FREE(STR(pnum));
STR(pnum) = s; STR(pnum) = s;
} }
com_atom(c, patom); com_atom(c, patom);
...@@ -4116,7 +4116,7 @@ PyNode_CompileSymtable(node *n, char *filename) ...@@ -4116,7 +4116,7 @@ PyNode_CompileSymtable(node *n, char *filename)
st = symtable_init(); st = symtable_init();
if (st == NULL) { if (st == NULL) {
PyMem_Free((void *)ff); PyObject_FREE((void *)ff);
return NULL; return NULL;
} }
st->st_future = ff; st->st_future = ff;
...@@ -4129,7 +4129,7 @@ PyNode_CompileSymtable(node *n, char *filename) ...@@ -4129,7 +4129,7 @@ PyNode_CompileSymtable(node *n, char *filename)
return st; return st;
fail: fail:
PyMem_Free((void *)ff); PyObject_FREE((void *)ff);
st->st_future = NULL; st->st_future = NULL;
PySymtable_Free(st); PySymtable_Free(st);
return NULL; return NULL;
...@@ -4722,7 +4722,7 @@ symtable_init() ...@@ -4722,7 +4722,7 @@ symtable_init()
{ {
struct symtable *st; struct symtable *st;
st = (struct symtable *)PyMem_Malloc(sizeof(struct symtable)); st = (struct symtable *)PyObject_MALLOC(sizeof(struct symtable));
if (st == NULL) if (st == NULL)
return NULL; return NULL;
st->st_pass = 1; st->st_pass = 1;
...@@ -4749,7 +4749,7 @@ PySymtable_Free(struct symtable *st) ...@@ -4749,7 +4749,7 @@ PySymtable_Free(struct symtable *st)
Py_XDECREF(st->st_symbols); Py_XDECREF(st->st_symbols);
Py_XDECREF(st->st_stack); Py_XDECREF(st->st_stack);
Py_XDECREF(st->st_cur); Py_XDECREF(st->st_cur);
PyMem_Free((void *)st); PyObject_FREE((void *)st);
} }
/* When the compiler exits a scope, it must should update the scope's /* When the compiler exits a scope, it must should update the scope's
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment