Mercurial > hg > CbC > CbC_gcc
diff gcc/vec.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/vec.c Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/vec.c Fri Feb 12 23:39:51 2010 +0900 @@ -33,7 +33,7 @@ #include "toplev.h" #include "hashtab.h" -struct vec_prefix +struct vec_prefix { unsigned num; unsigned alloc; @@ -113,7 +113,8 @@ if (!vec_desc_hash) vec_desc_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL); - slot = (struct vec_descriptor **) htab_find_slot (vec_desc_hash, &loc, 1); + slot = (struct vec_descriptor **) htab_find_slot (vec_desc_hash, &loc, + INSERT); if (*slot) return *slot; *slot = XCNEW (struct vec_descriptor); @@ -189,10 +190,10 @@ /* If there's no prefix, and we've not requested anything, then we will create a NULL vector. */ return 0; - + /* We must have run out of room. */ gcc_assert (alloc - num < (unsigned) reserve); - + if (exact) /* Exact size. */ alloc = num + reserve; @@ -207,7 +208,7 @@ else /* Grow slower when large. */ alloc = (alloc * 3 / 2); - + /* If this is still too small, set it to the right size. */ if (alloc < num + reserve) alloc = num + reserve; @@ -226,20 +227,20 @@ bool exact MEM_STAT_DECL) { struct vec_prefix *pfx = (struct vec_prefix *) vec; - unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact); - + unsigned alloc = calculate_allocation (pfx, reserve, exact); + if (!alloc) { if (pfx) ggc_free (pfx); return NULL; } - + vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT); ((struct vec_prefix *)vec)->alloc = alloc; if (!pfx) ((struct vec_prefix *)vec)->num = 0; - + return vec; } @@ -315,7 +316,7 @@ if (vec) free_overhead (pfx); #endif - + vec = xrealloc (vec, vec_offset + alloc * elt_size); ((struct vec_prefix *)vec)->alloc = alloc; if (!pfx) @@ -325,7 +326,7 @@ register_overhead ((struct vec_prefix *)vec, vec_offset + alloc * elt_size PASS_MEM_STAT); #endif - + return vec; } @@ -371,6 +372,147 @@ PASS_MEM_STAT); } +/* Stack vectors are a little different. VEC_alloc turns into a call + to vec_stack_p_reserve_exact1 and passes in space allocated via a + call to alloca. We record that pointer so that we know that we + shouldn't free it. If the vector is resized, we resize it on the + heap. We record the pointers in a vector and search it in LIFO + order--i.e., we look for the newest stack vectors first. We don't + expect too many stack vectors at any one level, and searching from + the end should normally be efficient even if they are used in a + recursive function. */ + +typedef void *void_p; +DEF_VEC_P(void_p); +DEF_VEC_ALLOC_P(void_p,heap); + +static VEC(void_p,heap) *stack_vecs; + +/* Allocate a vector which uses alloca for the initial allocation. + SPACE is space allocated using alloca, ALLOC is the number of + entries allocated. */ + +void * +vec_stack_p_reserve_exact_1 (int alloc, void *space) +{ + struct vec_prefix *pfx = (struct vec_prefix *) space; + + VEC_safe_push (void_p, heap, stack_vecs, space); + + pfx->num = 0; + pfx->alloc = alloc; + + return space; +} + +/* Grow a vector allocated using alloca. When this happens, we switch + back to heap allocation. We remove the vector from stack_vecs, if + it is there, since we no longer need to avoid freeing it. */ + +static void * +vec_stack_o_reserve_1 (void *vec, int reserve, size_t vec_offset, + size_t elt_size, bool exact MEM_STAT_DECL) +{ + bool found; + unsigned int ix; + void *newvec; + + found = false; + for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix) + { + if (VEC_index (void_p, stack_vecs, ix - 1) == vec) + { + VEC_unordered_remove (void_p, stack_vecs, ix - 1); + found = true; + break; + } + } + + if (!found) + { + /* VEC is already on the heap. */ + return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, + exact PASS_MEM_STAT); + } + + /* Move VEC to the heap. */ + reserve += ((struct vec_prefix *) vec)->num; + newvec = vec_heap_o_reserve_1 (NULL, reserve, vec_offset, elt_size, + exact PASS_MEM_STAT); + if (newvec && vec) + { + ((struct vec_prefix *) newvec)->num = ((struct vec_prefix *) vec)->num; + memcpy (((struct vec_prefix *) newvec)->vec, + ((struct vec_prefix *) vec)->vec, + ((struct vec_prefix *) vec)->num * elt_size); + } + return newvec; +} + +/* Grow a vector allocated on the stack. */ + +void * +vec_stack_p_reserve (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), false + PASS_MEM_STAT); +} + +/* Exact version of vec_stack_p_reserve. */ + +void * +vec_stack_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, + offsetof (struct vec_prefix, vec), + sizeof (void *), true + PASS_MEM_STAT); +} + +/* Like vec_stack_p_reserve, but for objects. */ + +void * +vec_stack_o_reserve (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, false + PASS_MEM_STAT); +} + +/* Like vec_stack_p_reserve_exact, but for objects. */ + +void * +vec_stack_o_reserve_exact (void *vec, int reserve, size_t vec_offset, + size_t elt_size MEM_STAT_DECL) +{ + return vec_stack_o_reserve_1 (vec, reserve, vec_offset, elt_size, true + PASS_MEM_STAT); +} + +/* Free a vector allocated on the stack. Don't actually free it if we + find it in the hash table. */ + +void +vec_stack_free (void *vec) +{ + unsigned int ix; + + for (ix = VEC_length (void_p, stack_vecs); ix > 0; --ix) + { + if (VEC_index (void_p, stack_vecs, ix - 1) == vec) + { + VEC_unordered_remove (void_p, stack_vecs, ix - 1); + return; + } + } + + /* VEC was not on the list of vecs allocated on the stack, so it + must be allocated on the heap. */ + vec_heap_free (vec); +} + #if ENABLE_CHECKING /* Issue a vector domain error, and then fall over. */