diff options
author | Richard Henderson <rth@redhat.com> | 2007-03-29 16:34:10 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2007-03-29 16:34:10 -0700 |
commit | 5b77de89ae8a85507bcb536800633b1a0cb18bdc (patch) | |
tree | 2c919bcf9dbd337e1077d98a0cfd9f4e1deaacc7 | |
parent | 50decae30e08d8210069514bcec5d28550a4ae72 (diff) | |
download | gcc-5b77de89ae8a85507bcb536800633b1a0cb18bdc.tar.gz |
emutls.c (struct __emutls_array): New.
* emutls.c (struct __emutls_array): New.
(emutls_destroy): Use it instead of casting element 0 from void*.
(__emutls_get_address): Likewise.
From-SVN: r123351
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/emutls.c | 43 |
2 files changed, 31 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc59fd773b0..5af2da30d3d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2007-03-29 Richard Henderson <rth@redhat.com> + * emutls.c (struct __emutls_array): New. + (emutls_destroy): Use it instead of casting element 0 from void*. + (__emutls_get_address): Likewise. + +2007-03-29 Richard Henderson <rth@redhat.com> + * varasm.c (initializer_constant_valid_p): Don't deny DECL_DLLIMPORT_P on functions. diff --git a/gcc/emutls.c b/gcc/emutls.c index f26d21772e3..c3374a1c7de 100644 --- a/gcc/emutls.c +++ b/gcc/emutls.c @@ -48,6 +48,12 @@ struct __emutls_object void *templ; }; +struct __emutls_array +{ + pointer size; + void **data[]; +}; + #ifdef __GTHREADS #ifdef __GTHREAD_MUTEX_INIT static __gthread_mutex_t emutls_mutex = __GTHREAD_MUTEX_INIT; @@ -60,15 +66,16 @@ static pointer emutls_size; static void emutls_destroy (void *ptr) { - void ***arr = (void ***) ptr; - unsigned long int size = (unsigned long int) arr[0]; - ++arr; - while (--size) + struct __emutls_array *arr = ptr; + pointer size = arr->size; + pointer i; + + for (i = 0; i < size; ++i) { - if (*arr) - free ((*arr)[-1]); - ++arr; + if (arr->data[i]) + free (arr->data[i][-1]); } + free (ptr); } @@ -130,9 +137,9 @@ __emutls_get_address (struct __emutls_object *obj) #ifndef __GTHREADS abort (); #else - pointer offset; + pointer offset = obj->loc.offset; - if (__builtin_expect (obj->loc.offset == 0, 0)) + if (__builtin_expect (offset == 0, 0)) { static __gthread_once_t once = __GTHREAD_ONCE_INIT; __gthread_once (&once, emutls_init); @@ -141,37 +148,37 @@ __emutls_get_address (struct __emutls_object *obj) obj->loc.offset = offset; __gthread_mutex_unlock (&emutls_mutex); } - else - offset = obj->loc.offset; - void **arr = (void **) __gthread_getspecific (emutls_key); + struct __emutls_array *arr = __gthread_getspecific (emutls_key); if (__builtin_expect (arr == NULL, 0)) { pointer size = offset + 32; arr = calloc (size, sizeof (void *)); if (arr == NULL) abort (); - arr[0] = (void *) size; + arr->size = size; __gthread_setspecific (emutls_key, (void *) arr); } - else if (__builtin_expect (offset >= (pointer) arr[0], 0)) + else if (__builtin_expect (offset >= arr->size, 0)) { - pointer orig_size = (pointer) arr[0]; + pointer orig_size = arr->size; pointer size = orig_size * 2; if (offset >= size) size = offset + 32; arr = realloc (arr, size * sizeof (void *)); if (arr == NULL) abort (); - memset (arr + orig_size, 0, (size - orig_size) * sizeof (void *)); + arr->size = size; + memset (arr->data + orig_size - 1, 0, + (size - orig_size) * sizeof (void *)); __gthread_setspecific (emutls_key, (void *) arr); } - void *ret = arr[offset]; + void *ret = arr->data[offset - 1]; if (__builtin_expect (ret == NULL, 0)) { ret = emutls_alloc (obj); - arr[offset] = ret; + arr->data[offset - 1] = ret; } return ret; #endif |