w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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