1 /* Parse tree node implementation */
10 node
*n
= (node
*) PyObject_MALLOC(1 * sizeof(node
));
21 /* See comments at XXXROUNDUP below. Returns -1 on overflow. */
25 /* Round up to the closest power of 2 >= n. */
36 /* A gimmick to make massive numbers of reallocs quicker. The result is
37 * a number >= the input. In PyNode_AddChild, it's used like so, when
38 * we're about to add child number current_size + 1:
40 * if XXXROUNDUP(current_size) < XXXROUNDUP(current_size + 1):
41 * allocate space for XXXROUNDUP(current_size + 1) total children
43 * we already have enough space
45 * Since a node starts out empty, we must have
47 * XXXROUNDUP(0) < XXXROUNDUP(1)
49 * so that we allocate space for the first child. One-child nodes are very
50 * common (presumably that would change if we used a more abstract form
51 * of syntax tree), so to avoid wasting memory it's desirable that
52 * XXXROUNDUP(1) == 1. That in turn forces XXXROUNDUP(0) == 0.
54 * Else for 2 <= n <= 128, we round up to the closest multiple of 4. Why 4?
55 * Rounding up to a multiple of an exact power of 2 is very efficient, and
56 * most nodes with more than one child have <= 4 kids.
58 * Else we call fancy_roundup() to grow proportionately to n. We've got an
59 * extreme case then (like test_longexp.py), and on many platforms doing
60 * anything less than proportional growth leads to exorbitant runtime
61 * (e.g., MacPython), or extreme fragmentation of user address space (e.g.,
64 * In a run of compileall across the 2.3a0 Lib directory, Andrew MacIntyre
65 * reported that, with this scheme, 89% of PyObject_REALLOC calls in
66 * PyNode_AddChild passed 1 for the size, and 9% passed 4. So this usually
67 * wastes very little memory, but is very effective at sidestepping
68 * platform-realloc disasters on vulnerable platforms.
70 * Note that this would be straightforward if a node stored its current
71 * capacity. The code is tricky to avoid that.
73 #define XXXROUNDUP(n) ((n) <= 1 ? (n) : \
74 (n) <= 128 ? (((n) + 3) & ~3) : \
79 PyNode_AddChild(register node
*n1
, int type
, char *str
, int lineno
, int col_offset
)
81 const int nch
= n1
->n_nchildren
;
83 int required_capacity
;
86 if (nch
== INT_MAX
|| nch
< 0)
89 current_capacity
= XXXROUNDUP(nch
);
90 required_capacity
= XXXROUNDUP(nch
+ 1);
91 if (current_capacity
< 0 || required_capacity
< 0)
93 if (current_capacity
< required_capacity
) {
95 n
= (node
*) PyObject_REALLOC(n
,
96 required_capacity
* sizeof(node
));
102 n
= &n1
->n_child
[n1
->n_nchildren
++];
105 n
->n_lineno
= lineno
;
106 n
->n_col_offset
= col_offset
;
113 static void freechildren(node
*);
126 freechildren(node
*n
)
129 for (i
= NCH(n
); --i
>= 0; )
130 freechildren(CHILD(n
, i
));
131 if (n
->n_child
!= NULL
)
132 PyObject_FREE(n
->n_child
);
134 PyObject_FREE(STR(n
));