Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Functions | Variables
obstack.c File Reference
#include "obstack.h"
#include <stdio.h>

Go to the source code of this file.

Classes

struct  fooalign
union  fooround

Defines

#define OBSTACK_INTERFACE_VERSION   1
#define POINTER   void *
#define DEFAULT_ALIGNMENT   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
#define DEFAULT_ROUNDING   (sizeof (union fooround))
#define COPYING_UNIT   int
#define EXIT_FAILURE   1
#define CALL_CHUNKFUN(h, size)
#define CALL_FREEFUN(h, old_chunk)
#define _(Str)   (Str)

Functions

static void print_and_abort (void)
int _obstack_begin (struct obstack *h, int size, int alignment, POINTER(*chunkfun)(long), void(*freefun)(void *))
int _obstack_begin_1 (struct obstack *h, int size, int alignment, POINTER(*chunkfun)(POINTER, long), void(*freefun)(POINTER, POINTER), POINTER arg)
void _obstack_newchunk (struct obstack *h, int length)
int _obstack_allocated_p (struct obstack *h, POINTER obj)
void _obstack_free (struct obstack *h, POINTER obj)
void obstack_free (struct obstack *h, POINTER obj)
int _obstack_memory_used (struct obstack *h)

Variables

void(* obstack_alloc_failed_handler )(void) = print_and_abort
int obstack_exit_failure = EXIT_FAILURE
struct obstack_obstack

Class Documentation

struct fooalign

Definition at line 58 of file obstack.c.

Class Members
double d
char x
union fooround

Definition at line 64 of file obstack.c.

Class Members
double d
long x

Define Documentation

#define _ (   Str)    (Str)

Definition at line 412 of file obstack.c.

#define CALL_CHUNKFUN (   h,
  size 
)
Value:
(((h) -> use_extra_arg) \
   ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
   : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))

Definition at line 117 of file obstack.c.

#define CALL_FREEFUN (   h,
  old_chunk 
)
Value:
do { \
    if ((h) -> use_extra_arg) \
      (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
    else \
      (*(void (*) ()) (h)->freefun) ((old_chunk)); \
  } while (0)

Definition at line 122 of file obstack.c.

#define COPYING_UNIT   int

Definition at line 72 of file obstack.c.

#define DEFAULT_ALIGNMENT   ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))

Definition at line 59 of file obstack.c.

#define DEFAULT_ROUNDING   (sizeof (union fooround))

Definition at line 65 of file obstack.c.

#define EXIT_FAILURE   1

Definition at line 88 of file obstack.c.

#define OBSTACK_INTERFACE_VERSION   1

Definition at line 32 of file obstack.c.

#define POINTER   void *

Definition at line 55 of file obstack.c.


Function Documentation

Definition at line 304 of file obstack.c.

{
  register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
  register struct _obstack_chunk *plp;    /* point to previous chunk if any */

  lp = (h)->chunk;
  /* We use >= rather than > since the object cannot be exactly at
     the beginning of the chunk but might be an empty object exactly
     at the end of an adjacent chunk.  */
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
    {
      plp = lp->prev;
      lp = plp;
    }
  return lp != 0;
}
int _obstack_begin ( struct obstack h,
int  size,
int  alignment,
POINTER(*)(long chunkfun,
void(*)(void *)  freefun 
)

Definition at line 142 of file obstack.c.

{
  register struct _obstack_chunk *chunk; /* points to new chunk */

  if (alignment == 0)
    alignment = (int) DEFAULT_ALIGNMENT;
  if (size == 0)
    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
    {
      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
        Use the values for range checking, because if range checking is off,
        the extra bytes won't be missed terribly, but if range checking is on
        and we used a larger request, a whole extra 4096 bytes would be
        allocated.

        These number are irrelevant to the new GNU malloc.  I suspect it is
        less sensitive to the size of the request.  */
      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
                  + 4 + DEFAULT_ROUNDING - 1)
                 & ~(DEFAULT_ROUNDING - 1));
      size = 4096 - extra;
    }

  h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
  h->chunk_size = size;
  h->alignment_mask = alignment - 1;
  h->use_extra_arg = 0;

  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
  if (!chunk)
    (*obstack_alloc_failed_handler) ();
  h->next_free = h->object_base = chunk->contents;
  h->chunk_limit = chunk->limit
    = (char *) chunk + h->chunk_size;
  chunk->prev = 0;
  /* The initial chunk now contains no empty object.  */
  h->maybe_empty_object = 0;
  h->alloc_failed = 0;
  return 1;
}
int _obstack_begin_1 ( struct obstack h,
int  size,
int  alignment,
POINTER(*)(POINTER, long chunkfun,
void(*)(POINTER, POINTER freefun,
POINTER  arg 
)

Definition at line 186 of file obstack.c.

{
  register struct _obstack_chunk *chunk; /* points to new chunk */

  if (alignment == 0)
    alignment = (int) DEFAULT_ALIGNMENT;
  if (size == 0)
    /* Default size is what GNU malloc can fit in a 4096-byte block.  */
    {
      /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
        Use the values for range checking, because if range checking is off,
        the extra bytes won't be missed terribly, but if range checking is on
        and we used a larger request, a whole extra 4096 bytes would be
        allocated.

        These number are irrelevant to the new GNU malloc.  I suspect it is
        less sensitive to the size of the request.  */
      int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
                  + 4 + DEFAULT_ROUNDING - 1)
                 & ~(DEFAULT_ROUNDING - 1));
      size = 4096 - extra;
    }

  h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
  h->chunk_size = size;
  h->alignment_mask = alignment - 1;
  h->extra_arg = arg;
  h->use_extra_arg = 1;

  chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
  if (!chunk)
    (*obstack_alloc_failed_handler) ();
  h->next_free = h->object_base = chunk->contents;
  h->chunk_limit = chunk->limit
    = (char *) chunk + h->chunk_size;
  chunk->prev = 0;
  /* The initial chunk now contains no empty object.  */
  h->maybe_empty_object = 0;
  h->alloc_failed = 0;
  return 1;
}
void _obstack_free ( struct obstack h,
POINTER  obj 
)

Definition at line 330 of file obstack.c.

{
  register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
  register struct _obstack_chunk *plp;    /* point to previous chunk if any */

  lp = h->chunk;
  /* We use >= because there cannot be an object at the beginning of a chunk.
     But there can be an empty object at that address
     at the end of another chunk.  */
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
    {
      plp = lp->prev;
      CALL_FREEFUN (h, lp);
      lp = plp;
      /* If we switch chunks, we can't tell whether the new current
        chunk contains an empty object, so assume that it may.  */
      h->maybe_empty_object = 1;
    }
  if (lp)
    {
      h->object_base = h->next_free = (char *) (obj);
      h->chunk_limit = lp->limit;
      h->chunk = lp;
    }
  else if (obj != 0)
    /* obj is not in any of the chunks! */
    abort ();
}

Definition at line 392 of file obstack.c.

{
  register struct _obstack_chunk* lp;
  register int nbytes = 0;

  for (lp = h->chunk; lp != 0; lp = lp->prev)
    {
      nbytes += lp->limit - (char *) lp;
    }
  return nbytes;
}
void _obstack_newchunk ( struct obstack h,
int  length 
)

Definition at line 238 of file obstack.c.

{
  register struct _obstack_chunk *old_chunk = h->chunk;
  register struct _obstack_chunk *new_chunk;
  register long      new_size;
  register long obj_size = h->next_free - h->object_base;
  register long i;
  long already;

  /* Compute size for new chunk.  */
  new_size = (obj_size + length) + (obj_size >> 3) + 100;
  if (new_size < h->chunk_size)
    new_size = h->chunk_size;

  /* Allocate and initialize the new chunk.  */
  new_chunk = CALL_CHUNKFUN (h, new_size);
  if (!new_chunk)
    (*obstack_alloc_failed_handler) ();
  h->chunk = new_chunk;
  new_chunk->prev = old_chunk;
  new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;

  /* Move the existing object to the new chunk.
     Word at a time is fast and is safe if the object
     is sufficiently aligned.  */
  if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
    {
      for (i = obj_size / sizeof (COPYING_UNIT) - 1;
          i >= 0; i--)
       ((COPYING_UNIT *)new_chunk->contents)[i]
         = ((COPYING_UNIT *)h->object_base)[i];
      /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
        but that can cross a page boundary on a machine
        which does not do strict alignment for COPYING_UNITS.  */
      already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
    }
  else
    already = 0;
  /* Copy remaining bytes one by one.  */
  for (i = already; i < obj_size; i++)
    new_chunk->contents[i] = h->object_base[i];

  /* If the object just copied was the only data in OLD_CHUNK,
     free that chunk and remove it from the chain.
     But not if that chunk might contain an empty object.  */
  if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
    {
      new_chunk->prev = old_chunk->prev;
      CALL_FREEFUN (h, old_chunk);
    }

  h->object_base = new_chunk->contents;
  h->next_free = h->object_base + obj_size;
  /* The new chunk certainly contains no empty object yet.  */
  h->maybe_empty_object = 0;
}
void obstack_free ( struct obstack h,
POINTER  obj 
)

Definition at line 362 of file obstack.c.

{
  register struct _obstack_chunk *lp;     /* below addr of any objects in this chunk */
  register struct _obstack_chunk *plp;    /* point to previous chunk if any */

  lp = h->chunk;
  /* We use >= because there cannot be an object at the beginning of a chunk.
     But there can be an empty object at that address
     at the end of another chunk.  */
  while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
    {
      plp = lp->prev;
      CALL_FREEFUN (h, lp);
      lp = plp;
      /* If we switch chunks, we can't tell whether the new current
        chunk contains an empty object, so assume that it may.  */
      h->maybe_empty_object = 1;
    }
  if (lp)
    {
      h->object_base = h->next_free = (char *) (obj);
      h->chunk_limit = lp->limit;
      h->chunk = lp;
    }
  else if (obj != 0)
    /* obj is not in any of the chunks! */
    abort ();
}
static void print_and_abort ( void  ) [static]

Definition at line 417 of file obstack.c.

{
  fputs (_("memory exhausted\n"), stderr);
  exit (obstack_exit_failure);
}

Variable Documentation

Definition at line 95 of file obstack.c.

Definition at line 81 of file obstack.c.

Definition at line 90 of file obstack.c.