Blame gettext-runtime/libasprintf/alloca.c

Packit 5b56b6
/* alloca.c -- allocate automatically reclaimed memory
Packit 5b56b6
   (Mostly) portable public-domain implementation -- D A Gwyn
Packit 5b56b6
Packit 5b56b6
   This implementation of the PWB library alloca function,
Packit 5b56b6
   which is used to allocate space off the run-time stack so
Packit 5b56b6
   that it is automatically reclaimed upon procedure exit,
Packit 5b56b6
   was inspired by discussions with J. Q. Johnson of Cornell.
Packit 5b56b6
   J.Otto Tennant <jot@cray.com> contributed the Cray support.
Packit 5b56b6
Packit 5b56b6
   There are some preprocessor constants that can
Packit 5b56b6
   be defined when compiling for your specific system, for
Packit 5b56b6
   improved efficiency; however, the defaults should be okay.
Packit 5b56b6
Packit 5b56b6
   The general concept of this implementation is to keep
Packit 5b56b6
   track of all alloca-allocated blocks, and reclaim any
Packit 5b56b6
   that are found to be deeper in the stack than the current
Packit 5b56b6
   invocation.  This heuristic does not reclaim storage as
Packit 5b56b6
   soon as it becomes invalid, but it will do so eventually.
Packit 5b56b6
Packit 5b56b6
   As a special case, alloca(0) reclaims storage without
Packit 5b56b6
   allocating any.  It is a good idea to use alloca(0) in
Packit 5b56b6
   your main control loop, etc. to force garbage collection.  */
Packit 5b56b6
Packit 5b56b6
#include <config.h>
Packit 5b56b6
Packit 5b56b6
#include <alloca.h>
Packit 5b56b6
Packit 5b56b6
#include <string.h>
Packit 5b56b6
#include <stdlib.h>
Packit 5b56b6
Packit 5b56b6
#ifdef emacs
Packit 5b56b6
# include "lisp.h"
Packit 5b56b6
# include "blockinput.h"
Packit 5b56b6
# ifdef EMACS_FREE
Packit 5b56b6
#  undef free
Packit 5b56b6
#  define free EMACS_FREE
Packit 5b56b6
# endif
Packit 5b56b6
#else
Packit 5b56b6
# define memory_full() abort ()
Packit 5b56b6
#endif
Packit 5b56b6
Packit 5b56b6
/* If compiling with GCC 2, this file's not needed.  */
Packit 5b56b6
#if !defined (__GNUC__) || __GNUC__ < 2
Packit 5b56b6
Packit 5b56b6
/* If someone has defined alloca as a macro,
Packit 5b56b6
   there must be some other way alloca is supposed to work.  */
Packit 5b56b6
# ifndef alloca
Packit 5b56b6
Packit 5b56b6
#  ifdef emacs
Packit 5b56b6
#   ifdef static
Packit 5b56b6
/* actually, only want this if static is defined as ""
Packit 5b56b6
   -- this is for usg, in which emacs must undefine static
Packit 5b56b6
   in order to make unexec workable
Packit 5b56b6
   */
Packit 5b56b6
#    ifndef STACK_DIRECTION
Packit 5b56b6
you
Packit 5b56b6
lose
Packit 5b56b6
-- must know STACK_DIRECTION at compile-time
Packit 5b56b6
/* Using #error here is not wise since this file should work for
Packit 5b56b6
   old and obscure compilers.  */
Packit 5b56b6
#    endif /* STACK_DIRECTION undefined */
Packit 5b56b6
#   endif /* static */
Packit 5b56b6
#  endif /* emacs */
Packit 5b56b6
Packit 5b56b6
/* If your stack is a linked list of frames, you have to
Packit 5b56b6
   provide an "address metric" ADDRESS_FUNCTION macro.  */
Packit 5b56b6
Packit 5b56b6
#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
Packit 5b56b6
long i00afunc ();
Packit 5b56b6
#   define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
Packit 5b56b6
#  else
Packit 5b56b6
#   define ADDRESS_FUNCTION(arg) &(arg)
Packit 5b56b6
#  endif
Packit 5b56b6
Packit 5b56b6
/* Define STACK_DIRECTION if you know the direction of stack
Packit 5b56b6
   growth for your system; otherwise it will be automatically
Packit 5b56b6
   deduced at run-time.
Packit 5b56b6
Packit 5b56b6
   STACK_DIRECTION > 0 => grows toward higher addresses
Packit 5b56b6
   STACK_DIRECTION < 0 => grows toward lower addresses
Packit 5b56b6
   STACK_DIRECTION = 0 => direction of growth unknown  */
Packit 5b56b6
Packit 5b56b6
#  ifndef STACK_DIRECTION
Packit 5b56b6
#   define STACK_DIRECTION      0       /* Direction unknown.  */
Packit 5b56b6
#  endif
Packit 5b56b6
Packit 5b56b6
#  if STACK_DIRECTION != 0
Packit 5b56b6
Packit 5b56b6
#   define STACK_DIR    STACK_DIRECTION /* Known at compile-time.  */
Packit 5b56b6
Packit 5b56b6
#  else /* STACK_DIRECTION == 0; need run-time code.  */
Packit 5b56b6
Packit 5b56b6
static int stack_dir;           /* 1 or -1 once known.  */
Packit 5b56b6
#   define STACK_DIR    stack_dir
Packit 5b56b6
Packit 5b56b6
static int
Packit 5b56b6
find_stack_direction (int *addr, int depth)
Packit 5b56b6
{
Packit 5b56b6
  int dir, dummy = 0;
Packit 5b56b6
  if (! addr)
Packit 5b56b6
    addr = &dummy;
Packit 5b56b6
  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
Packit 5b56b6
  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
Packit 5b56b6
  return dir + dummy;
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#  endif /* STACK_DIRECTION == 0 */
Packit 5b56b6
Packit 5b56b6
/* An "alloca header" is used to:
Packit 5b56b6
   (a) chain together all alloca'ed blocks;
Packit 5b56b6
   (b) keep track of stack depth.
Packit 5b56b6
Packit 5b56b6
   It is very important that sizeof(header) agree with malloc
Packit 5b56b6
   alignment chunk size.  The following default should work okay.  */
Packit 5b56b6
Packit 5b56b6
#  ifndef       ALIGN_SIZE
Packit 5b56b6
#   define ALIGN_SIZE   sizeof(double)
Packit 5b56b6
#  endif
Packit 5b56b6
Packit 5b56b6
typedef union hdr
Packit 5b56b6
{
Packit 5b56b6
  char align[ALIGN_SIZE];       /* To force sizeof(header).  */
Packit 5b56b6
  struct
Packit 5b56b6
    {
Packit 5b56b6
      union hdr *next;          /* For chaining headers.  */
Packit 5b56b6
      char *deep;               /* For stack depth measure.  */
Packit 5b56b6
    } h;
Packit 5b56b6
} header;
Packit 5b56b6
Packit 5b56b6
static header *last_alloca_header = NULL;       /* -> last alloca header.  */
Packit 5b56b6
Packit 5b56b6
/* Return a pointer to at least SIZE bytes of storage,
Packit 5b56b6
   which will be automatically reclaimed upon exit from
Packit 5b56b6
   the procedure that called alloca.  Originally, this space
Packit 5b56b6
   was supposed to be taken from the current stack frame of the
Packit 5b56b6
   caller, but that method cannot be made to work for some
Packit 5b56b6
   implementations of C, for example under Gould's UTX/32.  */
Packit 5b56b6
Packit 5b56b6
void *
Packit 5b56b6
alloca (size_t size)
Packit 5b56b6
{
Packit 5b56b6
  auto char probe;              /* Probes stack depth: */
Packit 5b56b6
  register char *depth = ADDRESS_FUNCTION (probe);
Packit 5b56b6
Packit 5b56b6
#  if STACK_DIRECTION == 0
Packit 5b56b6
  if (STACK_DIR == 0)           /* Unknown growth direction.  */
Packit 5b56b6
    STACK_DIR = find_stack_direction (NULL, (size & 1) + 20);
Packit 5b56b6
#  endif
Packit 5b56b6
Packit 5b56b6
  /* Reclaim garbage, defined as all alloca'd storage that
Packit 5b56b6
     was allocated from deeper in the stack than currently.  */
Packit 5b56b6
Packit 5b56b6
  {
Packit 5b56b6
    register header *hp;        /* Traverses linked list.  */
Packit 5b56b6
Packit 5b56b6
#  ifdef emacs
Packit 5b56b6
    BLOCK_INPUT;
Packit 5b56b6
#  endif
Packit 5b56b6
Packit 5b56b6
    for (hp = last_alloca_header; hp != NULL;)
Packit 5b56b6
      if ((STACK_DIR > 0 && hp->h.deep > depth)
Packit 5b56b6
          || (STACK_DIR < 0 && hp->h.deep < depth))
Packit 5b56b6
        {
Packit 5b56b6
          register header *np = hp->h.next;
Packit 5b56b6
Packit 5b56b6
          free (hp);            /* Collect garbage.  */
Packit 5b56b6
Packit 5b56b6
          hp = np;              /* -> next header.  */
Packit 5b56b6
        }
Packit 5b56b6
      else
Packit 5b56b6
        break;                  /* Rest are not deeper.  */
Packit 5b56b6
Packit 5b56b6
    last_alloca_header = hp;    /* -> last valid storage.  */
Packit 5b56b6
Packit 5b56b6
#  ifdef emacs
Packit 5b56b6
    UNBLOCK_INPUT;
Packit 5b56b6
#  endif
Packit 5b56b6
  }
Packit 5b56b6
Packit 5b56b6
  if (size == 0)
Packit 5b56b6
    return NULL;                /* No allocation required.  */
Packit 5b56b6
Packit 5b56b6
  /* Allocate combined header + user data storage.  */
Packit 5b56b6
Packit 5b56b6
  {
Packit 5b56b6
    /* Address of header.  */
Packit 5b56b6
    register header *new;
Packit 5b56b6
Packit 5b56b6
    size_t combined_size = sizeof (header) + size;
Packit 5b56b6
    if (combined_size < sizeof (header))
Packit 5b56b6
      memory_full ();
Packit 5b56b6
Packit 5b56b6
    new = malloc (combined_size);
Packit 5b56b6
Packit 5b56b6
    if (! new)
Packit 5b56b6
      memory_full ();
Packit 5b56b6
Packit 5b56b6
    new->h.next = last_alloca_header;
Packit 5b56b6
    new->h.deep = depth;
Packit 5b56b6
Packit 5b56b6
    last_alloca_header = new;
Packit 5b56b6
Packit 5b56b6
    /* User storage begins just after header.  */
Packit 5b56b6
Packit 5b56b6
    return (void *) (new + 1);
Packit 5b56b6
  }
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#  if defined (CRAY) && defined (CRAY_STACKSEG_END)
Packit 5b56b6
Packit 5b56b6
#   ifdef DEBUG_I00AFUNC
Packit 5b56b6
#    include <stdio.h>
Packit 5b56b6
#   endif
Packit 5b56b6
Packit 5b56b6
#   ifndef CRAY_STACK
Packit 5b56b6
#    define CRAY_STACK
Packit 5b56b6
#    ifndef CRAY2
Packit 5b56b6
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
Packit 5b56b6
struct stack_control_header
Packit 5b56b6
  {
Packit 5b56b6
    long shgrow:32;             /* Number of times stack has grown.  */
Packit 5b56b6
    long shaseg:32;             /* Size of increments to stack.  */
Packit 5b56b6
    long shhwm:32;              /* High water mark of stack.  */
Packit 5b56b6
    long shsize:32;             /* Current size of stack (all segments).  */
Packit 5b56b6
  };
Packit 5b56b6
Packit 5b56b6
/* The stack segment linkage control information occurs at
Packit 5b56b6
   the high-address end of a stack segment.  (The stack
Packit 5b56b6
   grows from low addresses to high addresses.)  The initial
Packit 5b56b6
   part of the stack segment linkage control information is
Packit 5b56b6
   0200 (octal) words.  This provides for register storage
Packit 5b56b6
   for the routine which overflows the stack.  */
Packit 5b56b6
Packit 5b56b6
struct stack_segment_linkage
Packit 5b56b6
  {
Packit 5b56b6
    long ss[0200];              /* 0200 overflow words.  */
Packit 5b56b6
    long sssize:32;             /* Number of words in this segment.  */
Packit 5b56b6
    long ssbase:32;             /* Offset to stack base.  */
Packit 5b56b6
    long:32;
Packit 5b56b6
    long sspseg:32;             /* Offset to linkage control of previous
Packit 5b56b6
                                   segment of stack.  */
Packit 5b56b6
    long:32;
Packit 5b56b6
    long sstcpt:32;             /* Pointer to task common address block.  */
Packit 5b56b6
    long sscsnm;                /* Private control structure number for
Packit 5b56b6
                                   microtasking.  */
Packit 5b56b6
    long ssusr1;                /* Reserved for user.  */
Packit 5b56b6
    long ssusr2;                /* Reserved for user.  */
Packit 5b56b6
    long sstpid;                /* Process ID for pid based multi-tasking.  */
Packit 5b56b6
    long ssgvup;                /* Pointer to multitasking thread giveup.  */
Packit 5b56b6
    long sscray[7];             /* Reserved for Cray Research.  */
Packit 5b56b6
    long ssa0;
Packit 5b56b6
    long ssa1;
Packit 5b56b6
    long ssa2;
Packit 5b56b6
    long ssa3;
Packit 5b56b6
    long ssa4;
Packit 5b56b6
    long ssa5;
Packit 5b56b6
    long ssa6;
Packit 5b56b6
    long ssa7;
Packit 5b56b6
    long sss0;
Packit 5b56b6
    long sss1;
Packit 5b56b6
    long sss2;
Packit 5b56b6
    long sss3;
Packit 5b56b6
    long sss4;
Packit 5b56b6
    long sss5;
Packit 5b56b6
    long sss6;
Packit 5b56b6
    long sss7;
Packit 5b56b6
  };
Packit 5b56b6
Packit 5b56b6
#    else /* CRAY2 */
Packit 5b56b6
/* The following structure defines the vector of words
Packit 5b56b6
   returned by the STKSTAT library routine.  */
Packit 5b56b6
struct stk_stat
Packit 5b56b6
  {
Packit 5b56b6
    long now;                   /* Current total stack size.  */
Packit 5b56b6
    long maxc;                  /* Amount of contiguous space which would
Packit 5b56b6
                                   be required to satisfy the maximum
Packit 5b56b6
                                   stack demand to date.  */
Packit 5b56b6
    long high_water;            /* Stack high-water mark.  */
Packit 5b56b6
    long overflows;             /* Number of stack overflow ($STKOFEN) calls.  */
Packit 5b56b6
    long hits;                  /* Number of internal buffer hits.  */
Packit 5b56b6
    long extends;               /* Number of block extensions.  */
Packit 5b56b6
    long stko_mallocs;          /* Block allocations by $STKOFEN.  */
Packit 5b56b6
    long underflows;            /* Number of stack underflow calls ($STKRETN).  */
Packit 5b56b6
    long stko_free;             /* Number of deallocations by $STKRETN.  */
Packit 5b56b6
    long stkm_free;             /* Number of deallocations by $STKMRET.  */
Packit 5b56b6
    long segments;              /* Current number of stack segments.  */
Packit 5b56b6
    long maxs;                  /* Maximum number of stack segments so far.  */
Packit 5b56b6
    long pad_size;              /* Stack pad size.  */
Packit 5b56b6
    long current_address;       /* Current stack segment address.  */
Packit 5b56b6
    long current_size;          /* Current stack segment size.  This
Packit 5b56b6
                                   number is actually corrupted by STKSTAT to
Packit 5b56b6
                                   include the fifteen word trailer area.  */
Packit 5b56b6
    long initial_address;       /* Address of initial segment.  */
Packit 5b56b6
    long initial_size;          /* Size of initial segment.  */
Packit 5b56b6
  };
Packit 5b56b6
Packit 5b56b6
/* The following structure describes the data structure which trails
Packit 5b56b6
   any stack segment.  I think that the description in 'asdef' is
Packit 5b56b6
   out of date.  I only describe the parts that I am sure about.  */
Packit 5b56b6
Packit 5b56b6
struct stk_trailer
Packit 5b56b6
  {
Packit 5b56b6
    long this_address;          /* Address of this block.  */
Packit 5b56b6
    long this_size;             /* Size of this block (does not include
Packit 5b56b6
                                   this trailer).  */
Packit 5b56b6
    long unknown2;
Packit 5b56b6
    long unknown3;
Packit 5b56b6
    long link;                  /* Address of trailer block of previous
Packit 5b56b6
                                   segment.  */
Packit 5b56b6
    long unknown5;
Packit 5b56b6
    long unknown6;
Packit 5b56b6
    long unknown7;
Packit 5b56b6
    long unknown8;
Packit 5b56b6
    long unknown9;
Packit 5b56b6
    long unknown10;
Packit 5b56b6
    long unknown11;
Packit 5b56b6
    long unknown12;
Packit 5b56b6
    long unknown13;
Packit 5b56b6
    long unknown14;
Packit 5b56b6
  };
Packit 5b56b6
Packit 5b56b6
#    endif /* CRAY2 */
Packit 5b56b6
#   endif /* not CRAY_STACK */
Packit 5b56b6
Packit 5b56b6
#   ifdef CRAY2
Packit 5b56b6
/* Determine a "stack measure" for an arbitrary ADDRESS.
Packit 5b56b6
   I doubt that "lint" will like this much.  */
Packit 5b56b6
Packit 5b56b6
static long
Packit 5b56b6
i00afunc (long *address)
Packit 5b56b6
{
Packit 5b56b6
  struct stk_stat status;
Packit 5b56b6
  struct stk_trailer *trailer;
Packit 5b56b6
  long *block, size;
Packit 5b56b6
  long result = 0;
Packit 5b56b6
Packit 5b56b6
  /* We want to iterate through all of the segments.  The first
Packit 5b56b6
     step is to get the stack status structure.  We could do this
Packit 5b56b6
     more quickly and more directly, perhaps, by referencing the
Packit 5b56b6
     $LM00 common block, but I know that this works.  */
Packit 5b56b6
Packit 5b56b6
  STKSTAT (&status);
Packit 5b56b6
Packit 5b56b6
  /* Set up the iteration.  */
Packit 5b56b6
Packit 5b56b6
  trailer = (struct stk_trailer *) (status.current_address
Packit 5b56b6
                                    + status.current_size
Packit 5b56b6
                                    - 15);
Packit 5b56b6
Packit 5b56b6
  /* There must be at least one stack segment.  Therefore it is
Packit 5b56b6
     a fatal error if "trailer" is null.  */
Packit 5b56b6
Packit 5b56b6
  if (trailer == 0)
Packit 5b56b6
    abort ();
Packit 5b56b6
Packit 5b56b6
  /* Discard segments that do not contain our argument address.  */
Packit 5b56b6
Packit 5b56b6
  while (trailer != 0)
Packit 5b56b6
    {
Packit 5b56b6
      block = (long *) trailer->this_address;
Packit 5b56b6
      size = trailer->this_size;
Packit 5b56b6
      if (block == 0 || size == 0)
Packit 5b56b6
        abort ();
Packit 5b56b6
      trailer = (struct stk_trailer *) trailer->link;
Packit 5b56b6
      if ((block <= address) && (address < (block + size)))
Packit 5b56b6
        break;
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  /* Set the result to the offset in this segment and add the sizes
Packit 5b56b6
     of all predecessor segments.  */
Packit 5b56b6
Packit 5b56b6
  result = address - block;
Packit 5b56b6
Packit 5b56b6
  if (trailer == 0)
Packit 5b56b6
    {
Packit 5b56b6
      return result;
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  do
Packit 5b56b6
    {
Packit 5b56b6
      if (trailer->this_size <= 0)
Packit 5b56b6
        abort ();
Packit 5b56b6
      result += trailer->this_size;
Packit 5b56b6
      trailer = (struct stk_trailer *) trailer->link;
Packit 5b56b6
    }
Packit 5b56b6
  while (trailer != 0);
Packit 5b56b6
Packit 5b56b6
  /* We are done.  Note that if you present a bogus address (one
Packit 5b56b6
     not in any segment), you will get a different number back, formed
Packit 5b56b6
     from subtracting the address of the first block.  This is probably
Packit 5b56b6
     not what you want.  */
Packit 5b56b6
Packit 5b56b6
  return (result);
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#   else /* not CRAY2 */
Packit 5b56b6
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
Packit 5b56b6
   Determine the number of the cell within the stack,
Packit 5b56b6
   given the address of the cell.  The purpose of this
Packit 5b56b6
   routine is to linearize, in some sense, stack addresses
Packit 5b56b6
   for alloca.  */
Packit 5b56b6
Packit 5b56b6
static long
Packit 5b56b6
i00afunc (long address)
Packit 5b56b6
{
Packit 5b56b6
  long stkl = 0;
Packit 5b56b6
Packit 5b56b6
  long size, pseg, this_segment, stack;
Packit 5b56b6
  long result = 0;
Packit 5b56b6
Packit 5b56b6
  struct stack_segment_linkage *ssptr;
Packit 5b56b6
Packit 5b56b6
  /* Register B67 contains the address of the end of the
Packit 5b56b6
     current stack segment.  If you (as a subprogram) store
Packit 5b56b6
     your registers on the stack and find that you are past
Packit 5b56b6
     the contents of B67, you have overflowed the segment.
Packit 5b56b6
Packit 5b56b6
     B67 also points to the stack segment linkage control
Packit 5b56b6
     area, which is what we are really interested in.  */
Packit 5b56b6
Packit 5b56b6
  stkl = CRAY_STACKSEG_END ();
Packit 5b56b6
  ssptr = (struct stack_segment_linkage *) stkl;
Packit 5b56b6
Packit 5b56b6
  /* If one subtracts 'size' from the end of the segment,
Packit 5b56b6
     one has the address of the first word of the segment.
Packit 5b56b6
Packit 5b56b6
     If this is not the first segment, 'pseg' will be
Packit 5b56b6
     nonzero.  */
Packit 5b56b6
Packit 5b56b6
  pseg = ssptr->sspseg;
Packit 5b56b6
  size = ssptr->sssize;
Packit 5b56b6
Packit 5b56b6
  this_segment = stkl - size;
Packit 5b56b6
Packit 5b56b6
  /* It is possible that calling this routine itself caused
Packit 5b56b6
     a stack overflow.  Discard stack segments which do not
Packit 5b56b6
     contain the target address.  */
Packit 5b56b6
Packit 5b56b6
  while (!(this_segment <= address && address <= stkl))
Packit 5b56b6
    {
Packit 5b56b6
#    ifdef DEBUG_I00AFUNC
Packit 5b56b6
      fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
Packit 5b56b6
#    endif
Packit 5b56b6
      if (pseg == 0)
Packit 5b56b6
        break;
Packit 5b56b6
      stkl = stkl - pseg;
Packit 5b56b6
      ssptr = (struct stack_segment_linkage *) stkl;
Packit 5b56b6
      size = ssptr->sssize;
Packit 5b56b6
      pseg = ssptr->sspseg;
Packit 5b56b6
      this_segment = stkl - size;
Packit 5b56b6
    }
Packit 5b56b6
Packit 5b56b6
  result = address - this_segment;
Packit 5b56b6
Packit 5b56b6
  /* If you subtract pseg from the current end of the stack,
Packit 5b56b6
     you get the address of the previous stack segment's end.
Packit 5b56b6
     This seems a little convoluted to me, but I'll bet you save
Packit 5b56b6
     a cycle somewhere.  */
Packit 5b56b6
Packit 5b56b6
  while (pseg != 0)
Packit 5b56b6
    {
Packit 5b56b6
#    ifdef DEBUG_I00AFUNC
Packit 5b56b6
      fprintf (stderr, "%011o %011o\n", pseg, size);
Packit 5b56b6
#    endif
Packit 5b56b6
      stkl = stkl - pseg;
Packit 5b56b6
      ssptr = (struct stack_segment_linkage *) stkl;
Packit 5b56b6
      size = ssptr->sssize;
Packit 5b56b6
      pseg = ssptr->sspseg;
Packit 5b56b6
      result += size;
Packit 5b56b6
    }
Packit 5b56b6
  return (result);
Packit 5b56b6
}
Packit 5b56b6
Packit 5b56b6
#   endif /* not CRAY2 */
Packit 5b56b6
#  endif /* CRAY */
Packit 5b56b6
Packit 5b56b6
# endif /* no alloca */
Packit 5b56b6
#endif /* not GCC 2 */