[Python-checkins] commit of r41604 - in python/branches/ast-arena: Include/Python-ast.h Include/Python.h Include/asdl.h Include/ast.h Include/compile.h Include/pyarena.h Include/pythonrun.h Makefile.pre.in Parser/asdl_c.py Python/Python-ast.c Python/asdl.c Python/ast.c Python/compile.c Python/import.c Python/pyarena.c Python/pythonrun.c

jeremy.hylton python-checkins at python.org
Mon Dec 5 06:26:00 CET 2005


Author: jeremy.hylton
Date: Mon Dec  5 06:25:53 2005
New Revision: 41604

Added:
   python/branches/ast-arena/Include/pyarena.h
   python/branches/ast-arena/Python/pyarena.c
Modified:
   python/branches/ast-arena/Include/Python-ast.h
   python/branches/ast-arena/Include/Python.h
   python/branches/ast-arena/Include/asdl.h
   python/branches/ast-arena/Include/ast.h
   python/branches/ast-arena/Include/compile.h
   python/branches/ast-arena/Include/pythonrun.h
   python/branches/ast-arena/Makefile.pre.in
   python/branches/ast-arena/Parser/asdl_c.py
   python/branches/ast-arena/Python/Python-ast.c
   python/branches/ast-arena/Python/asdl.c
   python/branches/ast-arena/Python/ast.c
   python/branches/ast-arena/Python/compile.c
   python/branches/ast-arena/Python/import.c
   python/branches/ast-arena/Python/pythonrun.c
Log:
Implement memory management for AST using an arena API.

The key idea is to allocate all AST notes from a single arena that is
freed when the compilation finishes (success or failure).  The change
is pervasive:  Every AST constructor now takes an arena as an
additional argument.  Also, every call related to freeing AST memory
is gone.

The actual implementation of the arena is a toy.  It uses plain old
malloc and free and stores all the pointers so allocated in a linked
list.

The arena also keeps track of PyObjects allocated by the AST and
DECREFs each of them when the arena is freed.  This part of the
implementation would probably stay, although Fredrik Lundh noted that
a PyList would server as a fine container for the pointers.

This set of changes only modifies the compiler in two places, where
Attributes are created.  In theory, the entire compiler could use an
AST interface.



Modified: python/branches/ast-arena/Include/Python-ast.h
==============================================================================
--- python/branches/ast-arena/Include/Python-ast.h	(original)
+++ python/branches/ast-arena/Include/Python-ast.h	Mon Dec  5 06:25:53 2005
@@ -1,4 +1,4 @@
-/* File automatically generated by ./Parser/asdl_c.py */
+/* File automatically generated by ../Parser/asdl_c.py */
 
 #include "asdl.h"
 
@@ -328,81 +328,79 @@
 };
 
 
-mod_ty Module(asdl_seq * body);
-mod_ty Interactive(asdl_seq * body);
-mod_ty Expression(expr_ty body);
-mod_ty Suite(asdl_seq * body);
+mod_ty Module(asdl_seq * body, PyArena *arena);
+mod_ty Interactive(asdl_seq * body, PyArena *arena);
+mod_ty Expression(expr_ty body, PyArena *arena);
+mod_ty Suite(asdl_seq * body, PyArena *arena);
 stmt_ty FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
-                    asdl_seq * decorators, int lineno);
+                    asdl_seq * decorators, int lineno, PyArena *arena);
 stmt_ty ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int
-                 lineno);
-stmt_ty Return(expr_ty value, int lineno);
-stmt_ty Delete(asdl_seq * targets, int lineno);
-stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno);
-stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno);
-stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno);
+                 lineno, PyArena *arena);
+stmt_ty Return(expr_ty value, int lineno, PyArena *arena);
+stmt_ty Delete(asdl_seq * targets, int lineno, PyArena *arena);
+stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno, PyArena *arena);
+stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno,
+                  PyArena *arena);
+stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, PyArena
+              *arena);
 stmt_ty For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
-            int lineno);
-stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno);
-stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno);
-stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno);
+            int lineno, PyArena *arena);
+stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+              PyArena *arena);
+stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+           PyArena *arena);
+stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena
+              *arena);
 stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int
-                  lineno);
-stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno);
-stmt_ty Assert(expr_ty test, expr_ty msg, int lineno);
-stmt_ty Import(asdl_seq * names, int lineno);
-stmt_ty ImportFrom(identifier module, asdl_seq * names, int lineno);
-stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno);
-stmt_ty Global(asdl_seq * names, int lineno);
-stmt_ty Expr(expr_ty value, int lineno);
-stmt_ty Pass(int lineno);
-stmt_ty Break(int lineno);
-stmt_ty Continue(int lineno);
-expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno);
-expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno);
-expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno);
-expr_ty Lambda(arguments_ty args, expr_ty body, int lineno);
-expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno);
-expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno);
-expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno);
-expr_ty Yield(expr_ty value, int lineno);
+                  lineno, PyArena *arena);
+stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, PyArena
+                   *arena);
+stmt_ty Assert(expr_ty test, expr_ty msg, int lineno, PyArena *arena);
+stmt_ty Import(asdl_seq * names, int lineno, PyArena *arena);
+stmt_ty ImportFrom(identifier module, asdl_seq * names, int lineno, PyArena
+                   *arena);
+stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, PyArena
+             *arena);
+stmt_ty Global(asdl_seq * names, int lineno, PyArena *arena);
+stmt_ty Expr(expr_ty value, int lineno, PyArena *arena);
+stmt_ty Pass(int lineno, PyArena *arena);
+stmt_ty Break(int lineno, PyArena *arena);
+stmt_ty Continue(int lineno, PyArena *arena);
+expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno, PyArena *arena);
+expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, PyArena
+              *arena);
+expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno, PyArena *arena);
+expr_ty Lambda(arguments_ty args, expr_ty body, int lineno, PyArena *arena);
+expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, PyArena *arena);
+expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
+                 *arena);
+expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
+                     *arena);
+expr_ty Yield(expr_ty value, int lineno, PyArena *arena);
 expr_ty Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int
-                lineno);
+                lineno, PyArena *arena);
 expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
-             starargs, expr_ty kwargs, int lineno);
-expr_ty Repr(expr_ty value, int lineno);
-expr_ty Num(object n, int lineno);
-expr_ty Str(string s, int lineno);
+             starargs, expr_ty kwargs, int lineno, PyArena *arena);
+expr_ty Repr(expr_ty value, int lineno, PyArena *arena);
+expr_ty Num(object n, int lineno, PyArena *arena);
+expr_ty Str(string s, int lineno, PyArena *arena);
 expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
-                  lineno);
+                  lineno, PyArena *arena);
 expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
-                  lineno);
-expr_ty Name(identifier id, expr_context_ty ctx, int lineno);
-expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno);
-expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno);
-slice_ty Ellipsis(void);
-slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step);
-slice_ty ExtSlice(asdl_seq * dims);
-slice_ty Index(expr_ty value);
-comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs);
-excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body);
+                  lineno, PyArena *arena);
+expr_ty Name(identifier id, expr_context_ty ctx, int lineno, PyArena *arena);
+expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
+expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
+slice_ty Ellipsis(PyArena *arena);
+slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
+slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
+slice_ty Index(expr_ty value, PyArena *arena);
+comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
+                               PyArena *arena);
+excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body,
+                               PyArena *arena);
 arguments_ty arguments(asdl_seq * args, identifier vararg, identifier kwarg,
-                       asdl_seq * defaults);
-keyword_ty keyword(identifier arg, expr_ty value);
-alias_ty alias(identifier name, identifier asname);
-
-void free_mod(mod_ty);
-void free_stmt(stmt_ty);
-void free_expr(expr_ty);
-void free_expr_context(expr_context_ty);
-void free_slice(slice_ty);
-void free_boolop(boolop_ty);
-void free_operator(operator_ty);
-void free_unaryop(unaryop_ty);
-void free_cmpop(cmpop_ty);
-void free_comprehension(comprehension_ty);
-void free_excepthandler(excepthandler_ty);
-void free_arguments(arguments_ty);
-void free_keyword(keyword_ty);
-void free_alias(alias_ty);
+                       asdl_seq * defaults, PyArena *arena);
+keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena);
+alias_ty alias(identifier name, identifier asname, PyArena *arena);
 

Modified: python/branches/ast-arena/Include/Python.h
==============================================================================
--- python/branches/ast-arena/Include/Python.h	(original)
+++ python/branches/ast-arena/Include/Python.h	Mon Dec  5 06:25:53 2005
@@ -113,6 +113,7 @@
 
 #include "pystate.h"
 
+#include "pyarena.h"
 #include "modsupport.h"
 #include "pythonrun.h"
 #include "ceval.h"

Modified: python/branches/ast-arena/Include/asdl.h
==============================================================================
--- python/branches/ast-arena/Include/asdl.h	(original)
+++ python/branches/ast-arena/Include/asdl.h	Mon Dec  5 06:25:53 2005
@@ -23,7 +23,7 @@
     void *elements[1];
 } asdl_seq;
 
-asdl_seq *asdl_seq_new(int size);
+asdl_seq *asdl_seq_new(int size, PyArena *arena);
 void asdl_seq_free(asdl_seq *);
 
 #ifdef Py_DEBUG

Modified: python/branches/ast-arena/Include/ast.h
==============================================================================
--- python/branches/ast-arena/Include/ast.h	(original)
+++ python/branches/ast-arena/Include/ast.h	Mon Dec  5 06:25:53 2005
@@ -5,7 +5,7 @@
 #endif
 
 PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags,
-				  const char *);
+				  const char *, PyArena *);
 
 #ifdef __cplusplus
 }

Modified: python/branches/ast-arena/Include/compile.h
==============================================================================
--- python/branches/ast-arena/Include/compile.h	(original)
+++ python/branches/ast-arena/Include/compile.h	Mon Dec  5 06:25:53 2005
@@ -25,7 +25,7 @@
 
 struct _mod; /* Declare the existence of this type */
 PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,
-					PyCompilerFlags *);
+					PyCompilerFlags *, PyArena *);
 PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *);
 
 #define ERR_LATE_FUTURE \

Added: python/branches/ast-arena/Include/pyarena.h
==============================================================================
--- (empty file)
+++ python/branches/ast-arena/Include/pyarena.h	Mon Dec  5 06:25:53 2005
@@ -0,0 +1,42 @@
+/* An arena-like memory interface for the compiler.
+ */
+
+#ifndef Py_PYARENA_H
+#define Py_PYARENA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef struct _arena PyArena;
+
+  /* PyArena_New() and PyArena_Free() create a new arena and free it,
+     respectively.  Once an arena has been created, it can be used
+     to allocate memory.  Once it is freed, all the memory it allocated
+     is freed and none of its pointers are valid.
+
+     Py_ArenaNew() returns an arena pointer.  On error, it
+     returns a negative number and sets an exception.
+  */
+  PyAPI_FUNC(PyArena *) PyArena_New(void);
+  PyAPI_FUNC(void) PyArena_Free(PyArena *);
+
+  PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t);
+
+  /* The next two routines aren't proper arena allocation routines.
+     They exist to experiment with the arena API without making wholesale
+     changes to the implementation.
+
+     The two functions register pointers with the arena id.  These
+     are externally allocated pointers that will be freed when the
+     arena is freed.  One takes a pointer allocated with malloc.  The
+     other takes a PyObject that is DECREFed when the arena is freed.
+  */
+  PyAPI_FUNC(int) PyArena_AddMallocPointer(PyArena *, void *);
+  PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYARENA_H */

Modified: python/branches/ast-arena/Include/pythonrun.h
==============================================================================
--- python/branches/ast-arena/Include/pythonrun.h	(original)
+++ python/branches/ast-arena/Include/pythonrun.h	Mon Dec  5 06:25:53 2005
@@ -37,10 +37,12 @@
 PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *);
 
 PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(const char *, const char *, 
-						 int, PyCompilerFlags *flags);
+						 int, PyCompilerFlags *flags,
+                                                 PyArena *);
 PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, 
 					       char *, char *,
-                                               PyCompilerFlags *, int *);
+                                               PyCompilerFlags *, int *,
+                                               PyArena *);
 #define PyParser_SimpleParseString(S, B) \
         PyParser_SimpleParseStringFlags(S, B, 0)
 #define PyParser_SimpleParseFile(FP, S, B) \

Modified: python/branches/ast-arena/Makefile.pre.in
==============================================================================
--- python/branches/ast-arena/Makefile.pre.in	(original)
+++ python/branches/ast-arena/Makefile.pre.in	Mon Dec  5 06:25:53 2005
@@ -254,6 +254,7 @@
 		Python/modsupport.o \
 		Python/mystrtoul.o \
 		Python/mysnprintf.o \
+		Python/pyarena.o \
 		Python/pyfpe.o \
 		Python/pystate.o \
 		Python/pythonrun.o \
@@ -520,6 +521,7 @@
 		Include/object.h \
 		Include/objimpl.h \
 		Include/patchlevel.h \
+		Include/pyarena.h \
 		Include/pydebug.h \
 		Include/pyerrors.h \
 		Include/pyfpe.h \

Modified: python/branches/ast-arena/Parser/asdl_c.py
==============================================================================
--- python/branches/ast-arena/Parser/asdl_c.py	(original)
+++ python/branches/ast-arena/Parser/asdl_c.py	Mon Dec  5 06:25:53 2005
@@ -249,8 +249,9 @@
         if args:
             argstr = ", ".join(["%s %s" % (atype, aname)
                                 for atype, aname, opt in args])
+            argstr += ", PyArena *arena"
         else:
-            argstr = "void"
+            argstr = "PyArena *arena"
         self.emit("%s %s(%s);" % (ctype, name, argstr), 0)
 
     def visitProduct(self, prod, name):
@@ -265,6 +266,10 @@
             self.emit(s, depth, reflow)
         argstr = ", ".join(["%s %s" % (atype, aname)
                             for atype, aname, opt in args + attrs])
+        if argstr:
+            argstr += ", PyArena *arena"
+        else:
+            argstr = "PyArena *arena"
         self.emit("%s" % ctype, 0)
         emit("%s(%s)" % (name, argstr))
         emit("{")
@@ -280,7 +285,7 @@
                 emit('return NULL;', 2)
                 emit('}', 1)
 
-        emit("p = (%s)malloc(sizeof(*p));" % ctype, 1)
+        emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1);
         emit("if (!p) {", 1)
         emit("PyErr_NoMemory();", 2)
         emit("return NULL;", 2)
@@ -652,7 +657,7 @@
     c = ChainOfVisitors(TypeDefVisitor(f),
                         StructVisitor(f),
                         PrototypeVisitor(f),
-                        FreePrototypeVisitor(f),
+##                        FreePrototypeVisitor(f),
                         )
     c.visit(mod)
     f.close()
@@ -668,8 +673,8 @@
     print >> f
     v = ChainOfVisitors(MarshalPrototypeVisitor(f),
                         FunctionVisitor(f),
-                        FreeUtilVisitor(f),
-                        FreeVisitor(f),
+##                        FreeUtilVisitor(f),
+##                        FreeVisitor(f),
                         MarshalUtilVisitor(f),
                         MarshalFunctionVisitor(f),
                         )

Modified: python/branches/ast-arena/Python/Python-ast.c
==============================================================================
--- python/branches/ast-arena/Python/Python-ast.c	(original)
+++ python/branches/ast-arena/Python/Python-ast.c	Mon Dec  5 06:25:53 2005
@@ -1,4 +1,4 @@
-/* File automatically generated by ./Parser/asdl_c.py */
+/* File automatically generated by ../Parser/asdl_c.py */
 
 #include "Python.h"
 #include "Python-ast.h"
@@ -19,10 +19,10 @@
 static int marshal_write_alias(PyObject **, int *, alias_ty);
 
 mod_ty
-Module(asdl_seq * body)
+Module(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -33,10 +33,10 @@
 }
 
 mod_ty
-Interactive(asdl_seq * body)
+Interactive(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -47,7 +47,7 @@
 }
 
 mod_ty
-Expression(expr_ty body)
+Expression(expr_ty body, PyArena *arena)
 {
         mod_ty p;
         if (!body) {
@@ -55,7 +55,7 @@
                                 "field body is required for Expression");
                 return NULL;
         }
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -66,10 +66,10 @@
 }
 
 mod_ty
-Suite(asdl_seq * body)
+Suite(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -81,7 +81,7 @@
 
 stmt_ty
 FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
-            decorators, int lineno)
+            decorators, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!name) {
@@ -94,7 +94,7 @@
                                 "field args is required for FunctionDef");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -109,7 +109,8 @@
 }
 
 stmt_ty
-ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno)
+ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno,
+         PyArena *arena)
 {
         stmt_ty p;
         if (!name) {
@@ -117,7 +118,7 @@
                                 "field name is required for ClassDef");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -131,10 +132,10 @@
 }
 
 stmt_ty
-Return(expr_ty value, int lineno)
+Return(expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -146,10 +147,10 @@
 }
 
 stmt_ty
-Delete(asdl_seq * targets, int lineno)
+Delete(asdl_seq * targets, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -161,7 +162,7 @@
 }
 
 stmt_ty
-Assign(asdl_seq * targets, expr_ty value, int lineno)
+Assign(asdl_seq * targets, expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!value) {
@@ -169,7 +170,7 @@
                                 "field value is required for Assign");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -182,7 +183,8 @@
 }
 
 stmt_ty
-AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno)
+AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, PyArena
+          *arena)
 {
         stmt_ty p;
         if (!target) {
@@ -200,7 +202,7 @@
                                 "field value is required for AugAssign");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -214,10 +216,10 @@
 }
 
 stmt_ty
-Print(expr_ty dest, asdl_seq * values, bool nl, int lineno)
+Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -232,7 +234,7 @@
 
 stmt_ty
 For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
-    lineno)
+    lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!target) {
@@ -245,7 +247,7 @@
                                 "field iter is required for For");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -260,7 +262,8 @@
 }
 
 stmt_ty
-While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno)
+While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena
+      *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -268,7 +271,7 @@
                                 "field test is required for While");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -282,7 +285,7 @@
 }
 
 stmt_ty
-If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno)
+If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -290,7 +293,7 @@
                                 "field test is required for If");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -304,10 +307,10 @@
 }
 
 stmt_ty
-Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno)
+Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -321,10 +324,11 @@
 }
 
 stmt_ty
-TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno)
+TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
+          PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -338,10 +342,10 @@
 }
 
 stmt_ty
-TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno)
+TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -354,7 +358,7 @@
 }
 
 stmt_ty
-Assert(expr_ty test, expr_ty msg, int lineno)
+Assert(expr_ty test, expr_ty msg, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -362,7 +366,7 @@
                                 "field test is required for Assert");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -375,10 +379,10 @@
 }
 
 stmt_ty
-Import(asdl_seq * names, int lineno)
+Import(asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -390,7 +394,7 @@
 }
 
 stmt_ty
-ImportFrom(identifier module, asdl_seq * names, int lineno)
+ImportFrom(identifier module, asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!module) {
@@ -398,7 +402,7 @@
                                 "field module is required for ImportFrom");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -411,7 +415,7 @@
 }
 
 stmt_ty
-Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno)
+Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!body) {
@@ -419,7 +423,7 @@
                                 "field body is required for Exec");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -433,10 +437,10 @@
 }
 
 stmt_ty
-Global(asdl_seq * names, int lineno)
+Global(asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -448,7 +452,7 @@
 }
 
 stmt_ty
-Expr(expr_ty value, int lineno)
+Expr(expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!value) {
@@ -456,7 +460,7 @@
                                 "field value is required for Expr");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -468,10 +472,10 @@
 }
 
 stmt_ty
-Pass(int lineno)
+Pass(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -482,10 +486,10 @@
 }
 
 stmt_ty
-Break(int lineno)
+Break(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -496,10 +500,10 @@
 }
 
 stmt_ty
-Continue(int lineno)
+Continue(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -510,7 +514,7 @@
 }
 
 expr_ty
-BoolOp(boolop_ty op, asdl_seq * values, int lineno)
+BoolOp(boolop_ty op, asdl_seq * values, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!op) {
@@ -518,7 +522,7 @@
                                 "field op is required for BoolOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -531,7 +535,7 @@
 }
 
 expr_ty
-BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno)
+BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!left) {
@@ -549,7 +553,7 @@
                                 "field right is required for BinOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -563,7 +567,7 @@
 }
 
 expr_ty
-UnaryOp(unaryop_ty op, expr_ty operand, int lineno)
+UnaryOp(unaryop_ty op, expr_ty operand, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!op) {
@@ -576,7 +580,7 @@
                                 "field operand is required for UnaryOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -589,7 +593,7 @@
 }
 
 expr_ty
-Lambda(arguments_ty args, expr_ty body, int lineno)
+Lambda(arguments_ty args, expr_ty body, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!args) {
@@ -602,7 +606,7 @@
                                 "field body is required for Lambda");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -615,10 +619,10 @@
 }
 
 expr_ty
-Dict(asdl_seq * keys, asdl_seq * values, int lineno)
+Dict(asdl_seq * keys, asdl_seq * values, int lineno, PyArena *arena)
 {
         expr_ty p;
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -631,7 +635,7 @@
 }
 
 expr_ty
-ListComp(expr_ty elt, asdl_seq * generators, int lineno)
+ListComp(expr_ty elt, asdl_seq * generators, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!elt) {
@@ -639,7 +643,7 @@
                                 "field elt is required for ListComp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -652,7 +656,7 @@
 }
 
 expr_ty
-GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno)
+GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!elt) {
@@ -660,7 +664,7 @@
                                 "field elt is required for GeneratorExp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -673,10 +677,10 @@
 }
 
 expr_ty
-Yield(expr_ty value, int lineno)
+Yield(expr_ty value, int lineno, PyArena *arena)
 {
         expr_ty p;
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -688,7 +692,8 @@
 }
 
 expr_ty
-Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno)
+Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno,
+        PyArena *arena)
 {
         expr_ty p;
         if (!left) {
@@ -696,7 +701,7 @@
                                 "field left is required for Compare");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -711,7 +716,7 @@
 
 expr_ty
 Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs,
-     expr_ty kwargs, int lineno)
+     expr_ty kwargs, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!func) {
@@ -719,7 +724,7 @@
                                 "field func is required for Call");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -735,7 +740,7 @@
 }
 
 expr_ty
-Repr(expr_ty value, int lineno)
+Repr(expr_ty value, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -743,7 +748,7 @@
                                 "field value is required for Repr");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -755,7 +760,7 @@
 }
 
 expr_ty
-Num(object n, int lineno)
+Num(object n, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!n) {
@@ -763,7 +768,7 @@
                                 "field n is required for Num");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -775,7 +780,7 @@
 }
 
 expr_ty
-Str(string s, int lineno)
+Str(string s, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!s) {
@@ -783,7 +788,7 @@
                                 "field s is required for Str");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -795,7 +800,8 @@
 }
 
 expr_ty
-Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno)
+Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno,
+          PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -813,7 +819,7 @@
                                 "field ctx is required for Attribute");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -827,7 +833,8 @@
 }
 
 expr_ty
-Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno)
+Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno,
+          PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -845,7 +852,7 @@
                                 "field ctx is required for Subscript");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -859,7 +866,7 @@
 }
 
 expr_ty
-Name(identifier id, expr_context_ty ctx, int lineno)
+Name(identifier id, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!id) {
@@ -872,7 +879,7 @@
                                 "field ctx is required for Name");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -885,7 +892,7 @@
 }
 
 expr_ty
-List(asdl_seq * elts, expr_context_ty ctx, int lineno)
+List(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!ctx) {
@@ -893,7 +900,7 @@
                                 "field ctx is required for List");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -906,7 +913,7 @@
 }
 
 expr_ty
-Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno)
+Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!ctx) {
@@ -914,7 +921,7 @@
                                 "field ctx is required for Tuple");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -927,10 +934,10 @@
 }
 
 slice_ty
-Ellipsis()
+Ellipsis(PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -940,10 +947,10 @@
 }
 
 slice_ty
-Slice(expr_ty lower, expr_ty upper, expr_ty step)
+Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -956,10 +963,10 @@
 }
 
 slice_ty
-ExtSlice(asdl_seq * dims)
+ExtSlice(asdl_seq * dims, PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -970,7 +977,7 @@
 }
 
 slice_ty
-Index(expr_ty value)
+Index(expr_ty value, PyArena *arena)
 {
         slice_ty p;
         if (!value) {
@@ -978,7 +985,7 @@
                                 "field value is required for Index");
                 return NULL;
         }
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -989,7 +996,7 @@
 }
 
 comprehension_ty
-comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs)
+comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
 {
         comprehension_ty p;
         if (!target) {
@@ -1002,7 +1009,7 @@
                                 "field iter is required for comprehension");
                 return NULL;
         }
-        p = (comprehension_ty)malloc(sizeof(*p));
+        p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1014,10 +1021,10 @@
 }
 
 excepthandler_ty
-excepthandler(expr_ty type, expr_ty name, asdl_seq * body)
+excepthandler(expr_ty type, expr_ty name, asdl_seq * body, PyArena *arena)
 {
         excepthandler_ty p;
-        p = (excepthandler_ty)malloc(sizeof(*p));
+        p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1030,10 +1037,10 @@
 
 arguments_ty
 arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq *
-          defaults)
+          defaults, PyArena *arena)
 {
         arguments_ty p;
-        p = (arguments_ty)malloc(sizeof(*p));
+        p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1046,7 +1053,7 @@
 }
 
 keyword_ty
-keyword(identifier arg, expr_ty value)
+keyword(identifier arg, expr_ty value, PyArena *arena)
 {
         keyword_ty p;
         if (!arg) {
@@ -1059,7 +1066,7 @@
                                 "field value is required for keyword");
                 return NULL;
         }
-        p = (keyword_ty)malloc(sizeof(*p));
+        p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1070,7 +1077,7 @@
 }
 
 alias_ty
-alias(identifier name, identifier asname)
+alias(identifier name, identifier asname, PyArena *arena)
 {
         alias_ty p;
         if (!name) {
@@ -1078,7 +1085,7 @@
                                 "field name is required for alias");
                 return NULL;
         }
-        p = (alias_ty)malloc(sizeof(*p));
+        p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1089,454 +1096,6 @@
 }
 
 
-static void
-free_seq_exprs(asdl_seq *seq)
-{
-        int i, n;
-        n = asdl_seq_LEN(seq);
-        for (i = 0; i < n; i++)
-                free_expr((expr_ty)asdl_seq_GET(seq, i));
-        asdl_seq_free(seq);
-}
-
-static void
-free_seq_stmts(asdl_seq *seq)
-{
-        int i, n;
-        n = asdl_seq_LEN(seq);
-        for (i = 0; i < n; i++)
-                free_stmt((stmt_ty)asdl_seq_GET(seq, i));
-        asdl_seq_free(seq);
-}
-
-
-void
-free_mod(mod_ty o)
-{
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case Module_kind:
-                free_seq_stmts(o->v.Module.body);
-                break;
-        case Interactive_kind:
-                free_seq_stmts(o->v.Interactive.body);
-                break;
-        case Expression_kind:
-                free_expr((expr_ty)o->v.Expression.body);
-                break;
-        case Suite_kind:
-                free_seq_stmts(o->v.Suite.body);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_stmt(stmt_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case FunctionDef_kind:
-                Py_DECREF((identifier)o->v.FunctionDef.name);
-                free_arguments((arguments_ty)o->v.FunctionDef.args);
-                free_seq_stmts(o->v.FunctionDef.body);
-                free_seq_exprs(o->v.FunctionDef.decorators);
-                break;
-        case ClassDef_kind:
-                Py_DECREF((identifier)o->v.ClassDef.name);
-                free_seq_exprs(o->v.ClassDef.bases);
-                free_seq_stmts(o->v.ClassDef.body);
-                break;
-        case Return_kind:
-                if (o->v.Return.value) {
-                        free_expr((expr_ty)o->v.Return.value);
-                }
-                break;
-        case Delete_kind:
-                free_seq_exprs(o->v.Delete.targets);
-                break;
-        case Assign_kind:
-                free_seq_exprs(o->v.Assign.targets);
-                free_expr((expr_ty)o->v.Assign.value);
-                break;
-        case AugAssign_kind:
-                free_expr((expr_ty)o->v.AugAssign.target);
-                free_operator((operator_ty)o->v.AugAssign.op);
-                free_expr((expr_ty)o->v.AugAssign.value);
-                break;
-        case Print_kind:
-                if (o->v.Print.dest) {
-                        free_expr((expr_ty)o->v.Print.dest);
-                }
-                free_seq_exprs(o->v.Print.values);
-                break;
-        case For_kind:
-                free_expr((expr_ty)o->v.For.target);
-                free_expr((expr_ty)o->v.For.iter);
-                free_seq_stmts(o->v.For.body);
-                free_seq_stmts(o->v.For.orelse);
-                break;
-        case While_kind:
-                free_expr((expr_ty)o->v.While.test);
-                free_seq_stmts(o->v.While.body);
-                free_seq_stmts(o->v.While.orelse);
-                break;
-        case If_kind:
-                free_expr((expr_ty)o->v.If.test);
-                free_seq_stmts(o->v.If.body);
-                free_seq_stmts(o->v.If.orelse);
-                break;
-        case Raise_kind:
-                if (o->v.Raise.type) {
-                        free_expr((expr_ty)o->v.Raise.type);
-                }
-                if (o->v.Raise.inst) {
-                        free_expr((expr_ty)o->v.Raise.inst);
-                }
-                if (o->v.Raise.tback) {
-                        free_expr((expr_ty)o->v.Raise.tback);
-                }
-                break;
-        case TryExcept_kind:
-                free_seq_stmts(o->v.TryExcept.body);
-                seq = o->v.TryExcept.handlers;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_excepthandler((excepthandler_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                free_seq_stmts(o->v.TryExcept.orelse);
-                break;
-        case TryFinally_kind:
-                free_seq_stmts(o->v.TryFinally.body);
-                free_seq_stmts(o->v.TryFinally.finalbody);
-                break;
-        case Assert_kind:
-                free_expr((expr_ty)o->v.Assert.test);
-                if (o->v.Assert.msg) {
-                        free_expr((expr_ty)o->v.Assert.msg);
-                }
-                break;
-        case Import_kind:
-                seq = o->v.Import.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_alias((alias_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case ImportFrom_kind:
-                Py_DECREF((identifier)o->v.ImportFrom.module);
-                seq = o->v.ImportFrom.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_alias((alias_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Exec_kind:
-                free_expr((expr_ty)o->v.Exec.body);
-                if (o->v.Exec.globals) {
-                        free_expr((expr_ty)o->v.Exec.globals);
-                }
-                if (o->v.Exec.locals) {
-                        free_expr((expr_ty)o->v.Exec.locals);
-                }
-                break;
-        case Global_kind:
-                seq = o->v.Global.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        Py_DECREF((identifier)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Expr_kind:
-                free_expr((expr_ty)o->v.Expr.value);
-                break;
-        case Pass_kind:
-                break;
-        case Break_kind:
-                break;
-        case Continue_kind:
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_expr(expr_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case BoolOp_kind:
-                free_boolop((boolop_ty)o->v.BoolOp.op);
-                free_seq_exprs(o->v.BoolOp.values);
-                break;
-        case BinOp_kind:
-                free_expr((expr_ty)o->v.BinOp.left);
-                free_operator((operator_ty)o->v.BinOp.op);
-                free_expr((expr_ty)o->v.BinOp.right);
-                break;
-        case UnaryOp_kind:
-                free_unaryop((unaryop_ty)o->v.UnaryOp.op);
-                free_expr((expr_ty)o->v.UnaryOp.operand);
-                break;
-        case Lambda_kind:
-                free_arguments((arguments_ty)o->v.Lambda.args);
-                free_expr((expr_ty)o->v.Lambda.body);
-                break;
-        case Dict_kind:
-                free_seq_exprs(o->v.Dict.keys);
-                free_seq_exprs(o->v.Dict.values);
-                break;
-        case ListComp_kind:
-                free_expr((expr_ty)o->v.ListComp.elt);
-                seq = o->v.ListComp.generators;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_comprehension((comprehension_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                break;
-        case GeneratorExp_kind:
-                free_expr((expr_ty)o->v.GeneratorExp.elt);
-                seq = o->v.GeneratorExp.generators;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_comprehension((comprehension_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                break;
-        case Yield_kind:
-                if (o->v.Yield.value) {
-                        free_expr((expr_ty)o->v.Yield.value);
-                }
-                break;
-        case Compare_kind:
-                free_expr((expr_ty)o->v.Compare.left);
-                seq = o->v.Compare.ops;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_cmpop((cmpop_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                free_seq_exprs(o->v.Compare.comparators);
-                break;
-        case Call_kind:
-                free_expr((expr_ty)o->v.Call.func);
-                free_seq_exprs(o->v.Call.args);
-                seq = o->v.Call.keywords;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_keyword((keyword_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                if (o->v.Call.starargs) {
-                        free_expr((expr_ty)o->v.Call.starargs);
-                }
-                if (o->v.Call.kwargs) {
-                        free_expr((expr_ty)o->v.Call.kwargs);
-                }
-                break;
-        case Repr_kind:
-                free_expr((expr_ty)o->v.Repr.value);
-                break;
-        case Num_kind:
-                Py_DECREF((object)o->v.Num.n);
-                break;
-        case Str_kind:
-                Py_DECREF((string)o->v.Str.s);
-                break;
-        case Attribute_kind:
-                free_expr((expr_ty)o->v.Attribute.value);
-                Py_DECREF((identifier)o->v.Attribute.attr);
-                free_expr_context((expr_context_ty)o->v.Attribute.ctx);
-                break;
-        case Subscript_kind:
-                free_expr((expr_ty)o->v.Subscript.value);
-                free_slice((slice_ty)o->v.Subscript.slice);
-                free_expr_context((expr_context_ty)o->v.Subscript.ctx);
-                break;
-        case Name_kind:
-                Py_DECREF((identifier)o->v.Name.id);
-                free_expr_context((expr_context_ty)o->v.Name.ctx);
-                break;
-        case List_kind:
-                free_seq_exprs(o->v.List.elts);
-                free_expr_context((expr_context_ty)o->v.List.ctx);
-                break;
-        case Tuple_kind:
-                free_seq_exprs(o->v.Tuple.elts);
-                free_expr_context((expr_context_ty)o->v.Tuple.ctx);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_expr_context(expr_context_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_slice(slice_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case Ellipsis_kind:
-                break;
-        case Slice_kind:
-                if (o->v.Slice.lower) {
-                        free_expr((expr_ty)o->v.Slice.lower);
-                }
-                if (o->v.Slice.upper) {
-                        free_expr((expr_ty)o->v.Slice.upper);
-                }
-                if (o->v.Slice.step) {
-                        free_expr((expr_ty)o->v.Slice.step);
-                }
-                break;
-        case ExtSlice_kind:
-                seq = o->v.ExtSlice.dims;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_slice((slice_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Index_kind:
-                free_expr((expr_ty)o->v.Index.value);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_boolop(boolop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_operator(operator_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_unaryop(unaryop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_cmpop(cmpop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_comprehension(comprehension_ty o)
-{
-        if (!o)
-                return;
-
-        free_expr((expr_ty)o->target);
-        free_expr((expr_ty)o->iter);
-        free_seq_exprs(o->ifs);
-
-        free(o);
-}
-
-void
-free_excepthandler(excepthandler_ty o)
-{
-        if (!o)
-                return;
-
-        if (o->type) {
-                free_expr((expr_ty)o->type);
-        }
-        if (o->name) {
-                free_expr((expr_ty)o->name);
-        }
-        free_seq_stmts(o->body);
-
-        free(o);
-}
-
-void
-free_arguments(arguments_ty o)
-{
-        if (!o)
-                return;
-
-        free_seq_exprs(o->args);
-        if (o->vararg) {
-                Py_DECREF((identifier)o->vararg);
-        }
-        if (o->kwarg) {
-                Py_DECREF((identifier)o->kwarg);
-        }
-        free_seq_exprs(o->defaults);
-
-        free(o);
-}
-
-void
-free_keyword(keyword_ty o)
-{
-        if (!o)
-                return;
-
-        Py_DECREF((identifier)o->arg);
-        free_expr((expr_ty)o->value);
-
-        free(o);
-}
-
-void
-free_alias(alias_ty o)
-{
-        if (!o)
-                return;
-
-        Py_DECREF((identifier)o->name);
-        if (o->asname) {
-                Py_DECREF((identifier)o->asname);
-        }
-
-        free(o);
-}
-
-
 
 #define CHECKSIZE(BUF, OFF, MIN) { \
 	int need = *(OFF) + MIN; \

Modified: python/branches/ast-arena/Python/asdl.c
==============================================================================
--- python/branches/ast-arena/Python/asdl.c	(original)
+++ python/branches/ast-arena/Python/asdl.c	Mon Dec  5 06:25:53 2005
@@ -2,7 +2,7 @@
 #include "asdl.h"
 
 asdl_seq *
-asdl_seq_new(int size)
+asdl_seq_new(int size, PyArena *arena)
 {
 	asdl_seq *seq = NULL;
 	size_t n = sizeof(asdl_seq) +
@@ -13,6 +13,7 @@
 		PyErr_NoMemory();
 		return NULL;
 	}
+        PyArena_AddMallocPointer(arena, (void *)seq);
 	memset(seq, 0, n);
 	seq->size = size;
 	return seq;
@@ -21,6 +22,4 @@
 void
 asdl_seq_free(asdl_seq *seq)
 {
-	PyObject_Free(seq);
 }
-

Modified: python/branches/ast-arena/Python/ast.c
==============================================================================
--- python/branches/ast-arena/Python/ast.c	(original)
+++ python/branches/ast-arena/Python/ast.c	Mon Dec  5 06:25:53 2005
@@ -7,6 +7,7 @@
 #include "Python-ast.h"
 #include "grammar.h"
 #include "node.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "token.h"
 #include "parsetok.h"
@@ -20,51 +21,10 @@
    - syntax errors
 */
 
-/*
-  Note:
-  
-  You should rarely need to use the asdl_seq_free() in this file.
-  If you use asdl_seq_free(), you will leak any objects held in the seq.
-  If there is an appropriate asdl_*_seq_free() function, use it.
-  If there isn't an asdl_*_seq_free() function for you, you will
-  need to loop over the data in the sequence and free it.
-
-  asdl_seq* seq;
-  int i;
-
-  for (i = 0; i < asdl_seq_LEN(seq); i++)
-      free_***(asdl_seq_GET(seq, i));
-  asdl_seq_free(seq); / * ok * /
-
-  Almost all of the ast functions return a seq of expr, so you should
-  use asdl_expr_seq_free().  The exception is ast_for_suite() which
-  returns a seq of stmt's, so use asdl_stmt_seq_free() to free it.
-
-  If asdl_seq_free is appropriate, you should mark it with an ok comment.
-
-  There are still many memory problems in this file even though
-  it runs clean in valgrind, save one problem that may have existed
-  before the AST.
-
-  Any code which does something like this:
-
-      return ASTconstruct(local, LINENO(n));
-
-  will leak memory.  The problem is if ASTconstruct (e.g., TryFinally)
-  cannot allocate memory, local will be leaked.
-
-  There was discussion on python-dev to replace the entire allocation
-  scheme in this file with arenas.  Basically rather than allocate
-  memory in little blocks with malloc(), we allocate one big honking
-  hunk and deref everything into this block.  We would still need
-  another block or technique to handle the PyObject*s.
-
-  http://mail.python.org/pipermail/python-dev/2005-November/058138.html
-*/
-
 /* Data structure used internally */
 struct compiling {
-	char *c_encoding; /* source encoding */
+    char *c_encoding; /* source encoding */
+    PyArena *c_arena; /* arena for allocating memeory */
 };
 
 static asdl_seq *seq_for_testlist(struct compiling *, const node *);
@@ -88,63 +48,14 @@
 #define LINENO(n)	((n)->n_lineno)
 #endif
 
-#define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
-
-static void
-asdl_stmt_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_stmt(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
-
-static void
-asdl_expr_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_expr(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
-
-static void
-asdl_alias_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_alias(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
+static identifier
+new_identifier(const char* n, PyArena *arena) {
+    PyObject* id = PyString_InternFromString(n);
+    PyArena_AddPyObject(arena, id);
+    return id;
 }
 
-static void
-asdl_comprehension_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_comprehension(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
+#define NEW_IDENTIFIER(n) new_identifier(STR(n), c->c_arena)
 
 /* This routine provides an invalid object for the syntax error.
    The outermost routine must unpack this error and create the
@@ -267,7 +178,8 @@
 */
 
 mod_ty
-PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename)
+PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
+               PyArena *arena)
 {
     int i, j, num;
     asdl_seq *stmts = NULL;
@@ -276,17 +188,18 @@
     struct compiling c;
 
     if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {
-            c.c_encoding = "utf-8";
+        c.c_encoding = "utf-8";
     } else if (TYPE(n) == encoding_decl) {
         c.c_encoding = STR(n);
         n = CHILD(n, 0);
     } else {
         c.c_encoding = NULL;
     }
+    c.c_arena = arena;
 
     switch (TYPE(n)) {
         case file_input:
-            stmts = asdl_seq_new(num_stmts(n));
+            stmts = asdl_seq_new(num_stmts(n), arena);
             if (!stmts)
                     return NULL;
             for (i = 0; i < NCH(n) - 1; i++) {
@@ -312,7 +225,7 @@
                     }
                 }
             }
-            return Module(stmts);
+            return Module(stmts, arena);
         case eval_input: {
             expr_ty testlist_ast;
 
@@ -320,20 +233,20 @@
             testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
             if (!testlist_ast)
                 goto error;
-            return Expression(testlist_ast);
+            return Expression(testlist_ast, arena);
         }
         case single_input:
             if (TYPE(CHILD(n, 0)) == NEWLINE) {
-                stmts = asdl_seq_new(1);
+                stmts = asdl_seq_new(1, arena);
                 if (!stmts)
 		    goto error;
-                asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
-                return Interactive(stmts);
+                asdl_seq_SET(stmts, 0, Pass(n->n_lineno, arena));
+                return Interactive(stmts, arena);
             }
             else {
                 n = CHILD(n, 0);
                 num = num_stmts(n);
-                stmts = asdl_seq_new(num);
+                stmts = asdl_seq_new(num, arena);
                 if (!stmts)
 		    goto error;
                 if (num == 1) {
@@ -356,14 +269,12 @@
                     }
                 }
 
-                return Interactive(stmts);
+                return Interactive(stmts, arena);
             }
         default:
             goto error;
     }
  error:
-    if (stmts)
-	asdl_stmt_seq_free(stmts);
     ast_error_finish(filename);
     return NULL;
 }
@@ -587,7 +498,7 @@
 	   || TYPE(n) == testlist_safe
 	   );
 
-    seq = asdl_seq_new((NCH(n) + 1) / 2);
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
     if (!seq)
         return NULL;
 
@@ -596,7 +507,6 @@
 
         expression = ast_for_expr(c, CHILD(n, i));
         if (!expression) {
-            asdl_expr_seq_free(seq);
             return NULL;
         }
 
@@ -607,11 +517,11 @@
 }
 
 static expr_ty
-compiler_complex_args(const node *n)
+compiler_complex_args(struct compiling *c, const node *n)
 {
     int i, len = (NCH(n) + 1) / 2;
     expr_ty result;
-    asdl_seq *args = asdl_seq_new(len);
+    asdl_seq *args = asdl_seq_new(len, c->c_arena);
     if (!args)
         return NULL;
 
@@ -625,15 +535,16 @@
 			ast_error(child, "assignment to None");
 			return NULL;
 		}
-            arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child));
+            arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
+                       c->c_arena);
 	}
         else
-            arg = compiler_complex_args(CHILD(CHILD(n, 2*i), 1));
+            arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1));
 	set_context(arg, Store, n);
         asdl_seq_SET(args, i, arg);
     }
 
-    result = Tuple(args, Store, LINENO(n));
+    result = Tuple(args, Store, LINENO(n), c->c_arena);
     set_context(result, Store, n);
     return result;
 }
@@ -658,7 +569,7 @@
 
     if (TYPE(n) == parameters) {
 	if (NCH(n) == 2) /* () as argument list */
-	    return arguments(NULL, NULL, NULL, NULL);
+	    return arguments(NULL, NULL, NULL, NULL, c->c_arena);
 	n = CHILD(n, 1);
     }
     REQ(n, varargslist);
@@ -672,10 +583,10 @@
 	if (TYPE(ch) == EQUAL)
 	    n_defaults++;
     }
-    args = (n_args ? asdl_seq_new(n_args) : NULL);
+    args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
     if (!args && n_args)
     	return NULL; /* Don't need to go to NULL; nothing allocated */
-    defaults = (n_defaults ? asdl_seq_new(n_defaults) : NULL);
+    defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
     if (!defaults && n_defaults)
         goto error;
 
@@ -704,7 +615,7 @@
 
                 if (NCH(ch) == 3) {
                     asdl_seq_APPEND(args, 
-                                    compiler_complex_args(CHILD(ch, 1))); 
+                                    compiler_complex_args(c, CHILD(ch, 1))); 
 		}
                 else if (TYPE(CHILD(ch, 0)) == NAME) {
 		    expr_ty name;
@@ -713,7 +624,7 @@
 			    goto error;
 		    }
                     name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
-                                Param, LINENO(ch));
+                                Param, LINENO(ch), c->c_arena);
                     if (!name)
                         goto error;
                     asdl_seq_APPEND(args, name);
@@ -745,15 +656,11 @@
 	}
     }
 
-    return arguments(args, vararg, kwarg, defaults);
+    return arguments(args, vararg, kwarg, defaults, c->c_arena);
 
  error:
     Py_XDECREF(vararg);
     Py_XDECREF(kwarg);
-    if (args)
-        asdl_expr_seq_free(args);
-    if (defaults)
-        asdl_expr_seq_free(defaults);
     return NULL;
 }
 
@@ -770,7 +677,7 @@
     id = NEW_IDENTIFIER(CHILD(n, 0));
     if (!id)
         goto error;
-    e = Name(id, Load, LINENO(n));
+    e = Name(id, Load, LINENO(n), c->c_arena);
     if (!e)
 	goto error;
     id = NULL;
@@ -779,7 +686,7 @@
         id = NEW_IDENTIFIER(CHILD(n, i));
 	if (!id)
 	    goto error;
-	attrib = Attribute(e, id, Load, LINENO(CHILD(n, i)));
+	attrib = Attribute(e, id, Load, LINENO(CHILD(n, i)), c->c_arena);
 	if (!attrib)
 	    goto error;
 	e = attrib;
@@ -789,8 +696,6 @@
     return e;
     
   error:
-    Py_XDECREF(id);
-    free_expr(e);
     return NULL;
 }
 
@@ -818,7 +723,7 @@
 	name_expr = NULL;
     }
     else if (NCH(n) == 5) { /* Call with no arguments */
-	d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n));
+	d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), c->c_arena);
 	if (!d)
 	    goto error;
 	name_expr = NULL;
@@ -833,8 +738,6 @@
     return d;
     
   error:
-    free_expr(name_expr);
-    free_expr(d);
     return NULL;
 }
 
@@ -847,7 +750,7 @@
     
     REQ(n, decorators);
 
-    decorator_seq = asdl_seq_new(NCH(n));
+    decorator_seq = asdl_seq_new(NCH(n), c->c_arena);
     if (!decorator_seq)
         return NULL;
 	
@@ -859,7 +762,6 @@
     }
     return decorator_seq;
   error:
-    asdl_expr_seq_free(decorator_seq);
     return NULL;
 }
 
@@ -899,13 +801,9 @@
     if (!body)
 	goto error;
 
-    return FunctionDef(name, args, body, decorator_seq, LINENO(n));
+    return FunctionDef(name, args, body, decorator_seq, LINENO(n), c->c_arena);
 
 error:
-    asdl_stmt_seq_free(body);
-    asdl_expr_seq_free(decorator_seq);
-    free_arguments(args);
-    Py_XDECREF(name);
     return NULL;
 }
 
@@ -917,12 +815,11 @@
     expr_ty expression;
 
     if (NCH(n) == 3) {
-        args = arguments(NULL, NULL, NULL, NULL);
+        args = arguments(NULL, NULL, NULL, NULL, c->c_arena);
         if (!args)
             return NULL;
         expression = ast_for_expr(c, CHILD(n, 2));
         if (!expression) {
-            free_arguments(args);
             return NULL;
         }
     }
@@ -932,12 +829,11 @@
             return NULL;
         expression = ast_for_expr(c, CHILD(n, 3));
         if (!expression) {
-            free_arguments(args);
             return NULL;
         }
     }
 
-    return Lambda(args, expression, LINENO(n));
+    return Lambda(args, expression, LINENO(n), c->c_arena);
 }
 
 /* Count the number of 'for' loop in a list comprehension.
@@ -1026,9 +922,8 @@
     if (n_fors == -1)
         return NULL;
 
-    listcomps = asdl_seq_new(n_fors);
+    listcomps = asdl_seq_new(n_fors, c->c_arena);
     if (!listcomps) {
-        free_expr(elt);
     	return NULL;
     }
     
@@ -1042,32 +937,22 @@
 
 	t = ast_for_exprlist(c, CHILD(ch, 1), Store);
         if (!t) {
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(elt);
             return NULL;
         }
         expression = ast_for_testlist(c, CHILD(ch, 3));
         if (!expression) {
-            asdl_expr_seq_free(t);
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(elt);
             return NULL;
         }
 
 	if (asdl_seq_LEN(t) == 1) {
-	    lc = comprehension(asdl_seq_GET(t, 0), expression, NULL);
-	    /* only free the sequence since we grabbed element 0 above */
-	    if (lc)
-	        asdl_seq_free(t); /* ok */
+	    lc = comprehension(asdl_seq_GET(t, 0), expression, NULL,
+                               c->c_arena);
 	}
 	else
-	    lc = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL);
+	    lc = comprehension(Tuple(t, Store, LINENO(ch), c->c_arena),
+                               expression, NULL, c->c_arena);
 
         if (!lc) {
-            asdl_expr_seq_free(t);
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(expression);
-            free_expr(elt);
             return NULL;
         }
 
@@ -1078,17 +963,11 @@
 	    ch = CHILD(ch, 4);
 	    n_ifs = count_list_ifs(ch);
             if (n_ifs == -1) {
-                free_comprehension(lc);
-                asdl_comprehension_seq_free(listcomps);
-                free_expr(elt);
                 return NULL;
             }
 
-	    ifs = asdl_seq_new(n_ifs);
+	    ifs = asdl_seq_new(n_ifs, c->c_arena);
 	    if (!ifs) {
-                free_comprehension(lc);
-		asdl_comprehension_seq_free(listcomps);
-                free_expr(elt);
 		return NULL;
 	    }
 
@@ -1110,7 +989,7 @@
 	asdl_seq_APPEND(listcomps, lc);
     }
 
-    return ListComp(elt, listcomps, LINENO(n));
+    return ListComp(elt, listcomps, LINENO(n), c->c_arena);
 }
 
 /*
@@ -1197,9 +1076,8 @@
     if (n_fors == -1)
         return NULL;
     
-    genexps = asdl_seq_new(n_fors);
+    genexps = asdl_seq_new(n_fors, c->c_arena);
     if (!genexps) {
-        free_expr(elt);
         return NULL;
     }
     
@@ -1213,34 +1091,22 @@
         
         t = ast_for_exprlist(c, CHILD(ch, 1), Store);
         if (!t) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
             return NULL;
         }
         expression = ast_for_expr(c, CHILD(ch, 3));
         if (!expression) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
             return NULL;
         }
         
         if (asdl_seq_LEN(t) == 1) {
             ge = comprehension(asdl_seq_GET(t, 0), expression,
-                               NULL);
-	    /* only free the sequence since we grabbed element 0 above */
-	    if (ge)
-	        asdl_seq_free(t); /* ok */
+                               NULL, c->c_arena);
 	}
         else
-            ge = comprehension(Tuple(t, Store, LINENO(ch)),
-                               expression, NULL);
+            ge = comprehension(Tuple(t, Store, LINENO(ch), c->c_arena),
+                               expression, NULL, c->c_arena);
         
         if (!ge) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
             return NULL;
         }
         
@@ -1251,17 +1117,11 @@
             ch = CHILD(ch, 4);
             n_ifs = count_gen_ifs(ch);
             if (n_ifs == -1) {
-                asdl_comprehension_seq_free(genexps);
-		free_comprehension(ge);
-                free_expr(elt);
                 return NULL;
             }
             
-            ifs = asdl_seq_new(n_ifs);
+            ifs = asdl_seq_new(n_ifs, c->c_arena);
             if (!ifs) {
-                asdl_comprehension_seq_free(genexps);
-		free_comprehension(ge);
-                free_expr(elt);
                 return NULL;
             }
             
@@ -1273,10 +1133,6 @@
                 
                 expression = ast_for_expr(c, CHILD(ch, 1));
                 if (!expression) {
-		    asdl_expr_seq_free(ifs);
-                    asdl_comprehension_seq_free(genexps);
-		    free_comprehension(ge);
-                    free_expr(elt);
                     return NULL;
                 }
                 asdl_seq_APPEND(ifs, expression);
@@ -1291,7 +1147,7 @@
         asdl_seq_APPEND(genexps, ge);
     }
     
-    return GeneratorExp(elt, genexps, LINENO(n));
+    return GeneratorExp(elt, genexps, LINENO(n), c->c_arena);
 }
 
 static expr_ty
@@ -1306,14 +1162,14 @@
     case NAME:
 	/* All names start in Load context, but may later be
 	   changed. */
-	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n));
+	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), c->c_arena);
     case STRING: {
 	PyObject *str = parsestrplus(c, n);
 	
 	if (!str)
 	    return NULL;
 	
-	return Str(str, LINENO(n));
+	return Str(str, LINENO(n), c->c_arena);
     }
     case NUMBER: {
 	PyObject *pynum = parsenumber(STR(ch));
@@ -1321,13 +1177,13 @@
 	if (!pynum)
 	    return NULL;
 	
-	return Num(pynum, LINENO(n));
+	return Num(pynum, LINENO(n), c->c_arena);
     }
     case LPAR: /* some parenthesized expressions */
 	ch = CHILD(n, 1);
 	
 	if (TYPE(ch) == RPAR)
-	    return Tuple(NULL, Load, LINENO(n));
+	    return Tuple(NULL, Load, LINENO(n), c->c_arena);
 	
 	if (TYPE(ch) == yield_expr)
 	    return ast_for_expr(c, ch);
@@ -1340,7 +1196,7 @@
 	ch = CHILD(n, 1);
 	
 	if (TYPE(ch) == RSQB)
-	    return List(NULL, Load, LINENO(n));
+	    return List(NULL, Load, LINENO(n), c->c_arena);
 	
 	REQ(ch, listmaker);
 	if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
@@ -1349,7 +1205,7 @@
 	    if (!elts)
 		return NULL;
 	    
-	    return List(elts, Load, LINENO(n));
+	    return List(elts, Load, LINENO(n), c->c_arena);
 	}
 	else
 	    return ast_for_listcomp(c, ch);
@@ -1360,13 +1216,12 @@
 	
 	ch = CHILD(n, 1);
 	size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
-	keys = asdl_seq_new(size);
+	keys = asdl_seq_new(size, c->c_arena);
 	if (!keys)
 	    return NULL;
 	
-	values = asdl_seq_new(size);
+	values = asdl_seq_new(size, c->c_arena);
 	if (!values) {
-	    asdl_seq_free(keys); /* ok */
 	    return NULL;
 	}
 	
@@ -1375,8 +1230,6 @@
 	    
 	    expression = ast_for_expr(c, CHILD(ch, i));
 	    if (!expression) {
-		asdl_expr_seq_free(keys);
-		asdl_expr_seq_free(values);
 		return NULL;
 	    }
 	    
@@ -1384,14 +1237,12 @@
 	    
 	    expression = ast_for_expr(c, CHILD(ch, i + 2));
 	    if (!expression) {
-		asdl_expr_seq_free(keys);
-		asdl_expr_seq_free(values);
 		return NULL;
 	    }
 
 	    asdl_seq_SET(values, i / 4, expression);
 	}
-	return Dict(keys, values, LINENO(n));
+	return Dict(keys, values, LINENO(n), c->c_arena);
     }
     case BACKQUOTE: { /* repr */
 	expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
@@ -1399,7 +1250,7 @@
 	if (!expression)
 	    return NULL;
 	
-	return Repr(expression, LINENO(n));
+	return Repr(expression, LINENO(n), c->c_arena);
     }
     default:
 	PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
@@ -1421,7 +1272,7 @@
     */
     ch = CHILD(n, 0);
     if (TYPE(ch) == DOT)
-	return Ellipsis();
+	return Ellipsis(c->c_arena);
 
     if (NCH(n) == 1 && TYPE(ch) == test) {
         /* 'step' variable hold no significance in terms of being used over
@@ -1430,7 +1281,7 @@
         if (!step)
             return NULL;
             
-	return Index(step);
+	return Index(step, c->c_arena);
     }
 
     if (TYPE(ch) == test) {
@@ -1475,7 +1326,7 @@
         }
     }
 
-    return Slice(lower, upper, step);
+    return Slice(lower, upper, step, c->c_arena);
 }
 
 static expr_ty
@@ -1502,7 +1353,7 @@
         if (!operator)
             return NULL;
 
-	result = BinOp(expr1, operator, expr2, LINENO(n));
+	result = BinOp(expr1, operator, expr2, LINENO(n), c->c_arena);
 	if (!result)
             return NULL;
 
@@ -1520,7 +1371,7 @@
                     return NULL;
 
                 tmp_result = BinOp(result, operator, tmp, 
-				   LINENO(next_oper));
+				   LINENO(next_oper), c->c_arena);
 		if (!tmp) 
 			return NULL;
 		result = tmp_result;
@@ -1536,7 +1387,7 @@
     REQ(n, trailer);
     if (TYPE(CHILD(n, 0)) == LPAR) {
         if (NCH(n) == 2)
-            e = Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n));
+            e = Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), c->c_arena);
         else
             e = ast_for_call(c, CHILD(n, 1), left_expr);
     }
@@ -1547,40 +1398,35 @@
             slice_ty slc = ast_for_slice(c, CHILD(n, 0));
             if (!slc)
                 return NULL;
-            e = Subscript(left_expr, slc, Load, LINENO(n));
+            e = Subscript(left_expr, slc, Load, LINENO(n), c->c_arena);
             if (!e) {
-                free_slice(slc);
                 return NULL;
             }
         }
         else {
             int j;
             slice_ty slc;
-            asdl_seq *slices = asdl_seq_new((NCH(n) + 1) / 2);
+            asdl_seq *slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
             if (!slices)
                 return NULL;
             for (j = 0; j < NCH(n); j += 2) {
                 slc = ast_for_slice(c, CHILD(n, j));
                 if (!slc) {
-		    for (j = j / 2; j >= 0; j--)
-                        free_slice(asdl_seq_GET(slices, j));
-                    asdl_seq_free(slices); /* ok */
                     return NULL;
                 }
                 asdl_seq_SET(slices, j / 2, slc);
             }
-            e = Subscript(left_expr, ExtSlice(slices), Load, LINENO(n));
+            e = Subscript(left_expr, ExtSlice(slices, c->c_arena),
+                          Load, LINENO(n), c->c_arena);
             if (!e) {
-		for (j = 0; j < asdl_seq_LEN(slices); j++)
-                    free_slice(asdl_seq_GET(slices, j));
-                asdl_seq_free(slices); /* ok */
                 return NULL;
             }
         }
     }
     else {
         assert(TYPE(CHILD(n, 0)) == DOT);
-        e = Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load, LINENO(n));
+        e = Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load, LINENO(n),
+                      c->c_arena);
     }
     return e;
 }
@@ -1604,7 +1450,6 @@
             break;
         tmp = ast_for_trailer(c, ch, e);
         if (!tmp) {
-            free_expr(e);
             return NULL;
         }
         e = tmp;
@@ -1612,13 +1457,10 @@
     if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
         expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
         if (!f) {
-            free_expr(e);
             return NULL;
         }
-        tmp = BinOp(e, Pow, f, LINENO(n));
+        tmp = BinOp(e, Pow, f, LINENO(n), c->c_arena);
         if (!tmp) {
-            free_expr(f);
-            free_expr(e);
             return NULL;
         }
         e = tmp;
@@ -1661,7 +1503,7 @@
                 n = CHILD(n, 0);
                 goto loop;
             }
-            seq = asdl_seq_new((NCH(n) + 1) / 2);
+            seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
             if (!seq)
                 return NULL;
             for (i = 0; i < NCH(n); i += 2) {
@@ -1671,10 +1513,10 @@
                 asdl_seq_SET(seq, i / 2, e);
             }
             if (!strcmp(STR(CHILD(n, 1)), "and"))
-                return BoolOp(And, seq, LINENO(n));
+                return BoolOp(And, seq, LINENO(n), c->c_arena);
             else {
                 assert(!strcmp(STR(CHILD(n, 1)), "or"));
-                return BoolOp(Or, seq, LINENO(n));
+                return BoolOp(Or, seq, LINENO(n), c->c_arena);
             }
             break;
         case not_test:
@@ -1687,7 +1529,7 @@
                 if (!expression)
                     return NULL;
 
-                return UnaryOp(Not, expression, LINENO(n));
+                return UnaryOp(Not, expression, LINENO(n), c->c_arena);
             }
         case comparison:
             if (NCH(n) == 1) {
@@ -1697,12 +1539,11 @@
             else {
                 expr_ty expression;
                 asdl_seq *ops, *cmps;
-                ops = asdl_seq_new(NCH(n) / 2);
+                ops = asdl_seq_new(NCH(n) / 2, c->c_arena);
                 if (!ops)
                     return NULL;
-                cmps = asdl_seq_new(NCH(n) / 2);
+                cmps = asdl_seq_new(NCH(n) / 2, c->c_arena);
                 if (!cmps) {
-                    asdl_seq_free(ops); /* ok */
                     return NULL;
                 }
                 for (i = 1; i < NCH(n); i += 2) {
@@ -1711,15 +1552,11 @@
 
                     operator = ast_for_comp_op(CHILD(n, i));
                     if (!operator) {
-		        asdl_expr_seq_free(ops);
-		        asdl_expr_seq_free(cmps);
                         return NULL;
 		    }
 
                     expression = ast_for_expr(c, CHILD(n, i + 1));
                     if (!expression) {
-		        asdl_expr_seq_free(ops);
-		        asdl_expr_seq_free(cmps);
                         return NULL;
 		    }
                         
@@ -1728,12 +1565,10 @@
                 }
                 expression = ast_for_expr(c, CHILD(n, 0));
                 if (!expression) {
-		    asdl_expr_seq_free(ops);
-		    asdl_expr_seq_free(cmps);
                     return NULL;
 		}
                     
-                return Compare(expression, ops, cmps, LINENO(n));
+                return Compare(expression, ops, cmps, LINENO(n), c->c_arena);
             }
             break;
 
@@ -1759,7 +1594,7 @@
 		if (!exp)
 		    return NULL;
 	    }
-	    return Yield(exp, LINENO(n));
+	    return Yield(exp, LINENO(n), c->c_arena);
 	}
         case factor: {
             expr_ty expression;
@@ -1775,11 +1610,11 @@
 
             switch (TYPE(CHILD(n, 0))) {
                 case PLUS:
-                    return UnaryOp(UAdd, expression, LINENO(n));
+                    return UnaryOp(UAdd, expression, LINENO(n), c->c_arena);
                 case MINUS:
-                    return UnaryOp(USub, expression, LINENO(n));
+                    return UnaryOp(USub, expression, LINENO(n), c->c_arena);
                 case TILDE:
-                    return UnaryOp(Invert, expression, LINENO(n));
+                    return UnaryOp(Invert, expression, LINENO(n), c->c_arena);
             }
             PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
 	    		 TYPE(CHILD(n, 0)));
@@ -1836,10 +1671,10 @@
       return NULL;
     }
 
-    args = asdl_seq_new(nargs + ngens);
+    args = asdl_seq_new(nargs + ngens, c->c_arena);
     if (!args)
         goto error;
-    keywords = asdl_seq_new(nkeywords);
+    keywords = asdl_seq_new(nkeywords, c->c_arena);
     if (!keywords)
         goto error;
     nargs = 0;
@@ -1881,11 +1716,10 @@
                   goto error;
                 }
 		key = e->v.Name.id;
-		free(e); /* XXX: is free correct here? */
 		e = ast_for_expr(c, CHILD(ch, 2));
                 if (!e)
                     goto error;
-		kw = keyword(key, e);
+		kw = keyword(key, e, c->c_arena);
                 if (!kw)
                     goto error;
 		asdl_seq_SET(keywords, nkeywords++, kw);
@@ -1901,18 +1735,9 @@
 	}
     }
 
-    return Call(func, args, keywords, vararg, kwarg, LINENO(n));
+    return Call(func, args, keywords, vararg, kwarg, LINENO(n), c->c_arena);
 
  error:
-    free_expr(vararg);
-    free_expr(kwarg);
-    if (args)
-        asdl_expr_seq_free(args);
-    if (keywords) {
-	for (i = 0; i < asdl_seq_LEN(keywords); i++)
-            free_keyword(asdl_seq_GET(keywords, i));
-        asdl_seq_free(keywords); /* ok */
-    }
     return NULL;
 }
 
@@ -1939,7 +1764,7 @@
         asdl_seq *tmp = seq_for_testlist(c, n);
         if (!tmp)
             return NULL;
-	return Tuple(tmp, Load, LINENO(n));
+	return Tuple(tmp, Load, LINENO(n), c->c_arena);
     }
 }
 
@@ -1965,12 +1790,11 @@
     REQ(n, testlist);
     if (NCH(n) == 1) {
         expr_ty base;
-        asdl_seq *bases = asdl_seq_new(1);
+        asdl_seq *bases = asdl_seq_new(1, c->c_arena);
         if (!bases)
             return NULL;
         base = ast_for_expr(c, CHILD(n, 0));
         if (!base) {
-            asdl_seq_free(bases); /* ok */
             return NULL;
         }
         asdl_seq_SET(bases, 0, base);
@@ -1998,7 +1822,7 @@
         if (!e)
             return NULL;
 
-	return Expr(e, LINENO(n));
+	return Expr(e, LINENO(n), c->c_arena);
     }
     else if (TYPE(CHILD(n, 1)) == augassign) {
         expr_ty expr1, expr2;
@@ -2008,12 +1832,12 @@
 	if (TYPE(ch) == testlist)
 	    expr1 = ast_for_testlist(c, ch);
 	else
-	    expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch));
+	    expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch),
+                          c->c_arena);
 
         if (!expr1)
             return NULL;
         if (expr1->kind == GeneratorExp_kind) {
-	    free_expr(expr1);
 	    ast_error(ch, "augmented assignment to generator "
 		      "expression not possible");
 	    return NULL;
@@ -2021,7 +1845,6 @@
 	if (expr1->kind == Name_kind) {
 		char *var_name = PyString_AS_STRING(expr1->v.Name.id);
 		if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
-			free_expr(expr1);
 			ast_error(ch, "assignment to None");
 			return NULL;
 		}
@@ -2031,20 +1854,17 @@
 	if (TYPE(ch) == testlist)
 	    expr2 = ast_for_testlist(c, ch);
 	else
-	    expr2 = Yield(ast_for_expr(c, ch), LINENO(ch));
+	    expr2 = Yield(ast_for_expr(c, ch), LINENO(ch), c->c_arena);
         if (!expr2) {
-            free_expr(expr1);
             return NULL;
         }
 
         operator = ast_for_augassign(CHILD(n, 1));
         if (!operator) {
-            free_expr(expr1);
-            free_expr(expr2);
             return NULL;
         }
 
-	return AugAssign(expr1, operator, expr2, LINENO(n));
+	return AugAssign(expr1, operator, expr2, LINENO(n), c->c_arena);
     }
     else {
 	int i;
@@ -2054,7 +1874,7 @@
 
 	/* a normal assignment */
 	REQ(CHILD(n, 1), EQUAL);
-	targets = asdl_seq_new(NCH(n) / 2);
+	targets = asdl_seq_new(NCH(n) / 2, c->c_arena);
 	if (!targets)
 	    return NULL;
 	for (i = 0; i < NCH(n) - 2; i += 2) {
@@ -2071,7 +1891,6 @@
 	      goto error;
 
 	    if (!set_context(e, Store, CHILD(n, i))) {
-              free_expr(e);
 	      goto error;
             }
 
@@ -2084,9 +1903,9 @@
 	    expression = ast_for_expr(c, value);
 	if (!expression)
 	    goto error;
-	return Assign(targets, expression, LINENO(n));
+	return Assign(targets, expression, LINENO(n), c->c_arena);
     error:
-        asdl_expr_seq_free(targets);
+        (void)1;
     }
     return NULL;
 }
@@ -2109,21 +1928,19 @@
             return NULL;
 	start = 4;
     }
-    seq = asdl_seq_new((NCH(n) + 1 - start) / 2);
+    seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
     if (!seq)
 	return NULL;
     for (i = start; i < NCH(n); i += 2) {
         expression = ast_for_expr(c, CHILD(n, i));
         if (!expression) {
-	    free_expr(dest);
-	    asdl_expr_seq_free(seq);
             return NULL;
 	}
 
 	asdl_seq_APPEND(seq, expression);
     }
     nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
-    return Print(dest, seq, nl, LINENO(n));
+    return Print(dest, seq, nl, LINENO(n), c->c_arena);
 }
 
 static asdl_seq *
@@ -2135,7 +1952,7 @@
 
     REQ(n, exprlist);
 
-    seq = asdl_seq_new((NCH(n) + 1) / 2);
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
     if (!seq)
 	return NULL;
     for (i = 0; i < NCH(n); i += 2) {
@@ -2151,7 +1968,6 @@
     return seq;
 
 error:
-    asdl_expr_seq_free(seq);
     return NULL;
 }
 
@@ -2166,7 +1982,7 @@
     expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);
     if (!expr_list)
         return NULL;
-    return Delete(expr_list, LINENO(n));
+    return Delete(expr_list, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2188,32 +2004,32 @@
     ch = CHILD(n, 0);
     switch (TYPE(ch)) {
         case break_stmt:
-            return Break(LINENO(n));
+            return Break(LINENO(n), c->c_arena);
         case continue_stmt:
-            return Continue(LINENO(n));
+            return Continue(LINENO(n), c->c_arena);
         case yield_stmt: { /* will reduce to yield_expr */
 	    expr_ty exp = ast_for_expr(c, CHILD(ch, 0));
 	    if (!exp)
 		return NULL;
-            return Expr(exp, LINENO(n));
+            return Expr(exp, LINENO(n), c->c_arena);
         }
         case return_stmt:
             if (NCH(ch) == 1)
-                return Return(NULL, LINENO(n));
+                return Return(NULL, LINENO(n), c->c_arena);
             else {
                 expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
                 if (!expression)
                     return NULL;
-                return Return(expression, LINENO(n));
+                return Return(expression, LINENO(n), c->c_arena);
             }
         case raise_stmt:
             if (NCH(ch) == 1)
-                return Raise(NULL, NULL, NULL, LINENO(n));
+                return Raise(NULL, NULL, NULL, LINENO(n), c->c_arena);
             else if (NCH(ch) == 2) {
                 expr_ty expression = ast_for_expr(c, CHILD(ch, 1));
                 if (!expression)
                     return NULL;
-                return Raise(expression, NULL, NULL, LINENO(n));
+                return Raise(expression, NULL, NULL, LINENO(n), c->c_arena);
             }
             else if (NCH(ch) == 4) {
                 expr_ty expr1, expr2;
@@ -2225,7 +2041,7 @@
                 if (!expr2)
                     return NULL;
 
-                return Raise(expr1, expr2, NULL, LINENO(n));
+                return Raise(expr1, expr2, NULL, LINENO(n), c->c_arena);
             }
             else if (NCH(ch) == 6) {
                 expr_ty expr1, expr2, expr3;
@@ -2240,7 +2056,7 @@
                 if (!expr3)
                     return NULL;
                     
-                return Raise(expr1, expr2, expr3, LINENO(n));
+                return Raise(expr1, expr2, expr3, LINENO(n), c->c_arena);
             }
         default:
             PyErr_Format(PyExc_SystemError,
@@ -2250,7 +2066,7 @@
 }
 
 static alias_ty
-alias_for_import_name(const node *n)
+alias_for_import_name(struct compiling *c, const node *n)
 {
     /*
       import_as_name: NAME [NAME NAME]
@@ -2262,10 +2078,10 @@
         case import_as_name:
             if (NCH(n) == 3)
                 return alias(NEW_IDENTIFIER(CHILD(n, 0)),
-                             NEW_IDENTIFIER(CHILD(n, 2)));
+                             NEW_IDENTIFIER(CHILD(n, 2)), c->c_arena);
             else
                 return alias(NEW_IDENTIFIER(CHILD(n, 0)),
-                             NULL);
+                             NULL, c->c_arena);
             break;
         case dotted_as_name:
             if (NCH(n) == 1) {
@@ -2273,7 +2089,7 @@
                 goto loop;
             }
             else {
-                alias_ty a = alias_for_import_name(CHILD(n, 0));
+                alias_ty a = alias_for_import_name(c, CHILD(n, 0));
                 assert(!a->asname);
                 a->asname = NEW_IDENTIFIER(CHILD(n, 2));
                 return a;
@@ -2281,7 +2097,7 @@
             break;
         case dotted_name:
             if (NCH(n) == 1)
-                return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL);
+                return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL, c->c_arena);
             else {
                 /* Create a string of the form "a.b.c" */
                 int i, len;
@@ -2308,11 +2124,11 @@
                 --s;
                 *s = '\0';
                 PyString_InternInPlace(&str);
-                return alias(str, NULL);
+                return alias(str, NULL, c->c_arena);
             }
             break;
         case STAR:
-            return alias(PyString_InternFromString("*"), NULL);
+            return alias(PyString_InternFromString("*"), NULL, c->c_arena);
         default:
             PyErr_Format(PyExc_SystemError,
                          "unexpected import name: %d", TYPE(n));
@@ -2339,25 +2155,24 @@
     if (STR(CHILD(n, 0))[0] == 'i') { /* import */
         n = CHILD(n, 1);
 	REQ(n, dotted_as_names);
-	aliases = asdl_seq_new((NCH(n) + 1) / 2);
+	aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
 	if (!aliases)
 		return NULL;
 	for (i = 0; i < NCH(n); i += 2) {
-            alias_ty import_alias = alias_for_import_name(CHILD(n, i));
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
                 return NULL;
             }
 	    asdl_seq_SET(aliases, i / 2, import_alias);
         }
-	return Import(aliases, LINENO(n));
+	return Import(aliases, LINENO(n), c->c_arena);
     }
     else if (STR(CHILD(n, 0))[0] == 'f') { /* from */
 	stmt_ty import;
         int n_children;
         const char *from_modules;
 	int lineno = LINENO(n);
-	alias_ty mod = alias_for_import_name(CHILD(n, 1));
+	alias_ty mod = alias_for_import_name(c, CHILD(n, 1));
 	if (!mod)
             return NULL;
 
@@ -2368,7 +2183,6 @@
             n = CHILD(n, 3);                  /* from ... import x, y, z */
             if (NCH(n) % 2 == 0) {
                 /* it ends with a comma, not valid but the parser allows it */
-		free_alias(mod);
                 ast_error(n, "trailing comma not allowed without"
                              " surrounding parentheses");
                 return NULL;
@@ -2381,7 +2195,6 @@
             n = CHILD(n, 4);                  /* from ... import (x, y, z) */
         else {
 	    /* XXX: don't we need to call ast_error(n, "..."); */
-	    free_alias(mod);
             return NULL;
 	}
 
@@ -2389,35 +2202,29 @@
         if (from_modules && from_modules[0] == '*')
             n_children = 1;
 
-	aliases = asdl_seq_new((n_children + 1) / 2);
+	aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena);
 	if (!aliases) {
-            free_alias(mod);
             return NULL;
 	}
 
         /* handle "from ... import *" special b/c there's no children */
         if (from_modules && from_modules[0] == '*') {
-            alias_ty import_alias = alias_for_import_name(n);
+            alias_ty import_alias = alias_for_import_name(c, n);
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
-                free_alias(mod);
                 return NULL;
             }
 	    asdl_seq_APPEND(aliases, import_alias);
         }
 
 	for (i = 0; i < NCH(n); i += 2) {
-            alias_ty import_alias = alias_for_import_name(CHILD(n, i));
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
-                free_alias(mod);
                 return NULL;
             }
 	    asdl_seq_APPEND(aliases, import_alias);
         }
         Py_INCREF(mod->name);
-	import = ImportFrom(mod->name, aliases, lineno);
-	free_alias(mod);
+	import = ImportFrom(mod->name, aliases, lineno, c->c_arena);
 	return import;
     }
     PyErr_Format(PyExc_SystemError,
@@ -2435,20 +2242,17 @@
     int i;
 
     REQ(n, global_stmt);
-    s = asdl_seq_new(NCH(n) / 2);
+    s = asdl_seq_new(NCH(n) / 2, c->c_arena);
     if (!s)
     	return NULL;
     for (i = 1; i < NCH(n); i += 2) {
 	name = NEW_IDENTIFIER(CHILD(n, i));
 	if (!name) {
-	    for (i = i / 2; i > 0; i--)
-                Py_XDECREF((identifier) asdl_seq_GET(s, i));
-	    asdl_seq_free(s); /* ok */
 	    return NULL;
 	}
 	asdl_seq_SET(s, i / 2, name);
     }
-    return Global(s, LINENO(n));
+    return Global(s, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2479,7 +2283,7 @@
             return NULL;
     }
 
-    return Exec(expr1, globals, locals, LINENO(n));
+    return Exec(expr1, globals, locals, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2491,7 +2295,7 @@
         expr_ty expression = ast_for_expr(c, CHILD(n, 1));
         if (!expression)
             return NULL;
-	return Assert(expression, NULL, LINENO(n));
+	return Assert(expression, NULL, LINENO(n), c->c_arena);
     }
     else if (NCH(n) == 4) {
         expr_ty expr1, expr2;
@@ -2503,7 +2307,7 @@
         if (!expr2)
             return NULL;
             
-	return Assert(expr1, expr2, LINENO(n));
+	return Assert(expr1, expr2, LINENO(n), c->c_arena);
     }
     PyErr_Format(PyExc_SystemError,
                  "improper number of parts to 'assert' statement: %d",
@@ -2523,7 +2327,7 @@
     REQ(n, suite);
 
     total = num_stmts(n);
-    seq = asdl_seq_new(total);
+    seq = asdl_seq_new(total, c->c_arena);
     if (!seq)
     	return NULL;
     if (TYPE(CHILD(n, 0)) == simple_stmt) {
@@ -2571,8 +2375,6 @@
     assert(pos == seq->size);
     return seq;
  error:
-    if (seq)
-	asdl_stmt_seq_free(seq);
     return NULL;
 }
 
@@ -2595,11 +2397,10 @@
             return NULL;
         suite_seq = ast_for_suite(c, CHILD(n, 3)); 
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
             
-	return If(expression, suite_seq, NULL, LINENO(n));
+	return If(expression, suite_seq, NULL, LINENO(n), c->c_arena);
     }
     s = STR(CHILD(n, 4));
     /* s[2], the third character in the string, will be
@@ -2615,17 +2416,14 @@
             return NULL;
         seq1 = ast_for_suite(c, CHILD(n, 3));
         if (!seq1) {
-	    free_expr(expression);
             return NULL;
 	}
         seq2 = ast_for_suite(c, CHILD(n, 6));
         if (!seq2) {
-	    asdl_stmt_seq_free(seq1);
-	    free_expr(expression);
             return NULL;
 	}
 
-	return If(expression, seq1, seq2, LINENO(n));
+	return If(expression, seq1, seq2, LINENO(n), c->c_arena);
     }
     else if (s[2] == 'i') {
 	int i, n_elif, has_else = 0;
@@ -2644,30 +2442,25 @@
             expr_ty expression;
             asdl_seq *seq1, *seq2;
 
-	    orelse = asdl_seq_new(1);
+	    orelse = asdl_seq_new(1, c->c_arena);
 	    if (!orelse)
 		return NULL;
             expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
             if (!expression) {
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
             seq1 = ast_for_suite(c, CHILD(n, NCH(n) - 4));
             if (!seq1) {
-                free_expr(expression);
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
             seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
             if (!seq2) {
-                free_expr(expression);
-                asdl_stmt_seq_free(seq1);
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
 
 	    asdl_seq_SET(orelse, 0, If(expression, seq1, seq2, 
-				       LINENO(CHILD(n, NCH(n) - 6))));
+				       LINENO(CHILD(n, NCH(n) - 6)),
+                                       c->c_arena));
 	    /* the just-created orelse handled the last elif */
 	    n_elif--;
 	}
@@ -2678,33 +2471,27 @@
 	    int off = 5 + (n_elif - i - 1) * 4;
             expr_ty expression;
             asdl_seq *suite_seq;
-	    asdl_seq *new = asdl_seq_new(1);
+	    asdl_seq *new = asdl_seq_new(1, c->c_arena);
 	    if (!new) {
-		asdl_stmt_seq_free(orelse);
 		return NULL;
 	    }
             expression = ast_for_expr(c, CHILD(n, off));
             if (!expression) {
-		asdl_stmt_seq_free(orelse);
-                asdl_seq_free(new); /* ok */
                 return NULL;
             }
             suite_seq = ast_for_suite(c, CHILD(n, off + 2));
             if (!suite_seq) {
-		asdl_stmt_seq_free(orelse);
-	        free_expr(expression);
-                asdl_seq_free(new); /* ok */
                 return NULL;
             }
 
 	    asdl_seq_SET(new, 0,
 			 If(expression, suite_seq, orelse, 
-			    LINENO(CHILD(n, off))));
+			    LINENO(CHILD(n, off)), c->c_arena));
 	    orelse = new;
 	}
 	return If(ast_for_expr(c, CHILD(n, 1)),
 		  ast_for_suite(c, CHILD(n, 3)),
-		  orelse, LINENO(n));
+		  orelse, LINENO(n), c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2728,10 +2515,9 @@
             return NULL;
         suite_seq = ast_for_suite(c, CHILD(n, 3));
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
-	return While(expression, suite_seq, NULL, LINENO(n));
+	return While(expression, suite_seq, NULL, LINENO(n), c->c_arena);
     }
     else if (NCH(n) == 7) {
         expr_ty expression;
@@ -2742,17 +2528,14 @@
             return NULL;
         seq1 = ast_for_suite(c, CHILD(n, 3));
         if (!seq1) {
-	    free_expr(expression);
             return NULL;
 	}
         seq2 = ast_for_suite(c, CHILD(n, 6));
         if (!seq2) {
-	    asdl_stmt_seq_free(seq1);
-	    free_expr(expression);
             return NULL;
 	}
 
-	return While(expression, seq1, seq2, LINENO(n));
+	return While(expression, seq1, seq2, LINENO(n), c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2779,31 +2562,24 @@
 
     _target = ast_for_exprlist(c, CHILD(n, 1), Store);
     if (!_target) {
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
     if (asdl_seq_LEN(_target) == 1) {
 	target = asdl_seq_GET(_target, 0);
-	asdl_seq_free(_target); /* ok */
     }
     else
-	target = Tuple(_target, Store, LINENO(n));
+	target = Tuple(_target, Store, LINENO(n), c->c_arena);
 
     expression = ast_for_testlist(c, CHILD(n, 3));
     if (!expression) {
-	free_expr(target);
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
     suite_seq = ast_for_suite(c, CHILD(n, 5));
     if (!suite_seq) {
-	free_expr(target);
-	free_expr(expression);
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
 
-    return For(target, expression, suite_seq, seq, LINENO(n));
+    return For(target, expression, suite_seq, seq, LINENO(n), c->c_arena);
 }
 
 static excepthandler_ty
@@ -2818,7 +2594,7 @@
         if (!suite_seq)
             return NULL;
 
-	return excepthandler(NULL, NULL, suite_seq);
+	return excepthandler(NULL, NULL, suite_seq, c->c_arena);
     }
     else if (NCH(exc) == 2) {
         expr_ty expression;
@@ -2829,11 +2605,10 @@
             return NULL;
         suite_seq = ast_for_suite(c, body);
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
 
-	return excepthandler(expression, NULL, suite_seq);
+	return excepthandler(expression, NULL, suite_seq, c->c_arena);
     }
     else if (NCH(exc) == 4) {
         asdl_seq *suite_seq;
@@ -2842,22 +2617,18 @@
 	if (!e)
             return NULL;
 	if (!set_context(e, Store, CHILD(exc, 3))) {
-	    free_expr(e);
             return NULL;
 	}
         expression = ast_for_expr(c, CHILD(exc, 1));
         if (!expression) {
-	    free_expr(e);
             return NULL;
 	}
         suite_seq = ast_for_suite(c, body);
         if (!suite_seq) {
-	    free_expr(expression);
-	    free_expr(e);
             return NULL;
 	}
 
-	return excepthandler(expression, e, suite_seq);
+	return excepthandler(expression, e, suite_seq, c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2880,11 +2651,10 @@
             return NULL;
         s2 = ast_for_suite(c, CHILD(n, 5));
         if (!s2) {
-	    asdl_stmt_seq_free(s1);
             return NULL;
 	}
             
-	return TryFinally(s1, s2, LINENO(n));
+	return TryFinally(s1, s2, LINENO(n), c->c_arena);
     }
     else if (TYPE(CHILD(n, 3)) == except_clause) {
 	/* try_stmt: ('try' ':' suite (except_clause ':' suite)+
@@ -2898,7 +2668,7 @@
 	    n_except -= 3;
 	}
 	n_except /= 3;
-	handlers = asdl_seq_new(n_except);
+	handlers = asdl_seq_new(n_except, c->c_arena);
 	if (!handlers)
 		return NULL;
 	for (i = 0; i < n_except; i++) {
@@ -2906,9 +2676,6 @@
                                                        CHILD(n, 3 + i * 3),
                                                        CHILD(n, 5 + i * 3));
             if (!e) {
-		for ( ; i >= 0; i--)
-		    free_excepthandler(asdl_seq_GET(handlers, i));
-	        asdl_seq_free(handlers); /* ok */
                 return NULL;
 	    }
 	    asdl_seq_SET(handlers, i, e);
@@ -2916,25 +2683,19 @@
 
         suite_seq1 = ast_for_suite(c, CHILD(n, 2));
         if (!suite_seq1) {
-	    for (i = 0; i < asdl_seq_LEN(handlers); i++)
-		free_excepthandler(asdl_seq_GET(handlers, i));
-	    asdl_seq_free(handlers); /* ok */
             return NULL;
 	}
         if (has_else) {
             suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
             if (!suite_seq2) {
-	        for (i = 0; i < asdl_seq_LEN(handlers); i++)
-		    free_excepthandler(asdl_seq_GET(handlers, i));
-	        asdl_seq_free(handlers); /* ok */
-		asdl_stmt_seq_free(suite_seq1);
                 return NULL;
 	    }
         }
         else
             suite_seq2 = NULL;
 
-	return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n));
+	return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n),
+                         c->c_arena);
     }
     else {
         ast_error(n, "malformed 'try' statement");
@@ -2959,14 +2720,16 @@
         s = ast_for_suite(c, CHILD(n, 3));
         if (!s)
             return NULL;
-	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n));
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        c->c_arena);
     }
     /* check for empty base list */
     if (TYPE(CHILD(n,3)) == RPAR) {
 	s = ast_for_suite(c, CHILD(n,5));
 	if (!s)
 		return NULL;
-	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n));
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        c->c_arena);
     }
 
     /* else handle the base class list */
@@ -2976,10 +2739,10 @@
 
     s = ast_for_suite(c, CHILD(n, 6));
     if (!s) {
-        asdl_expr_seq_free(bases);
         return NULL;
     }
-    return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n));
+    return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n),
+                    c->c_arena);
 }
 
 static stmt_ty
@@ -3008,7 +2771,7 @@
             case del_stmt:
                 return ast_for_del_stmt(c, n);
             case pass_stmt:
-                return Pass(LINENO(n));
+                return Pass(LINENO(n), c->c_arena);
             case flow_stmt:
                 return ast_for_flow_stmt(c, n);
             case import_stmt:

Modified: python/branches/ast-arena/Python/compile.c
==============================================================================
--- python/branches/ast-arena/Python/compile.c	(original)
+++ python/branches/ast-arena/Python/compile.c	Mon Dec  5 06:25:53 2005
@@ -23,6 +23,7 @@
 
 #include "Python-ast.h"
 #include "node.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "code.h"
 #include "compile.h"
@@ -148,6 +149,7 @@
         struct compiler_unit *u; /* compiler state for current block */
 	PyObject *c_stack;       /* Python list holding compiler_unit ptrs */
 	char *c_encoding;	 /* source encoding (a borrowed reference) */
+        PyArena *c_arena;        /* pointer to memory allocation arena */
 };
 
 struct assembler {
@@ -243,7 +245,8 @@
 }
 
 PyCodeObject *
-PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags)
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+              PyArena *arena)
 {
 	struct compiler c;
 	PyCodeObject *co = NULL;
@@ -259,6 +262,7 @@
 	if (!compiler_init(&c))
 		goto error;
 	c.c_filename = filename;
+        c.c_arena = arena;
 	c.c_future = PyFuture_FromAST(mod, filename);
 	if (c.c_future == NULL)
 		goto error;
@@ -293,11 +297,13 @@
 PyNode_Compile(struct _node *n, const char *filename)
 {
 	PyCodeObject *co;
-	mod_ty mod = PyAST_FromNode(n, NULL, filename);
+        PyArena *arena;
+        arena = PyArena_New();
+	mod_ty mod = PyAST_FromNode(n, NULL, filename, arena);
 	if (!mod)
 		return NULL;
-	co = PyAST_Compile(mod, filename, NULL);
-	free_mod(mod);
+	co = PyAST_Compile(mod, filename, NULL, arena);
+        PyArena_Free(arena);
 	return co;
 }
 
@@ -3407,7 +3413,7 @@
 	switch (e->kind) {
                 case Attribute_kind:
 		auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
-				 AugLoad, e->lineno);
+				 AugLoad, e->lineno, c->c_arena);
                 if (auge == NULL)
                     return 0;
 		VISIT(c, expr, auge);
@@ -3415,11 +3421,10 @@
 		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
 		auge->v.Attribute.ctx = AugStore;
 		VISIT(c, expr, auge);
-		free(auge);
 		break;
 	case Subscript_kind:
 		auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
-				 AugLoad, e->lineno);
+				 AugLoad, e->lineno, c->c_arena);
                 if (auge == NULL)
                     return 0;
 		VISIT(c, expr, auge);
@@ -3427,7 +3432,6 @@
 		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
                 auge->v.Subscript.ctx = AugStore;
 		VISIT(c, expr, auge);
-		free(auge);
                 break;
 	case Name_kind:
 		VISIT(c, expr, s->v.AugAssign.target);

Modified: python/branches/ast-arena/Python/import.c
==============================================================================
--- python/branches/ast-arena/Python/import.c	(original)
+++ python/branches/ast-arena/Python/import.c	Mon Dec  5 06:25:53 2005
@@ -4,6 +4,7 @@
 #include "Python.h"
 
 #include "Python-ast.h"
+#include "pyarena.h"
 #include "pythonrun.h"
 #include "errcode.h"
 #include "marshal.h"
@@ -773,13 +774,14 @@
 {
 	PyCodeObject *co = NULL;
 	mod_ty mod;
+        PyArena *arena = PyArena_New();
 
 	mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, 0, 
-				   NULL);
+				   NULL, arena);
 	if (mod) {
-		co = PyAST_Compile(mod, pathname, NULL);
-		free_mod(mod);
+		co = PyAST_Compile(mod, pathname, NULL, arena);
 	}
+        PyArena_Free(arena);
 	return co;
 }
 

Added: python/branches/ast-arena/Python/pyarena.c
==============================================================================
--- (empty file)
+++ python/branches/ast-arena/Python/pyarena.c	Mon Dec  5 06:25:53 2005
@@ -0,0 +1,129 @@
+#include "Python.h"
+#include "pyarena.h"
+
+/* An arena list is a linked list that can store either pointers or
+   PyObjects.  The type is clear from context.
+ */
+
+typedef struct _arena_list {
+  struct _arena_list *al_next;
+  void *al_pointer;
+} PyArenaList;
+
+/* There are two linked lists in an arena, one for malloc pointers and
+   one for PyObject.  For each list, there is a pointer to the head
+   and to the tail.  The head is used to free the list.  The tail is
+   used to add a new element to the list.
+
+   The list always keeps one un-used node at the end of the list.
+*/
+
+struct _arena {
+  PyArenaList *a_malloc_head;
+  PyArenaList *a_malloc_tail;
+  PyArenaList *a_object_head;
+  PyArenaList *a_object_tail;
+};
+
+static PyArenaList*
+PyArenaList_New(void) 
+{
+  PyArenaList *alist = (PyArenaList *)malloc(sizeof(PyArenaList));
+  alist->al_next = NULL;
+  alist->al_pointer = NULL;
+  return alist;
+}
+
+static PyArenaList*
+PyArenaList_Add(PyArenaList *alist) 
+{
+  assert(alist->al_next == NULL);
+  alist->al_next = PyArenaList_New();
+  return alist->al_next;
+}
+
+static void
+PyArenaList_FreeObject(PyArenaList *alist) 
+{
+  PyArenaList *prev;
+  while (alist) {
+    Py_XDECREF((PyObject *)alist->al_pointer);
+    alist->al_pointer = NULL;
+    prev = alist;
+    alist = alist->al_next;
+    free(prev);
+  }
+}
+
+static void
+PyArenaList_FreeMalloc(PyArenaList *alist)
+{
+  PyArenaList *prev;
+  while (alist) {
+    if (alist->al_pointer) {
+      free(alist->al_pointer);
+    }
+    alist->al_pointer = NULL;
+    prev = alist;
+    alist = alist->al_next;
+    free(prev);
+  }
+}
+
+
+PyAPI_FUNC(PyArena *)
+PyArena_New()
+{
+  PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
+  arena->a_object_head = PyArenaList_New();
+  arena->a_object_tail = arena->a_object_head;
+  arena->a_malloc_head = PyArenaList_New();
+  arena->a_malloc_tail = arena->a_malloc_head;
+  return arena;
+}
+
+PyAPI_FUNC(void)
+PyArena_Free(PyArena *arena)
+{
+  assert(arena);
+  PyArenaList_FreeObject(arena->a_object_head);
+  PyArenaList_FreeMalloc(arena->a_malloc_head);
+  free(arena);
+}
+
+PyAPI_FUNC(void *)
+PyArena_Malloc(PyArena *arena, size_t size) 
+{
+  /* A better implementation might actually use an arena.  The current
+     approach is just a trivial implementation of the API that allows
+     it to be tested.
+  */
+  void *p;
+  assert(size != 0);
+  p = malloc(size);
+  PyArena_AddMallocPointer(arena, p);
+  return p;
+}
+
+PyAPI_FUNC(int)
+PyArena_AddMallocPointer(PyArena *arena, void *pointer) 
+{
+  assert(pointer);
+  PyArenaList *tail = arena->a_malloc_tail;
+  assert(tail->al_pointer != pointer);
+  tail->al_next = PyArenaList_New();
+  tail->al_pointer = pointer;
+  arena->a_malloc_tail = tail->al_next;
+  return 1;
+}
+
+PyAPI_FUNC(int)
+PyArena_AddPyObject(PyArena *arena, PyObject *pointer) 
+{
+  assert(pointer);
+  PyArenaList *tail = arena->a_object_tail;
+  tail->al_next = PyArenaList_New();
+  tail->al_pointer = pointer;
+  arena->a_object_tail = tail->al_next;
+  return 1;
+}

Modified: python/branches/ast-arena/Python/pythonrun.c
==============================================================================
--- python/branches/ast-arena/Python/pythonrun.c	(original)
+++ python/branches/ast-arena/Python/pythonrun.c	Mon Dec  5 06:25:53 2005
@@ -12,6 +12,7 @@
 #include "code.h"
 #include "compile.h"
 #include "symtable.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "eval.h"
 #include "marshal.h"
@@ -36,9 +37,9 @@
 static void initmain(void);
 static void initsite(void);
 static PyObject *run_err_mod(mod_ty, const char *, PyObject *, PyObject *,
-			      PyCompilerFlags *);
+			      PyCompilerFlags *, PyArena *arena);
 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
-			  PyCompilerFlags *);
+			  PyCompilerFlags *, PyArena *);
 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
 			      PyCompilerFlags *);
 static void err_input(perrdetail *);
@@ -697,6 +698,7 @@
 {
 	PyObject *m, *d, *v, *w;
 	mod_ty mod;
+        PyArena *arena;
 	char *ps1 = "", *ps2 = "";
 	int errcode = 0;
 
@@ -716,9 +718,10 @@
 		else if (PyString_Check(w))
 			ps2 = PyString_AsString(w);
 	}
+        arena = PyArena_New();
 	mod = PyParser_ASTFromFile(fp, filename, 
 				   Py_single_input, ps1, ps2,
-				   flags, &errcode);
+				   flags, &errcode, arena);
 	Py_XDECREF(v);
 	Py_XDECREF(w);
 	if (mod == NULL) {
@@ -733,8 +736,8 @@
 	if (m == NULL)
 		return -1;
 	d = PyModule_GetDict(m);
-	v = run_mod(mod, filename, d, d, flags);
-	free_mod(mod);
+	v = run_mod(mod, filename, d, d, flags, arena);
+        PyArena_Free(arena);
 	if (v == NULL) {
 		PyErr_Print();
 		return -1;
@@ -1155,9 +1158,11 @@
 		  PyObject *locals, PyCompilerFlags *flags)
 {
 	PyObject *ret;
-	mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags);
-	ret = run_err_mod(mod, "<string>", globals, locals, flags);
-	free_mod(mod);
+        PyArena *arena = PyArena_New();
+	mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags,
+                                            arena);
+	ret = run_err_mod(mod, "<string>", globals, locals, flags, arena);
+        PyArena_Free(arena);
 	return ret;
 }
 
@@ -1166,33 +1171,36 @@
 		  PyObject *locals, int closeit, PyCompilerFlags *flags)
 {
 	PyObject *ret;
+        PyArena *arena = PyArena_New();
 	mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
-					  flags, NULL);
-	if (mod == NULL)
+					  flags, NULL, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
+        }
 	if (closeit)
 		fclose(fp);
-	ret = run_err_mod(mod, filename, globals, locals, flags);
-	free_mod(mod);
+	ret = run_err_mod(mod, filename, globals, locals, flags, arena);
+        PyArena_Free(arena);
 	return ret;
 }
 
 static PyObject *
 run_err_mod(mod_ty mod, const char *filename, PyObject *globals, 
-	    PyObject *locals, PyCompilerFlags *flags)
+	    PyObject *locals, PyCompilerFlags *flags, PyArena *arena)
 {
 	if (mod == NULL)
 		return  NULL;
-	return run_mod(mod, filename, globals, locals, flags);
+	return run_mod(mod, filename, globals, locals, flags, arena);
 }
 
 static PyObject *
 run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
-	 PyCompilerFlags *flags)
+	 PyCompilerFlags *flags, PyArena *arena)
 {
 	PyCodeObject *co;
 	PyObject *v;
-	co = PyAST_Compile(mod, filename, flags);
+	co = PyAST_Compile(mod, filename, flags, arena);
 	if (co == NULL)
 		return NULL;
 	v = PyEval_EvalCode(co, globals, locals);
@@ -1238,11 +1246,15 @@
 {
 	mod_ty mod;
 	PyCodeObject *co;
-	mod = PyParser_ASTFromString(str, filename, start, flags);
-	if (mod == NULL)
+        PyArena *arena;
+        arena = PyArena_New();
+	mod = PyParser_ASTFromString(str, filename, start, flags, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
-	co = PyAST_Compile(mod, filename, flags);
-	free_mod(mod);
+        }
+	co = PyAST_Compile(mod, filename, flags, arena);
+        PyArena_Free(arena);
 	return (PyObject *)co;
 }
 
@@ -1252,18 +1264,22 @@
 	mod_ty mod;
 	struct symtable *st;
 
-	mod = PyParser_ASTFromString(str, filename, start, NULL);
-	if (mod == NULL)
+        PyArena *arena;
+        arena = PyArena_New();
+	mod = PyParser_ASTFromString(str, filename, start, NULL, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
+        }
 	st = PySymtable_Build(mod, filename, 0);
-	free_mod(mod);
+        PyArena_Free(arena);
 	return st;
 }
 
 /* Preferred access to parser is through AST. */
 mod_ty
 PyParser_ASTFromString(const char *s, const char *filename, int start, 
-		       PyCompilerFlags *flags)
+		       PyCompilerFlags *flags, PyArena *arena)
 {
 	node *n;
 	mod_ty mod;
@@ -1272,7 +1288,7 @@
 					      start, &err, 
 					      PARSER_FLAGS(flags));
 	if (n) {
-		mod = PyAST_FromNode(n, flags, filename);
+		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
 		return mod;
 	}
@@ -1284,7 +1300,8 @@
 
 mod_ty
 PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, 
-		     char *ps2, PyCompilerFlags *flags, int *errcode)
+		     char *ps2, PyCompilerFlags *flags, int *errcode,
+                     PyArena *arena)
 {
 	node *n;
 	mod_ty mod;
@@ -1292,7 +1309,7 @@
 	n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, 
 				    ps1, ps2, &err, PARSER_FLAGS(flags));
 	if (n) {
-		mod = PyAST_FromNode(n, flags, filename);
+		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
 		return mod;
 	}


More information about the Python-checkins mailing list