From patchwork Sat Jul 26 05:57:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 2186 Received: (qmail 14724 invoked by alias); 26 Jul 2014 05:57:31 -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 14607 invoked by uid 89); 26 Jul 2014 05:57:30 -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-pd0-f179.google.com X-Received: by 10.66.229.98 with SMTP id sp2mr23787210pac.95.1406354246211; Fri, 25 Jul 2014 22:57:26 -0700 (PDT) From: Alan Modra To: bug-gnulib@gnu.org, libc-alpha@sourceware.org Cc: Alan Modra Subject: [PATCH 3/5] 64-bit obstack support, part 2 Date: Sat, 26 Jul 2014 15:27:10 +0930 Message-Id: <1406354233-7664-4-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> This gets us 4G obstack support, without changing ABI compatibility. a) Replace "int" size parameters, return values, and macro local vars with __OBSTACK_SIZE_T, an "unsigned int" for now. b) Make obstack.chunk_size a __CHUNK_SIZE_T, an "unsigned long" for now. c) Make all obstack macros checking available room use obstack_room. "next_free + desired > chunk_limit" may wrap the lhs for chunks allocated near the top of memory. d) Use unsigned comparisons, and macro locals to support >2G on 32-bit. * lib/obstack.h (__OBSTACK_SIZE_T): Define. Use throughout in place of "int" size parameters, return values and local vars. (__CHUNK_SIZE_T): Define. (struct obstack): Make chunk_size a __CHUNK_SIZE_T. Make temp union use an __OBSTACK_SIZE_T integer type. For __GNUC__ versions of the following macros... (obstack_room): Rename local var. (obstack_make_room): Use obstack_room. (obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow, obstack_int_grow, obstack_blank): Likewise. (obstack_finish): Use unsigned comparison when comparing aligned next_free against chunk_limit. (obstack_free): Cast OBJ to remove possible const qualifier. For !__GNUC__ versions of the following macros... (obstack_make_room): Use obstack_room. (obstack_grow, obstack_grow0, obstack_1grow, obstack_ptr_grow, obstack_int_grow, obstack_blank): Likewise. (obstack_finish): Use unsigned comparision when comparing aligned next_free against chunk_limit. (obstack_free): Use temp.p and same comparisons as __GNUC__ version. * lib/obstack.c (_obstack_begin_worker): Make "size" parameter __OBSTACK_SIZE_T. (_obstack_begin, _obstack_begin_1): Likewise. (_obstack_newchunk): Likewise for length parameter. Use size_t locals. (_obstack_memory_used): Return and use __OBSTACK_SIZE_T local. --- lib/obstack.c | 16 +++++----- lib/obstack.h | 91 ++++++++++++++++++++++++++++++--------------------------- 2 files changed, 56 insertions(+), 51 deletions(-) diff --git a/lib/obstack.c b/lib/obstack.c index 37cf5ae..98b955e 100644 --- a/lib/obstack.c +++ b/lib/obstack.c @@ -108,7 +108,7 @@ typedef void (*freefun_type) (void *, struct _obstack_chunk *); static int _obstack_begin_worker (struct obstack *h, - int size, int alignment, + __OBSTACK_SIZE_T size, int alignment, chunkfun_type chunkfun, freefun_type freefun) { struct _obstack_chunk *chunk; /* points to new chunk */ @@ -153,7 +153,7 @@ _obstack_begin_worker (struct obstack *h, int _obstack_begin (struct obstack *h, - int size, int alignment, + __OBSTACK_SIZE_T size, int alignment, void *(*chunkfun) (size_t), void (*freefun) (void *)) { @@ -165,7 +165,7 @@ _obstack_begin (struct obstack *h, int _obstack_begin_1 (struct obstack *h, - int size, int alignment, + __OBSTACK_SIZE_T size, int alignment, void *(*chunkfun) (void *, size_t), void (*freefun) (void *, void *), void *arg) @@ -184,12 +184,12 @@ _obstack_begin_1 (struct obstack *h, to the beginning of the new one. */ void -_obstack_newchunk (struct obstack *h, int length) +_obstack_newchunk (struct obstack *h, __OBSTACK_SIZE_T length) { struct _obstack_chunk *old_chunk = h->chunk; struct _obstack_chunk *new_chunk; - long new_size; - long obj_size = h->next_free - h->object_base; + size_t new_size; + size_t obj_size = h->next_free - h->object_base; char *object_base; /* Compute size for new chunk. */ @@ -298,11 +298,11 @@ _obstack_free (struct obstack *h, void *obj) strong_alias (_obstack_free, obstack_free) # endif -int +__OBSTACK_SIZE_T _obstack_memory_used (struct obstack *h) { struct _obstack_chunk *lp; - int nbytes = 0; + __OBSTACK_SIZE_T nbytes = 0; for (lp = h->chunk; lp != 0; lp = lp->prev) { diff --git a/lib/obstack.h b/lib/obstack.h index d70408e..daf28bd 100644 --- a/lib/obstack.h +++ b/lib/obstack.h @@ -106,6 +106,9 @@ #include +#define __OBSTACK_SIZE_T unsigned int +#define __CHUNK_SIZE_T unsigned long + /* 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 char *. A + 1 must be a power of 2. */ @@ -142,14 +145,14 @@ struct _obstack_chunk /* Lives at front of each chunk. */ struct obstack /* control current object in current chunk */ { - long chunk_size; /* preferred size to allocate chunks in */ + __CHUNK_SIZE_T chunk_size; /* preferred size to allocate chunks in */ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */ char *object_base; /* address of object we are building */ char *next_free; /* where to add next char to current object */ char *chunk_limit; /* address of char after current chunk */ union { - ptrdiff_t i; + __OBSTACK_SIZE_T i; void *p; } temp; /* Temporary for some macros. */ int alignment_mask; /* Mask of alignment for each object. */ @@ -171,14 +174,15 @@ 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_newchunk (struct obstack *, __OBSTACK_SIZE_T); extern void _obstack_free (struct obstack *, void *); -extern int _obstack_begin (struct obstack *, int, int, +extern int _obstack_begin (struct obstack *, __OBSTACK_SIZE_T, int, void *(*)(size_t), void (*)(void *)); -extern int _obstack_begin_1 (struct obstack *, int, int, +extern int _obstack_begin_1 (struct obstack *, __OBSTACK_SIZE_T, int, void *(*)(void *, size_t), void (*)(void *, void *), void *); -extern int _obstack_memory_used (struct obstack *) __attribute_pure__; +extern __OBSTACK_SIZE_T _obstack_memory_used (struct obstack *) + __attribute_pure__; /* Error handler called when 'obstack_chunk_alloc' failed to allocate @@ -254,18 +258,20 @@ extern int obstack_exit_failure; # define obstack_object_size(OBSTACK) \ __extension__ \ ({ struct obstack const *__o = (OBSTACK); \ - (unsigned) (__o->next_free - __o->object_base); }) + (__OBSTACK_SIZE_T) (__o->next_free - __o->object_base); }) +/* The local variable is named __o1 to avoid a shadowed variable + warning when invoked from other obstack macros. */ # define obstack_room(OBSTACK) \ __extension__ \ - ({ struct obstack const *__o = (OBSTACK); \ - (unsigned) (__o->chunk_limit - __o->next_free); }) + ({ struct obstack const *__o1 = (OBSTACK); \ + (__OBSTACK_SIZE_T) (__o1->chunk_limit - __o1->next_free); }) # define obstack_make_room(OBSTACK, length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ + __OBSTACK_SIZE_T __len = (length); \ + if (obstack_room (__o) < __len) \ _obstack_newchunk (__o, __len); \ (void) 0; }) @@ -280,8 +286,8 @@ extern int obstack_exit_failure; # define obstack_grow(OBSTACK, where, length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len > __o->chunk_limit) \ + __OBSTACK_SIZE_T __len = (length); \ + if (obstack_room (__o) < __len) \ _obstack_newchunk (__o, __len); \ memcpy (__o->next_free, where, __len); \ __o->next_free += __len; \ @@ -290,8 +296,8 @@ extern int obstack_exit_failure; # define obstack_grow0(OBSTACK, where, length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->next_free + __len + 1 > __o->chunk_limit) \ + __OBSTACK_SIZE_T __len = (length); \ + if (obstack_room (__o) < __len + 1) \ _obstack_newchunk (__o, __len + 1); \ memcpy (__o->next_free, where, __len); \ __o->next_free += __len; \ @@ -301,7 +307,7 @@ extern int obstack_exit_failure; # define obstack_1grow(OBSTACK, datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + 1 > __o->chunk_limit) \ + if (obstack_room (__o) < 1) \ _obstack_newchunk (__o, 1); \ obstack_1grow_fast (__o, datum); \ (void) 0; }) @@ -313,14 +319,14 @@ extern int obstack_exit_failure; # define obstack_ptr_grow(OBSTACK, datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ + if (obstack_room (__o) < sizeof (void *)) \ _obstack_newchunk (__o, sizeof (void *)); \ - obstack_ptr_grow_fast (__o, datum); }) \ + obstack_ptr_grow_fast (__o, datum); }) # define obstack_int_grow(OBSTACK, datum) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - if (__o->next_free + sizeof (int) > __o->chunk_limit) \ + if (obstack_room (__o) < sizeof (int)) \ _obstack_newchunk (__o, sizeof (int)); \ obstack_int_grow_fast (__o, datum); }) @@ -343,8 +349,8 @@ extern int obstack_exit_failure; # define obstack_blank(OBSTACK, length) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - int __len = (length); \ - if (__o->chunk_limit - __o->next_free < __len) \ + __OBSTACK_SIZE_T __len = (length); \ + if (obstack_room (__o) < __len) \ _obstack_newchunk (__o, __len); \ obstack_blank_fast (__o, __len); \ (void) 0; }) @@ -367,8 +373,8 @@ extern int obstack_exit_failure; obstack_grow0 (__h, (where), (length)); \ obstack_finish (__h); }) -/* The local variable is named __o1 to avoid a name conflict - when obstack_blank is called. */ +/* The local variable is named __o1 to avoid a shadowed variable + warning when invoked from other obstack macros, typically obstack_free. */ # define obstack_finish(OBSTACK) \ __extension__ \ ({ struct obstack *__o1 = (OBSTACK); \ @@ -378,8 +384,8 @@ extern int obstack_exit_failure; __o1->next_free \ = __PTR_ALIGN (__o1->object_base, __o1->next_free, \ __o1->alignment_mask); \ - if (__o1->next_free - (char *) __o1->chunk \ - > __o1->chunk_limit - (char *) __o1->chunk) \ + if ((size_t) (__o1->next_free - (char *) __o1->chunk) \ + > (size_t) (__o1->chunk_limit - (char *) __o1->chunk)) \ __o1->next_free = __o1->chunk_limit; \ __o1->object_base = __o1->next_free; \ __value; }) @@ -387,7 +393,7 @@ extern int obstack_exit_failure; # define obstack_free(OBSTACK, OBJ) \ __extension__ \ ({ struct obstack *__o = (OBSTACK); \ - void *__obj = (OBJ); \ + void *__obj = (void *) (OBJ); \ if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) \ __o->next_free = __o->object_base = (char *) __obj; \ else \ @@ -396,10 +402,10 @@ extern int obstack_exit_failure; #else /* not __GNUC__ */ # define obstack_object_size(h) \ - ((unsigned) ((h)->next_free - (h)->object_base)) + ((__OBSTACK_SIZE_T) ((h)->next_free - (h)->object_base)) # define obstack_room(h) \ - ((unsigned) ((h)->chunk_limit - (h)->next_free)) + ((__OBSTACK_SIZE_T) ((h)->chunk_limit - (h)->next_free)) # define obstack_empty_p(h) \ ((h)->chunk->prev == 0 \ @@ -415,36 +421,36 @@ extern int obstack_exit_failure; # define obstack_make_room(h, length) \ ((h)->temp.i = (length), \ - (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \ + ((obstack_room (h) < (h)->temp.i) \ ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0)) # define obstack_grow(h, where, length) \ ((h)->temp.i = (length), \ - (((h)->next_free + (h)->temp.i > (h)->chunk_limit) \ + ((obstack_room (h) < (h)->temp.i) \ ? (_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.i = (length), \ - (((h)->next_free + (h)->temp.i + 1 > (h)->chunk_limit) \ + ((obstack_room (h) < (h)->temp.i + 1) \ ? (_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) \ - ((((h)->next_free + 1 > (h)->chunk_limit) \ + (((obstack_room (h) < 1) \ ? (_obstack_newchunk ((h), 1), 0) : 0), \ obstack_1grow_fast (h, datum)) # define obstack_ptr_grow(h, datum) \ - ((((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ + (((obstack_room (h) < sizeof (char *)) \ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ obstack_ptr_grow_fast (h, datum)) # define obstack_int_grow(h, datum) \ - ((((h)->next_free + sizeof (int) > (h)->chunk_limit) \ + (((obstack_room (h) < sizeof (int)) \ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ obstack_int_grow_fast (h, datum)) @@ -456,7 +462,7 @@ extern int obstack_exit_failure; # define obstack_blank(h, length) \ ((h)->temp.i = (length), \ - (((h)->chunk_limit - (h)->next_free < (h)->temp.i) \ + ((obstack_room (h) < (h)->temp.i) \ ? (_obstack_newchunk ((h), (h)->temp.i), 0) : 0), \ obstack_blank_fast (h, (h)->temp.i)) @@ -477,19 +483,18 @@ extern int obstack_exit_failure; (h)->next_free \ = __PTR_ALIGN ((h)->object_base, (h)->next_free, \ (h)->alignment_mask), \ - (((h)->next_free - (char *) (h)->chunk \ - > (h)->chunk_limit - (char *) (h)->chunk) \ + (((size_t) ((h)->next_free - (char *) (h)->chunk) \ + > (size_t) ((h)->chunk_limit - (char *) (h)->chunk)) \ ? ((h)->next_free = (h)->chunk_limit) : 0), \ (h)->object_base = (h)->next_free, \ (h)->temp.p) # define obstack_free(h, obj) \ - ((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.i + (char *) (h)->chunk) \ - : _obstack_free (h, (h)->temp.i + (char *) (h)->chunk))) + ((h)->temp.p = (void *) (obj), \ + (((h)->temp.p > (void *) (h)->chunk \ + && (h)->temp.p < (void *) (h)->chunk_limit) \ + ? (void) ((h)->next_free = (h)->object_base = (char *) (h)->temp.p) \ + : _obstack_free ((h), (h)->temp.p))) #endif /* not __GNUC__ */