Patchwork [3/5] 64-bit obstack support, part 1

login
register
mail settings
Submitter Alan Modra
Date Oct. 29, 2014, 3:32 a.m.
Message ID <20141029033231.GL4267@bubble.grove.modra.org>
Download mbox | patch
Permalink /patch/3455/
State New
Headers show

Comments

Alan Modra - Oct. 29, 2014, 3:32 a.m.
a) Correct calls to alloc function, to use a size_t arg.  "long" is
   just wrong on targets like x86_64-mingw64 where "long" is 32 bits
   and "size_t" 64 bits.
b) Consolidate _obstack_begin and _obstack_begin1 code.

	* lib/obstack.h (struct obstack <chunkfun>): Correct prototype to
	use "size_t" rather than "long".
	(_obstack_begin, _obstack_begin1): Likewise.
	(obstack_init, obstack_begin, obstack_specify_allocation_with_arg,
	obstack_chunkfun): Update alloc function casts.
	* lib/obstack.c (CALL_CHUNKFUN): Update chunkfun cast.
	(chunkfun_type, freefun_type): New typdefs.
	(_obstack_begin_worker): Split out from ..
	(_obstack_begin, _obstack_begin_1): ..here.
---
 lib/obstack.c | 77 ++++++++++++++++++++++-------------------------------------
 lib/obstack.h | 16 ++++++-------
 2 files changed, 36 insertions(+), 57 deletions(-)
Roland McGrath - Oct. 30, 2014, 7:52 p.m.
It would be easier to review if you separated the very trivial changes from
the others.  The size_t change is clearly fine and can be approved quickly.
The refactoring requires more attention.

Patch

diff --git a/lib/obstack.c b/lib/obstack.c
index 2d5dfbc..d9beb9b 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -94,7 +94,7 @@  compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
 # define CALL_CHUNKFUN(h, size) \
   (((h)->use_extra_arg)							      \
    ? (*(h)->chunkfun)((h)->extra_arg, (size))				      \
-   : (*(struct _obstack_chunk *(*)(long))(h)->chunkfun)((size)))
+   : (*(struct _obstack_chunk *(*)(size_t))(h)->chunkfun)((size)))
 
 # define CALL_FREEFUN(h, old_chunk) \
   do { \
@@ -113,11 +113,13 @@  compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
    Return nonzero if successful, calls obstack_alloc_failed_handler if
    allocation fails.  */
 
-int
-_obstack_begin (struct obstack *h,
-                int size, int alignment,
-                void *(*chunkfun) (long),
-                void (*freefun) (void *))
+typedef struct _obstack_chunk * (*chunkfun_type) (void *, size_t);
+typedef void (*freefun_type) (void *, struct _obstack_chunk *);
+
+static int
+_obstack_begin_worker (struct obstack *h,
+                       int size, int alignment,
+                       chunkfun_type chunkfun, freefun_type freefun)
 {
   struct _obstack_chunk *chunk; /* points to new chunk */
 
@@ -140,11 +142,10 @@  _obstack_begin (struct obstack *h,
       size = 4096 - extra;
     }
 
-  h->chunkfun = (struct _obstack_chunk * (*) (void *, long)) chunkfun;
-  h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+  h->chunkfun = chunkfun;
+  h->freefun = 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)
@@ -160,51 +161,29 @@  _obstack_begin (struct obstack *h,
 }
 
 int
-_obstack_begin_1 (struct obstack *h, int size, int alignment,
-                  void *(*chunkfun) (void *, long),
+_obstack_begin (struct obstack *h,
+                int size, int alignment,
+                void *(*chunkfun) (size_t),
+                void (*freefun) (void *))
+{
+  h->use_extra_arg = 0;
+  return _obstack_begin_worker (h, size, alignment,
+                                (chunkfun_type) chunkfun,
+                                (freefun_type) freefun);
+}
+
+int
+_obstack_begin_1 (struct obstack *h,
+                  int size, int alignment,
+                  void *(*chunkfun) (void *, size_t),
                   void (*freefun) (void *, void *),
                   void *arg)
 {
-  struct _obstack_chunk *chunk; /* points to new chunk */
-
-  if (alignment == 0)
-    alignment = 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 = __PTR_ALIGN ((char *) chunk, chunk->contents,
-                                               alignment - 1);
-  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;
+  return _obstack_begin_worker (h, size, alignment,
+                                (chunkfun_type) chunkfun,
+                                (freefun_type) freefun);
 }
 
 /* Allocate a new current chunk for the obstack *H
diff --git a/lib/obstack.h b/lib/obstack.h
index f3a7c77..ef647aa 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -156,7 +156,7 @@  struct obstack          /* control current object in current chunk */
   /* These prototypes vary based on 'use_extra_arg', and we use
      casts to the prototypeless function type in all assignments,
      but having prototypes here quiets -Wstrict-prototypes.  */
-  struct _obstack_chunk *(*chunkfun) (void *, long);
+  struct _obstack_chunk *(*chunkfun) (void *, size_t);
   void (*freefun) (void *, struct _obstack_chunk *);
   void *extra_arg;              /* first arg for chunk alloc/dealloc funcs */
   unsigned use_extra_arg : 1;     /* chunk alloc/dealloc funcs take extra arg */
@@ -174,9 +174,9 @@  struct obstack          /* control current object in current chunk */
 extern void _obstack_newchunk (struct obstack *, int);
 extern void _obstack_free (struct obstack *, void *);
 extern int _obstack_begin (struct obstack *, int, int,
-                           void *(*)(long), void (*)(void *));
+                           void *(*)(size_t), void (*)(void *));
 extern int _obstack_begin_1 (struct obstack *, int, int,
-                             void *(*)(void *, long),
+                             void *(*)(void *, size_t),
                              void (*)(void *, void *), void *);
 extern int _obstack_memory_used (struct obstack *) __attribute_pure__;
 
@@ -211,26 +211,26 @@  extern int obstack_exit_failure;
 /* To prevent prototype warnings provide complete argument list.  */
 #define obstack_init(h)							      \
   _obstack_begin ((h), 0, 0,						      \
-                  (void *(*)(long))obstack_chunk_alloc,			      \
+                  (void *(*)(size_t))obstack_chunk_alloc,		      \
                   (void (*)(void *))obstack_chunk_free)
 
 #define obstack_begin(h, size)						      \
   _obstack_begin ((h), (size), 0,					      \
-                  (void *(*)(long))obstack_chunk_alloc,			      \
+                  (void *(*)(size_t))obstack_chunk_alloc,		      \
                   (void (*)(void *))obstack_chunk_free)
 
 #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun)     \
   _obstack_begin ((h), (size), (alignment),				      \
-                  (void *(*)(long))(chunkfun),				      \
+                  (void *(*)(size_t))(chunkfun),			      \
                   (void (*)(void *))(freefun))
 
 #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
   _obstack_begin_1 ((h), (size), (alignment),				      \
-                    (void *(*)(void *, long))(chunkfun),		      \
+                    (void *(*)(void *, size_t))(chunkfun),		      \
                     (void (*)(void *, void *))(freefun), (arg))
 
 #define obstack_chunkfun(h, newchunkfun)				      \
-  ((h)->chunkfun = (struct _obstack_chunk *(*)(void *, long))(newchunkfun))
+  ((h)->chunkfun = (struct _obstack_chunk *(*)(void *, size_t))(newchunkfun))
 
 #define obstack_freefun(h, newfreefun)					      \
   ((h)->freefun = (void (*)(void *, struct _obstack_chunk *))(newfreefun))