|
|
1.1 root 1: /* alloca.c -- allocate automatically reclaimed memory
2: (Mostly) portable public-domain implementation -- D A Gwyn
3:
4: This implementation of the PWB library alloca function,
5: which is used to allocate space off the run-time stack so
6: that it is automatically reclaimed upon procedure exit,
7: was inspired by discussions with J. Q. Johnson of Cornell.
8: J.Otto Tennant <[email protected]> contributed the Cray support.
9:
10: There are some preprocessor constants that can
11: be defined when compiling for your specific system, for
12: improved efficiency; however, the defaults should be okay.
13:
14: The general concept of this implementation is to keep
15: track of all alloca-allocated blocks, and reclaim any
16: that are found to be deeper in the stack than the current
17: invocation. This heuristic does not reclaim storage as
18: soon as it becomes invalid, but it will do so eventually.
19:
20: As a special case, alloca(0) reclaims storage without
21: allocating any. It is a good idea to use alloca(0) in
22: your main control loop, etc. to force garbage collection. */
23:
24: #ifdef HAVE_CONFIG_H
25: #if defined (emacs) || defined (CONFIG_BROKETS)
26: #include <config.h>
27: #else
28: #include "config.h"
29: #endif
30: #endif
31:
32: /* If compiling with GCC 2, this file's not needed. */
33: #if !defined (__GNUC__) || __GNUC__ < 2
34:
35: /* If someone has defined alloca as a macro,
36: there must be some other way alloca is supposed to work. */
37: #ifndef alloca
38:
39: #ifdef emacs
40: #ifdef static
41: /* actually, only want this if static is defined as ""
42: -- this is for usg, in which emacs must undefine static
43: in order to make unexec workable
44: */
45: #ifndef STACK_DIRECTION
46: you
47: lose
48: -- must know STACK_DIRECTION at compile-time
49: #endif /* STACK_DIRECTION undefined */
50: #endif /* static */
51: #endif /* emacs */
52:
53: /* If your stack is a linked list of frames, you have to
54: provide an "address metric" ADDRESS_FUNCTION macro. */
55:
56: #if defined (CRAY) && defined (CRAY_STACKSEG_END)
57: long i00afunc ();
58: #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
59: #else
60: #define ADDRESS_FUNCTION(arg) &(arg)
61: #endif
62:
63: #if __STDC__
64: typedef void *pointer;
65: #else
66: typedef char *pointer;
67: #endif
68:
69: #define NULL 0
70:
71: /* Different portions of Emacs need to call different versions of
72: malloc. The Emacs executable needs alloca to call xmalloc, because
73: ordinary malloc isn't protected from input signals. On the other
74: hand, the utilities in lib-src need alloca to call malloc; some of
75: them are very simple, and don't have an xmalloc routine.
76:
77: Non-Emacs programs expect this to call use xmalloc.
78:
79: Callers below should use malloc. */
80:
81: #ifndef emacs
82: #define malloc xmalloc
83: #endif
84: extern pointer malloc ();
85:
86: /* Define STACK_DIRECTION if you know the direction of stack
87: growth for your system; otherwise it will be automatically
88: deduced at run-time.
89:
90: STACK_DIRECTION > 0 => grows toward higher addresses
91: STACK_DIRECTION < 0 => grows toward lower addresses
92: STACK_DIRECTION = 0 => direction of growth unknown */
93:
94: #ifndef STACK_DIRECTION
95: #define STACK_DIRECTION 0 /* Direction unknown. */
96: #endif
97:
98: #if STACK_DIRECTION != 0
99:
100: #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
101:
102: #else /* STACK_DIRECTION == 0; need run-time code. */
103:
104: static int stack_dir; /* 1 or -1 once known. */
105: #define STACK_DIR stack_dir
106:
107: static void
108: find_stack_direction ()
109: {
110: static char *addr = NULL; /* Address of first `dummy', once known. */
111: auto char dummy; /* To get stack address. */
112:
113: if (addr == NULL)
114: { /* Initial entry. */
115: addr = ADDRESS_FUNCTION (dummy);
116:
117: find_stack_direction (); /* Recurse once. */
118: }
119: else
120: {
121: /* Second entry. */
122: if (ADDRESS_FUNCTION (dummy) > addr)
123: stack_dir = 1; /* Stack grew upward. */
124: else
125: stack_dir = -1; /* Stack grew downward. */
126: }
127: }
128:
129: #endif /* STACK_DIRECTION == 0 */
130:
131: /* An "alloca header" is used to:
132: (a) chain together all alloca'ed blocks;
133: (b) keep track of stack depth.
134:
135: It is very important that sizeof(header) agree with malloc
136: alignment chunk size. The following default should work okay. */
137:
138: #ifndef ALIGN_SIZE
139: #define ALIGN_SIZE sizeof(double)
140: #endif
141:
142: typedef union hdr
143: {
144: char align[ALIGN_SIZE]; /* To force sizeof(header). */
145: struct
146: {
147: union hdr *next; /* For chaining headers. */
148: char *deep; /* For stack depth measure. */
149: } h;
150: } header;
151:
152: static header *last_alloca_header = NULL; /* -> last alloca header. */
153:
154: /* Return a pointer to at least SIZE bytes of storage,
155: which will be automatically reclaimed upon exit from
156: the procedure that called alloca. Originally, this space
157: was supposed to be taken from the current stack frame of the
158: caller, but that method cannot be made to work for some
159: implementations of C, for example under Gould's UTX/32. */
160:
161: pointer
162: alloca (size)
163: unsigned size;
164: {
165: auto char probe; /* Probes stack depth: */
166: register char *depth = ADDRESS_FUNCTION (probe);
167:
168: #if STACK_DIRECTION == 0
169: if (STACK_DIR == 0) /* Unknown growth direction. */
170: find_stack_direction ();
171: #endif
172:
173: /* Reclaim garbage, defined as all alloca'd storage that
174: was allocated from deeper in the stack than currently. */
175:
176: {
177: register header *hp; /* Traverses linked list. */
178:
179: for (hp = last_alloca_header; hp != NULL;)
180: if ((STACK_DIR > 0 && hp->h.deep > depth)
181: || (STACK_DIR < 0 && hp->h.deep < depth))
182: {
183: register header *np = hp->h.next;
184:
185: free ((pointer) hp); /* Collect garbage. */
186:
187: hp = np; /* -> next header. */
188: }
189: else
190: break; /* Rest are not deeper. */
191:
192: last_alloca_header = hp; /* -> last valid storage. */
193: }
194:
195: if (size == 0)
196: return NULL; /* No allocation required. */
197:
198: /* Allocate combined header + user data storage. */
199:
200: {
201: register pointer new = malloc (sizeof (header) + size);
202: /* Address of header. */
203:
204: ((header *) new)->h.next = last_alloca_header;
205: ((header *) new)->h.deep = depth;
206:
207: last_alloca_header = (header *) new;
208:
209: /* User storage begins just after header. */
210:
211: return (pointer) ((char *) new + sizeof (header));
212: }
213: }
214:
215: #if defined (CRAY) && defined (CRAY_STACKSEG_END)
216:
217: #ifdef DEBUG_I00AFUNC
218: #include <stdio.h>
219: #endif
220:
221: #ifndef CRAY_STACK
222: #define CRAY_STACK
223: #ifndef CRAY2
224: /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
225: struct stack_control_header
226: {
227: long shgrow:32; /* Number of times stack has grown. */
228: long shaseg:32; /* Size of increments to stack. */
229: long shhwm:32; /* High water mark of stack. */
230: long shsize:32; /* Current size of stack (all segments). */
231: };
232:
233: /* The stack segment linkage control information occurs at
234: the high-address end of a stack segment. (The stack
235: grows from low addresses to high addresses.) The initial
236: part of the stack segment linkage control information is
237: 0200 (octal) words. This provides for register storage
238: for the routine which overflows the stack. */
239:
240: struct stack_segment_linkage
241: {
242: long ss[0200]; /* 0200 overflow words. */
243: long sssize:32; /* Number of words in this segment. */
244: long ssbase:32; /* Offset to stack base. */
245: long:32;
246: long sspseg:32; /* Offset to linkage control of previous
247: segment of stack. */
248: long:32;
249: long sstcpt:32; /* Pointer to task common address block. */
250: long sscsnm; /* Private control structure number for
251: microtasking. */
252: long ssusr1; /* Reserved for user. */
253: long ssusr2; /* Reserved for user. */
254: long sstpid; /* Process ID for pid based multi-tasking. */
255: long ssgvup; /* Pointer to multitasking thread giveup. */
256: long sscray[7]; /* Reserved for Cray Research. */
257: long ssa0;
258: long ssa1;
259: long ssa2;
260: long ssa3;
261: long ssa4;
262: long ssa5;
263: long ssa6;
264: long ssa7;
265: long sss0;
266: long sss1;
267: long sss2;
268: long sss3;
269: long sss4;
270: long sss5;
271: long sss6;
272: long sss7;
273: };
274:
275: #else /* CRAY2 */
276: /* The following structure defines the vector of words
277: returned by the STKSTAT library routine. */
278: struct stk_stat
279: {
280: long now; /* Current total stack size. */
281: long maxc; /* Amount of contiguous space which would
282: be required to satisfy the maximum
283: stack demand to date. */
284: long high_water; /* Stack high-water mark. */
285: long overflows; /* Number of stack overflow ($STKOFEN) calls. */
286: long hits; /* Number of internal buffer hits. */
287: long extends; /* Number of block extensions. */
288: long stko_mallocs; /* Block allocations by $STKOFEN. */
289: long underflows; /* Number of stack underflow calls ($STKRETN). */
290: long stko_free; /* Number of deallocations by $STKRETN. */
291: long stkm_free; /* Number of deallocations by $STKMRET. */
292: long segments; /* Current number of stack segments. */
293: long maxs; /* Maximum number of stack segments so far. */
294: long pad_size; /* Stack pad size. */
295: long current_address; /* Current stack segment address. */
296: long current_size; /* Current stack segment size. This
297: number is actually corrupted by STKSTAT to
298: include the fifteen word trailer area. */
299: long initial_address; /* Address of initial segment. */
300: long initial_size; /* Size of initial segment. */
301: };
302:
303: /* The following structure describes the data structure which trails
304: any stack segment. I think that the description in 'asdef' is
305: out of date. I only describe the parts that I am sure about. */
306:
307: struct stk_trailer
308: {
309: long this_address; /* Address of this block. */
310: long this_size; /* Size of this block (does not include
311: this trailer). */
312: long unknown2;
313: long unknown3;
314: long link; /* Address of trailer block of previous
315: segment. */
316: long unknown5;
317: long unknown6;
318: long unknown7;
319: long unknown8;
320: long unknown9;
321: long unknown10;
322: long unknown11;
323: long unknown12;
324: long unknown13;
325: long unknown14;
326: };
327:
328: #endif /* CRAY2 */
329: #endif /* not CRAY_STACK */
330:
331: #ifdef CRAY2
332: /* Determine a "stack measure" for an arbitrary ADDRESS.
333: I doubt that "lint" will like this much. */
334:
335: static long
336: i00afunc (long *address)
337: {
338: struct stk_stat status;
339: struct stk_trailer *trailer;
340: long *block, size;
341: long result = 0;
342:
343: /* We want to iterate through all of the segments. The first
344: step is to get the stack status structure. We could do this
345: more quickly and more directly, perhaps, by referencing the
346: $LM00 common block, but I know that this works. */
347:
348: STKSTAT (&status);
349:
350: /* Set up the iteration. */
351:
352: trailer = (struct stk_trailer *) (status.current_address
353: + status.current_size
354: - 15);
355:
356: /* There must be at least one stack segment. Therefore it is
357: a fatal error if "trailer" is null. */
358:
359: if (trailer == 0)
360: abort ();
361:
362: /* Discard segments that do not contain our argument address. */
363:
364: while (trailer != 0)
365: {
366: block = (long *) trailer->this_address;
367: size = trailer->this_size;
368: if (block == 0 || size == 0)
369: abort ();
370: trailer = (struct stk_trailer *) trailer->link;
371: if ((block <= address) && (address < (block + size)))
372: break;
373: }
374:
375: /* Set the result to the offset in this segment and add the sizes
376: of all predecessor segments. */
377:
378: result = address - block;
379:
380: if (trailer == 0)
381: {
382: return result;
383: }
384:
385: do
386: {
387: if (trailer->this_size <= 0)
388: abort ();
389: result += trailer->this_size;
390: trailer = (struct stk_trailer *) trailer->link;
391: }
392: while (trailer != 0);
393:
394: /* We are done. Note that if you present a bogus address (one
395: not in any segment), you will get a different number back, formed
396: from subtracting the address of the first block. This is probably
397: not what you want. */
398:
399: return (result);
400: }
401:
402: #else /* not CRAY2 */
403: /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
404: Determine the number of the cell within the stack,
405: given the address of the cell. The purpose of this
406: routine is to linearize, in some sense, stack addresses
407: for alloca. */
408:
409: static long
410: i00afunc (long address)
411: {
412: long stkl = 0;
413:
414: long size, pseg, this_segment, stack;
415: long result = 0;
416:
417: struct stack_segment_linkage *ssptr;
418:
419: /* Register B67 contains the address of the end of the
420: current stack segment. If you (as a subprogram) store
421: your registers on the stack and find that you are past
422: the contents of B67, you have overflowed the segment.
423:
424: B67 also points to the stack segment linkage control
425: area, which is what we are really interested in. */
426:
427: stkl = CRAY_STACKSEG_END ();
428: ssptr = (struct stack_segment_linkage *) stkl;
429:
430: /* If one subtracts 'size' from the end of the segment,
431: one has the address of the first word of the segment.
432:
433: If this is not the first segment, 'pseg' will be
434: nonzero. */
435:
436: pseg = ssptr->sspseg;
437: size = ssptr->sssize;
438:
439: this_segment = stkl - size;
440:
441: /* It is possible that calling this routine itself caused
442: a stack overflow. Discard stack segments which do not
443: contain the target address. */
444:
445: while (!(this_segment <= address && address <= stkl))
446: {
447: #ifdef DEBUG_I00AFUNC
448: fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
449: #endif
450: if (pseg == 0)
451: break;
452: stkl = stkl - pseg;
453: ssptr = (struct stack_segment_linkage *) stkl;
454: size = ssptr->sssize;
455: pseg = ssptr->sspseg;
456: this_segment = stkl - size;
457: }
458:
459: result = address - this_segment;
460:
461: /* If you subtract pseg from the current end of the stack,
462: you get the address of the previous stack segment's end.
463: This seems a little convoluted to me, but I'll bet you save
464: a cycle somewhere. */
465:
466: while (pseg != 0)
467: {
468: #ifdef DEBUG_I00AFUNC
469: fprintf (stderr, "%011o %011o\n", pseg, size);
470: #endif
471: stkl = stkl - pseg;
472: ssptr = (struct stack_segment_linkage *) stkl;
473: size = ssptr->sssize;
474: pseg = ssptr->sspseg;
475: result += size;
476: }
477: return (result);
478: }
479:
480: #endif /* not CRAY2 */
481: #endif /* CRAY */
482:
483: #endif /* no alloca */
484: #endif /* not GCC version 2 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.