@@ -51,6 +51,29 @@ frame_getattr(f, name)
5151 return getmember ((char * )f , frame_memberlist , name );
5252}
5353
54+ /* Stack frames are allocated and deallocated at a considerable rate.
55+ In an attempt to improve the speed of function calls, we maintain a
56+ separate free list of stack frames (just like integers are
57+ allocated in a special way -- see intobject.c). When a stack frame
58+ is on the free list, only the following members have a meaning:
59+ ob_type == &Frametype
60+ f_back next item on free list, or NULL
61+ f_nvalues size of f_valuestack
62+ f_valuestack array of (f_nvalues+1) object pointers, or NULL
63+ f_nblocks size of f_blockstack
64+ f_blockstack array of (f_nblocks+1) blocks, or NULL
65+ Note that the value and block stacks are preserved -- this can save
66+ another malloc() call or two (and two free() calls as well!).
67+ Also note that, unlike for integers, each frame object is a
68+ malloc'ed object in its own right -- it is only the actual calls to
69+ malloc() that we are trying to save here, not the administration.
70+ After all, while a typical program may make millions of calls, a
71+ call depth of more than 20 or 30 is probably already exceptional
72+ unless the program contains run-away recursion. I hope.
73+ */
74+
75+ static frameobject * free_list = NULL ;
76+
5477static void
5578frame_dealloc (f )
5679 frameobject * f ;
@@ -59,9 +82,8 @@ frame_dealloc(f)
5982 XDECREF (f -> f_code );
6083 XDECREF (f -> f_globals );
6184 XDECREF (f -> f_locals );
62- XDEL (f -> f_valuestack );
63- XDEL (f -> f_blockstack );
64- DEL (f );
85+ f -> f_back = free_list ;
86+ free_list = f ;
6587}
6688
6789typeobject Frametype = {
@@ -99,7 +121,17 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
99121 err_badcall ();
100122 return NULL ;
101123 }
102- f = NEWOBJ (frameobject , & Frametype );
124+ if (free_list == NULL ) {
125+ f = NEWOBJ (frameobject , & Frametype );
126+ f -> f_nvalues = f -> f_nblocks = 0 ;
127+ f -> f_valuestack = NULL ;
128+ f -> f_blockstack = NULL ;
129+ }
130+ else {
131+ f = free_list ;
132+ free_list = free_list -> f_back ;
133+ NEWREF (f );
134+ }
103135 if (f != NULL ) {
104136 if (back )
105137 INCREF (back );
@@ -110,22 +142,45 @@ newframeobject(back, code, globals, locals, nvalues, nblocks)
110142 f -> f_globals = globals ;
111143 INCREF (locals );
112144 f -> f_locals = locals ;
113- f -> f_valuestack = NEW (object * , nvalues + 1 );
114- f -> f_blockstack = NEW (block , nblocks + 1 );
115- f -> f_nvalues = nvalues ;
116- f -> f_nblocks = nblocks ;
145+ if (nvalues > f -> f_nvalues || f -> f_valuestack == NULL ) {
146+ XDEL (f -> f_valuestack );
147+ f -> f_valuestack = NEW (object * , nvalues + 1 );
148+ f -> f_nvalues = nvalues ;
149+ }
150+ if (nblocks > f -> f_nblocks || f -> f_blockstack == NULL ) {
151+ XDEL (f -> f_blockstack );
152+ f -> f_blockstack = NEW (block , nblocks + 1 );
153+ f -> f_nblocks = nblocks ;
154+ }
117155 f -> f_iblock = 0 ;
156+ f -> f_lasti = 0 ;
157+ f -> f_lineno = -1 ;
118158 if (f -> f_valuestack == NULL || f -> f_blockstack == NULL ) {
119159 err_nomem ();
120160 DECREF (f );
121161 f = NULL ;
122162 }
123- f -> f_lasti = 0 ;
124- f -> f_lineno = -1 ;
125163 }
126164 return f ;
127165}
128166
167+ object * *
168+ extend_stack (f , level , incr )
169+ frameobject * f ;
170+ int level ;
171+ int incr ;
172+ {
173+ f -> f_nvalues = level + incr + 10 ;
174+ f -> f_valuestack =
175+ (object * * ) realloc ((ANY * )f -> f_valuestack ,
176+ sizeof (object * ) * (f -> f_nvalues + 1 ));
177+ if (f -> f_valuestack == NULL ) {
178+ err_nomem ();
179+ return NULL ;
180+ }
181+ return f -> f_valuestack + level ;
182+ }
183+
129184/* Block management */
130185
131186void
0 commit comments