From patchwork Sat Jul 26 05:57:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 2184 Received: (qmail 14563 invoked by alias); 26 Jul 2014 05:57:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 14539 invoked by uid 89); 26 Jul 2014 05:57:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f51.google.com X-Received: by 10.70.0.48 with SMTP id 16mr23839108pdb.8.1406354245845; Fri, 25 Jul 2014 22:57:25 -0700 (PDT) From: Alan Modra To: bug-gnulib@gnu.org, libc-alpha@sourceware.org Cc: Alan Modra Subject: [PATCH 1/5] obstack tidy Date: Sat, 26 Jul 2014 15:27:08 +0930 Message-Id: <1406354233-7664-2-git-send-email-amodra@gmail.com> In-Reply-To: <1406354233-7664-1-git-send-email-amodra@gmail.com> References: <1406354233-7664-1-git-send-email-amodra@gmail.com> a) Delete nonsense about "not polluting the namespace with stddef.h symbols" since string.h includes stddef.h a little later anyway. b) Don't roll our own slow memcpy in _obstack_newchunk. c) Rename obstack_free to _obstack_free. This makes the naming consistent with other obstack functions and obviates the need for __obstack_free. Ancient obstack.c defined both obstack_free and _obstack_free. We continue to do that for _LIBC via an alias. d) Miscellaneous macro fixes. The expression used to test for gcc-2.8 is clever, but will give a warning nowadays if simulating an old gcc with -U__GNUC__ -U__GNUC_MINOR__ -D__GNUC__=1. e) Move error handling code, to avoid a forward declaration and to simplify later patches in this series. * lib/obstack.h: Include stddef.h unconditionally and stdlib.h earlier. (PTR_INT_TYPE): Delete, replace with ptrdiff_t. (struct obstack ): Rename fields of union and update all uses. (__obstack_free): Delete, update refs. (_obstack_free): Rename from obstack_free. (__extension__): Avoid undefined macro warning for __GNUC_MINOR__. (obstack_object_size, obstack_room): Parenthesise !__GNUC__ versions. * lib/obstack.c: Don't include stddef.h. (COPYING_UNIT): Delete. (_obstack_newchunk): Use memcpy to move existing object to new chunk. (_obstack_free): Rename from __obstack_free, update alias. (obstack_exit_failure, obstack_alloc_failed_handler, _obstack_compat): Move later in file. --- lib/obstack.c | 97 ++++++++++++++++++++------------------------------------- lib/obstack.h | 91 ++++++++++++++++++++++------------------------------- 2 files changed, 71 insertions(+), 117 deletions(-) diff --git a/lib/obstack.c b/lib/obstack.c index 598f6aa..f7cd4e5 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -47,12 +47,11 @@ # endif #endif -#include - #ifndef ELIDE_CODE # include +# include /* Determine default alignment. */ union fooround @@ -75,42 +74,6 @@ enum DEFAULT_ROUNDING = sizeof (union fooround) }; -/* When we copy a long block of data, this is the unit to do it with. - On some machines, copying successive ints does not work; - in such a case, redefine COPYING_UNIT to 'long' (if that works) - or 'char' as a last resort. */ -# ifndef COPYING_UNIT -# define COPYING_UNIT int -# endif - - -/* The functions allocating more room by calling 'obstack_chunk_alloc' - jump to the handler pointed to by 'obstack_alloc_failed_handler'. - This can be set to a user defined function which should either - abort gracefully or use longjump - but shouldn't return. This - variable by default points to the internal function - 'print_and_abort'. */ -static _Noreturn void print_and_abort (void); -void (*obstack_alloc_failed_handler) (void) = print_and_abort; - -/* Exit value used when 'print_and_abort' is used. */ -# include -# ifdef _LIBC -int obstack_exit_failure = EXIT_FAILURE; -# else -# include "exitfail.h" -# define obstack_exit_failure exit_failure -# endif - -# ifdef _LIBC -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -/* A looong time ago (before 1994, anyway; we're not sure) this global variable - was used by non-GNU-C macros to avoid multiple evaluation. The GNU C - library still exports it because somebody might use it. */ -struct obstack *_obstack_compat = 0; -compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); -# endif -# endif /* Define a macro that either calls functions with the traditional malloc/free calling interface, or calls functions with the mmalloc/mfree interface @@ -248,8 +211,6 @@ _obstack_newchunk (struct obstack *h, int length) struct _obstack_chunk *new_chunk; long new_size; long obj_size = h->next_free - h->object_base; - long i; - long already; char *object_base; /* Compute size for new chunk. */ @@ -269,25 +230,8 @@ _obstack_newchunk (struct obstack *h, int length) object_base = __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask); - /* 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 *) object_base)[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++) - object_base[i] = h->object_base[i]; + /* Move the existing object to the new chunk. */ + memcpy (object_base, h->object_base, obj_size); /* If the object just copied was the only data in OLD_CHUNK, free that chunk and remove it from the chain. @@ -342,7 +286,7 @@ _obstack_allocated_p (struct obstack *h, void *obj) # undef obstack_free void -__obstack_free (struct obstack *h, void *obj) +_obstack_free (struct obstack *h, void *obj) { struct _obstack_chunk *lp; /* below addr of any objects in this chunk */ struct _obstack_chunk *plp; /* point to previous chunk if any */ @@ -370,11 +314,9 @@ __obstack_free (struct obstack *h, void *obj) /* obj is not in any of the chunks! */ abort (); } - # ifdef _LIBC -/* Older versions of libc used a function _obstack_free intended to be - called by non-GCC compilers. */ -strong_alias (obstack_free, _obstack_free) +/* Older versions of libc defined both _obstack_free and obstack_free. */ +strong_alias (_obstack_free, obstack_free) # endif int @@ -391,6 +333,15 @@ _obstack_memory_used (struct obstack *h) } /* Define the error handler. */ + +/* Exit value used when 'print_and_abort' is used. */ +# ifdef _LIBC +int obstack_exit_failure = EXIT_FAILURE; +# else +# include "exitfail.h" +# define obstack_exit_failure exit_failure +# endif + # ifdef _LIBC # include # else @@ -420,4 +371,22 @@ print_and_abort (void) exit (obstack_exit_failure); } +/* The functions allocating more room by calling 'obstack_chunk_alloc' + jump to the handler pointed to by 'obstack_alloc_failed_handler'. + This can be set to a user defined function which should either + abort gracefully or use longjump - but shouldn't return. This + variable by default points to the internal function + 'print_and_abort'. */ +void (*obstack_alloc_failed_handler) (void) = print_and_abort; + +# ifdef _LIBC +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) +/* A looong time ago (before 1994, anyway; we're not sure) this global variable + was used by non-GNU-C macros to avoid multiple evaluation. The GNU C + library still exports it because somebody might use it. */ +struct obstack *_obstack_compat = 0; +compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0); +# endif +# endif + #endif /* !ELIDE_CODE */ diff --git a/lib/obstack.h b/lib/obstack.h index f92492f..413c7a3 100644 --- a/lib/obstack.h +++ b/lib/obstack.h @@ -104,17 +104,7 @@ #ifndef _OBSTACK_H #define _OBSTACK_H 1 -/* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is - defined, as with GNU C, use that; that way we don't pollute the - namespace with 's symbols. Otherwise, include - and use ptrdiff_t. */ - -#ifdef __PTRDIFF_TYPE__ -# define PTR_INT_TYPE __PTRDIFF_TYPE__ -#else -# include -# define PTR_INT_TYPE ptrdiff_t -#endif +#include /* If B is the base of an object addressed by P, return the result of aligning P to the next multiple of A + 1. B and P must be of type @@ -122,15 +112,15 @@ #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A))) -/* Similar to _BPTR_ALIGN (B, P, A), except optimize the common case +/* Similar to __BPTR_ALIGN (B, P, A), except optimize the common case where pointers can be converted to integers, aligned as integers, - and converted back again. If PTR_INT_TYPE is narrower than a + and converted back again. If ptrdiff_t is narrower than a pointer (e.g., the AS/400), play it safe and compute the alignment relative to B. Otherwise, use the faster strategy of computing the alignment relative to 0. */ #define __PTR_ALIGN(B, P, A) \ - __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \ + __BPTR_ALIGN (sizeof (ptrdiff_t) < sizeof (void *) ? (B) : (char *) 0, \ P, A) #include @@ -159,8 +149,8 @@ struct obstack /* control current object in current chunk */ char *chunk_limit; /* address of char after current chunk */ union { - PTR_INT_TYPE tempint; - void *tempptr; + ptrdiff_t i; + void *p; } temp; /* Temporary for some macros. */ int alignment_mask; /* Mask of alignment for each object. */ /* These prototypes vary based on 'use_extra_arg', and we use @@ -182,6 +172,7 @@ struct obstack /* control current object in current chunk */ /* Declare the external functions we use; they are in obstack.c. */ 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 *)); extern int _obstack_begin_1 (struct obstack *, int, int, @@ -189,13 +180,6 @@ extern int _obstack_begin_1 (struct obstack *, int, int, void (*)(void *, void *), void *); extern int _obstack_memory_used (struct obstack *) __attribute_pure__; -/* The default name of the function for freeing a chunk is 'obstack_free', - but gnulib users can override this by defining '__obstack_free'. */ -#ifndef __obstack_free -# define __obstack_free obstack_free -#endif -extern void __obstack_free (struct obstack *, void *); - /* Error handler called when 'obstack_chunk_alloc' failed to allocate more memory. This can be set to a user defined function which @@ -258,7 +242,7 @@ extern int obstack_exit_failure; #define obstack_memory_used(h) _obstack_memory_used (h) #if defined __GNUC__ -# if ! (2 < __GNUC__ + (8 <= __GNUC_MINOR__)) +# if !defined __GNUC_MINOR__ || __GNUC__ * 1000 + __GNUC_MINOR__ < 2008 # define __extension__ # endif @@ -406,15 +390,16 @@ extern int obstack_exit_failure; void *__obj = (OBJ); \ if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \ __o->next_free = __o->object_base = (char *) __obj; \ - else (__obstack_free) (__o, __obj); }) + else \ + _obstack_free (__o, __obj); }) #else /* not __GNUC__ */ -# define obstack_object_size(h) \ - (unsigned) ((h)->next_free - (h)->object_base) +# define obstack_object_size(h) \ + ((unsigned) ((h)->next_free - (h)->object_base)) # define obstack_room(h) \ - (unsigned) ((h)->chunk_limit - (h)->next_free) + ((unsigned) ((h)->chunk_limit - (h)->next_free)) # define obstack_empty_p(h) \ ((h)->chunk->prev == 0 \ @@ -429,23 +414,23 @@ extern int obstack_exit_failure; but some compilers won't accept it. */ # define obstack_make_room(h, length) \ - ((h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0)) + ((h)->temp.i = (length), \ + (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0)) # define obstack_grow(h, where, length) \ - ((h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint) + ((h)->temp.i = (length), \ + (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \ + memcpy ((h)->next_free, where, (h)->temp.i), \ + (h)->next_free += (h)->temp.i) # define obstack_grow0(h, where, length) \ - ((h)->temp.tempint = (length), \ - (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \ - memcpy ((h)->next_free, where, (h)->temp.tempint), \ - (h)->next_free += (h)->temp.tempint, \ + ((h)->temp.i = (length), \ + (((h)->next_free + (h)->temp.i + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp.i + 1), 0) : 0), \ + memcpy ((h)->next_free, where, (h)->temp.i), \ + (h)->next_free += (h)->temp.i, \ *((h)->next_free)++ = 0) # define obstack_1grow(h, datum) \ @@ -470,10 +455,10 @@ extern int obstack_exit_failure; (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint)) # define obstack_blank(h, length) \ - ((h)->temp.tempint = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \ - ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \ - obstack_blank_fast (h, (h)->temp.tempint)) + ((h)->temp.i = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp.i) \ + ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \ + obstack_blank_fast (h, (h)->temp.i)) # define obstack_alloc(h, length) \ (obstack_blank ((h), (length)), obstack_finish ((h))) @@ -488,7 +473,7 @@ extern int obstack_exit_failure; (((h)->next_free == (h)->object_base \ ? (((h)->maybe_empty_object = 1), 0) \ : 0), \ - (h)->temp.tempptr = (h)->object_base, \ + (h)->temp.p = (h)->object_base, \ (h)->next_free \ = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ (h)->alignment_mask), \ @@ -496,15 +481,15 @@ extern int obstack_exit_failure; > (h)->chunk_limit - (char *) (h)->chunk) \ ? ((h)->next_free = (h)->chunk_limit) : 0), \ (h)->object_base = (h)->next_free, \ - (h)->temp.tempptr) + (h)->temp.p) # define obstack_free(h, obj) \ - ((h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \ - ((((h)->temp.tempint > 0 \ - && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \ + ((h)->temp.i = (char *) (obj) - (char *) (h)->chunk, \ + ((((h)->temp.i > 0 \ + && (h)->temp.i < (h)->chunk_limit - (char *) (h)->chunk)) \ ? (void) ((h)->next_free = (h)->object_base \ - = (h)->temp.tempint + (char *) (h)->chunk) \ - : (__obstack_free) (h, (h)->temp.tempint + (char *) (h)->chunk))) + = (h)->temp.i + (char *) (h)->chunk) \ + : _obstack_free (h, (h)->temp.i + (char *) (h)->chunk))) #endif /* not __GNUC__ */ @@ -512,4 +497,4 @@ extern int obstack_exit_failure; } /* C++ */ #endif -#endif /* obstack.h */ +#endif /* _OBSTACK_H */