Blame lib/alloca.c

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