Commit efb7e1e0 by Ian Lance Taylor Committed by Ian Lance Taylor

vec.h (VEC_reserve_exact): Define.

./:	* vec.h (VEC_reserve_exact): Define.
	(vec_gc_p_reserve_exact): Declare.
	(vec_gc_o_reserve_exact): Declare.
	(vec_heap_p_reserve_exact): Declare.
	(vec_heap_o_reserve_exact): Declare.
	(VEC_OP (T,A,reserve_exact)): New static inline function, three
	versions.
	(VEC_OP (T,A,reserve)) [all versions]: Remove handling of
	negative parameter.
	(VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact.
	(VEC_OP (T,A,copy)) [all versions]: Likewise.
	(VEC_OP (T,a,safe_grow)) [all versions]: Likewise.
	* vec.c (calculate_allocation): Add exact parameter.  Change all
	callers.
	(vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve.
	(vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1.
	(vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions.
	(vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve.
	(vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1.
	(vec_heap_p_reserve_exact): New function.
	(vec_heap_o_reserve_exact): New function.
cp/:
	* class.c (add_method): Call VEC_reserve_exact rather than passing
	a negative size to VEC_reserve.

From-SVN: r120861
parent 9dd8004e
2007-01-17 Ian Lance Taylor <iant@google.com>
* vec.h (VEC_reserve_exact): Define.
(vec_gc_p_reserve_exact): Declare.
(vec_gc_o_reserve_exact): Declare.
(vec_heap_p_reserve_exact): Declare.
(vec_heap_o_reserve_exact): Declare.
(VEC_OP (T,A,reserve_exact)): New static inline function, three
versions.
(VEC_OP (T,A,reserve)) [all versions]: Remove handling of
negative parameter.
(VEC_OP (T,A,alloc)) [all versions]: Call ...reserve_exact.
(VEC_OP (T,A,copy)) [all versions]: Likewise.
(VEC_OP (T,a,safe_grow)) [all versions]: Likewise.
* vec.c (calculate_allocation): Add exact parameter. Change all
callers.
(vec_gc_o_reserve_1): New static function, from vec_gc_o_reserve.
(vec_gc_p_reserve, vec_gc_o_reserve): Call vec_gc_o_reserve_1.
(vec_gc_p_reserve_exact, vec_gc_o_reserve_exact): New functions.
(vec_heap_o_reserve_1): New static function, from vec_heap_o_reserve.
(vec_heap_p_reserve, vec_heap_o_reserve): Call vec_heap_o_reserve_1.
(vec_heap_p_reserve_exact): New function.
(vec_heap_o_reserve_exact): New function.
2007-01-17 Jan Hubicka <jh@suse.cz> 2007-01-17 Jan Hubicka <jh@suse.cz>
* ipa-type-escape.c (look_for_casts): Revamp using handled_component_p. * ipa-type-escape.c (look_for_casts): Revamp using handled_component_p.
......
2007-01-17 Ian Lance Taylor <iant@google.com>
* class.c (add_method): Call VEC_reserve_exact rather than passing
a negative size to VEC_reserve.
2007-01-11 Simon Martin <simartin@users.sourceforge.net> 2007-01-11 Simon Martin <simartin@users.sourceforge.net>
PR c++/29573 PR c++/29573
......
...@@ -1071,9 +1071,15 @@ add_method (tree type, tree method, tree using_decl) ...@@ -1071,9 +1071,15 @@ add_method (tree type, tree method, tree using_decl)
if (insert_p) if (insert_p)
{ {
bool reallocated;
/* We only expect to add few methods in the COMPLETE_P case, so /* We only expect to add few methods in the COMPLETE_P case, so
just make room for one more method in that case. */ just make room for one more method in that case. */
if (VEC_reserve (tree, gc, method_vec, complete_p ? -1 : 1)) if (complete_p)
reallocated = VEC_reserve_exact (tree, gc, method_vec, 1);
else
reallocated = VEC_reserve (tree, gc, method_vec, 1);
if (reallocated)
CLASSTYPE_METHOD_VEC (type) = method_vec; CLASSTYPE_METHOD_VEC (type) = method_vec;
if (slot == VEC_length (tree, method_vec)) if (slot == VEC_length (tree, method_vec))
VEC_quick_push (tree, method_vec, overload); VEC_quick_push (tree, method_vec, overload);
......
...@@ -40,16 +40,17 @@ struct vec_prefix ...@@ -40,16 +40,17 @@ struct vec_prefix
void *vec[1]; void *vec[1];
}; };
/* Calculate the new ALLOC value, making sure that abs(RESERVE) slots /* Calculate the new ALLOC value, making sure that RESERVE slots are
are free. If RESERVE < 0 grow exactly, otherwise grow free. If EXACT grow exactly, otherwise grow exponentially. */
exponentially. */
static inline unsigned static inline unsigned
calculate_allocation (const struct vec_prefix *pfx, int reserve) calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact)
{ {
unsigned alloc = 0; unsigned alloc = 0;
unsigned num = 0; unsigned num = 0;
gcc_assert (reserve >= 0);
if (pfx) if (pfx)
{ {
alloc = pfx->alloc; alloc = pfx->alloc;
...@@ -61,11 +62,11 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve) ...@@ -61,11 +62,11 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
return 0; return 0;
/* We must have run out of room. */ /* We must have run out of room. */
gcc_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve)); gcc_assert (alloc - num < (unsigned) reserve);
if (reserve < 0) if (exact)
/* Exact size. */ /* Exact size. */
alloc = num + -reserve; alloc = num + reserve;
else else
{ {
/* Exponential growth. */ /* Exponential growth. */
...@@ -85,33 +86,95 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve) ...@@ -85,33 +86,95 @@ calculate_allocation (const struct vec_prefix *pfx, int reserve)
return alloc; return alloc;
} }
/* Ensure there are at least abs(RESERVE) free slots in VEC. If /* Ensure there are at least RESERVE free slots in VEC. If EXACT grow
RESERVE < 0 grow exactly, else grow exponentially. As a special exactly, else grow exponentially. As a special case, if VEC is
case, if VEC is NULL, and RESERVE is 0, no vector will be created. */ NULL and RESERVE is 0, no vector will be created. The vector's
trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
sized elements. */
static void *
vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
bool exact MEM_STAT_DECL)
{
struct vec_prefix *pfx = vec;
unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
if (!alloc)
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;
}
/* Ensure there are at least RESERVE free slots in VEC, growing
exponentially. If RESERVE < 0 grow exactly, else grow
exponentially. As a special case, if VEC is NULL, and RESERVE is
0, no vector will be created. */
void * void *
vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL) vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
{ {
return vec_gc_o_reserve (vec, reserve, return vec_gc_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec), sizeof (void *) offsetof (struct vec_prefix, vec),
sizeof (void *), false
PASS_MEM_STAT);
}
/* Ensure there are at least RESERVE free slots in VEC, growing
exactly. If RESERVE < 0 grow exactly, else grow exponentially. As
a special case, if VEC is NULL, and RESERVE is 0, no vector will be
created. */
void *
vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
{
return vec_gc_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), true
PASS_MEM_STAT); PASS_MEM_STAT);
} }
/* As vec_gc_p_reserve, but for object vectors. The vector's trailing /* As for vec_gc_p_reserve, but for object vectors. The vector's
array is at VEC_OFFSET offset and consists of ELT_SIZE sized trailing array is at VEC_OFFSET offset and consists of ELT_SIZE
elements. */ sized elements. */
void * void *
vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL) MEM_STAT_DECL)
{ {
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
PASS_MEM_STAT);
}
/* As for vec_gc_p_reserve_exact, but for object vectors. The
vector's trailing array is at VEC_OFFSET offset and consists of
ELT_SIZE sized elements. */
void *
vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
size_t elt_size MEM_STAT_DECL)
{
return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
PASS_MEM_STAT);
}
/* As for vec_gc_o_reserve_1, but for heap allocated vectors. */
static void *
vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset,
size_t elt_size, bool exact MEM_STAT_DECL)
{
struct vec_prefix *pfx = vec; struct vec_prefix *pfx = vec;
unsigned alloc = alloc = calculate_allocation (pfx, reserve); unsigned alloc = calculate_allocation (pfx, reserve, exact);
if (!alloc) if (!alloc)
return NULL; return NULL;
vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT); vec = xrealloc (vec, vec_offset + alloc * elt_size);
((struct vec_prefix *)vec)->alloc = alloc; ((struct vec_prefix *)vec)->alloc = alloc;
if (!pfx) if (!pfx)
((struct vec_prefix *)vec)->num = 0; ((struct vec_prefix *)vec)->num = 0;
...@@ -124,8 +187,20 @@ vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size ...@@ -124,8 +187,20 @@ vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
void * void *
vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL) vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
{ {
return vec_heap_o_reserve (vec, reserve, return vec_heap_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec), sizeof (void *) offsetof (struct vec_prefix, vec),
sizeof (void *), false
PASS_MEM_STAT);
}
/* As for vec_gc_p_reserve_exact, but for heap allocated vectors. */
void *
vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve,
offsetof (struct vec_prefix, vec),
sizeof (void *), true
PASS_MEM_STAT); PASS_MEM_STAT);
} }
...@@ -135,18 +210,18 @@ void * ...@@ -135,18 +210,18 @@ void *
vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
MEM_STAT_DECL) MEM_STAT_DECL)
{ {
struct vec_prefix *pfx = vec; return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
unsigned alloc = calculate_allocation (pfx, reserve); PASS_MEM_STAT);
}
if (!alloc)
return NULL;
vec = xrealloc (vec, vec_offset + alloc * elt_size); /* As for vec_gc_o_reserve_exact, but for heap allocated vectors. */
((struct vec_prefix *)vec)->alloc = alloc;
if (!pfx)
((struct vec_prefix *)vec)->num = 0;
return vec; void *
vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
size_t elt_size MEM_STAT_DECL)
{
return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
PASS_MEM_STAT);
} }
#if ENABLE_CHECKING #if ENABLE_CHECKING
......
...@@ -66,8 +66,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -66,8 +66,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
least as many elements as you ask for, it will exponentially least as many elements as you ask for, it will exponentially
increase if there are too few spare slots. If you want reserve a increase if there are too few spare slots. If you want reserve a
specific number of slots, but do not want the exponential increase specific number of slots, but do not want the exponential increase
(for instance, you know this is the last allocation), use a (for instance, you know this is the last allocation), use the
negative number for reservation. You can also create a vector of a reserve_exact operation. You can also create a vector of a
specific size from the get go. specific size from the get go.
You should prefer the push and pop operations, as they append and You should prefer the push and pop operations, as they append and
...@@ -238,16 +238,25 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -238,16 +238,25 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* Reserve space. /* Reserve space.
int VEC_T_A_reserve(VEC(T,A) *&v, int reserve); int VEC_T_A_reserve(VEC(T,A) *&v, int reserve);
Ensure that V has at least abs(RESERVE) slots available. The Ensure that V has at least RESERVE slots available. This will
signedness of RESERVE determines the reallocation behavior. A create additional headroom. Note this can cause V to be
negative value will not create additional headroom beyond that reallocated. Returns nonzero iff reallocation actually
requested. A positive value will create additional headroom. Note occurred. */
this can cause V to be reallocated. Returns nonzero iff
reallocation actually occurred. */
#define VEC_reserve(T,A,V,R) \ #define VEC_reserve(T,A,V,R) \
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO)) (VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Reserve space exactly.
int VEC_T_A_reserve_exact(VEC(T,A) *&v, int reserve);
Ensure that V has at least RESERVE slots available. This will not
create additional headroom. Note this can cause V to be
reallocated. Returns nonzero iff reallocation actually
occurred. */
#define VEC_reserve_exact(T,A,V,R) \
(VEC_OP(T,A,reserve_exact)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Push object with no reallocation /* Push object with no reallocation
T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
...@@ -411,11 +420,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -411,11 +420,17 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#if !IN_GENGTYPE #if !IN_GENGTYPE
/* Reallocate an array of elements with prefix. */ /* Reallocate an array of elements with prefix. */
extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL); extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_gc_o_reserve_exact (void *, int, size_t, size_t
MEM_STAT_DECL);
extern void ggc_free (void *); extern void ggc_free (void *);
#define vec_gc_free(V) ggc_free (V) #define vec_gc_free(V) ggc_free (V)
extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL); extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
extern void *vec_heap_p_reserve_exact (void *, int MEM_STAT_DECL);
extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL); extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
extern void *vec_heap_o_reserve_exact (void *, int, size_t, size_t
MEM_STAT_DECL);
#define vec_heap_free(V) free (V) #define vec_heap_free(V) free (V)
#if ENABLE_CHECKING #if ENABLE_CHECKING
...@@ -702,8 +717,8 @@ static inline unsigned VEC_OP (T,base,lower_bound) \ ...@@ -702,8 +717,8 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \ static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \ (int alloc_ MEM_STAT_DECL) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
return (VEC(T,A) *) vec_##A##_p_reserve (NULL, -alloc_ PASS_MEM_STAT); \ PASS_MEM_STAT); \
} \ } \
\ \
static inline void VEC_OP (T,A,free) \ static inline void VEC_OP (T,A,free) \
...@@ -721,9 +736,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ ...@@ -721,9 +736,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\ \
if (len_) \ if (len_) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve_exact \
new_vec_ = (VEC (T,A) *)(vec_##A##_p_reserve \ (NULL, len_ PASS_MEM_STAT)); \
(NULL, -len_ PASS_MEM_STAT)); \
\ \
new_vec_->base.num = len_; \ new_vec_->base.num = len_; \
memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \ memcpy (new_vec_->base.vec, vec_->vec, sizeof (T) * len_); \
...@@ -734,8 +748,7 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ ...@@ -734,8 +748,7 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
static inline int VEC_OP (T,A,reserve) \ static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \ int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
alloc_ < 0 ? -alloc_ : alloc_ \
VEC_CHECK_PASS); \ VEC_CHECK_PASS); \
\ \
if (extend) \ if (extend) \
...@@ -744,13 +757,27 @@ static inline int VEC_OP (T,A,reserve) \ ...@@ -744,13 +757,27 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \ return extend; \
} \ } \
\ \
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_p_reserve_exact (*vec_, alloc_ \
PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \ static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
VEC_ASSERT (size_ >= 0 \ VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \ "grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \ VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \ VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \ VEC_BASE (*vec_)->num = size_; \
} \ } \
...@@ -972,8 +999,7 @@ static inline unsigned VEC_OP (T,base,lower_bound) \ ...@@ -972,8 +999,7 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \ static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \ (int alloc_ MEM_STAT_DECL) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ return (VEC(T,A) *) vec_##A##_o_reserve_exact (NULL, alloc_, \
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \
offsetof (VEC(T,A),base.vec), \ offsetof (VEC(T,A),base.vec), \
sizeof (T) \ sizeof (T) \
PASS_MEM_STAT); \ PASS_MEM_STAT); \
...@@ -986,9 +1012,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ ...@@ -986,9 +1012,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\ \
if (len_) \ if (len_) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \ (NULL, len_, \
(NULL, -len_, \
offsetof (VEC(T,A),base.vec), sizeof (T) \ offsetof (VEC(T,A),base.vec), sizeof (T) \
PASS_MEM_STAT)); \ PASS_MEM_STAT)); \
\ \
...@@ -1009,8 +1034,7 @@ static inline void VEC_OP (T,A,free) \ ...@@ -1009,8 +1034,7 @@ static inline void VEC_OP (T,A,free) \
static inline int VEC_OP (T,A,reserve) \ static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \ int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
alloc_ < 0 ? -alloc_ : alloc_ \
VEC_CHECK_PASS); \ VEC_CHECK_PASS); \
\ \
if (extend) \ if (extend) \
...@@ -1022,13 +1046,29 @@ static inline int VEC_OP (T,A,reserve) \ ...@@ -1022,13 +1046,29 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \ return extend; \
} \ } \
\ \
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
(*vec_, alloc_, \
offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \ static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
VEC_ASSERT (size_ >= 0 \ VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \ "grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \ VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \ VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \ VEC_BASE (*vec_)->num = size_; \
} \ } \
...@@ -1064,11 +1104,9 @@ static inline T *VEC_OP (T,A,safe_insert) \ ...@@ -1064,11 +1104,9 @@ static inline T *VEC_OP (T,A,safe_insert) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \ static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \ (int alloc_ MEM_STAT_DECL) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ return (VEC(T,A) *) vec_##A##_o_reserve_exact \
return (VEC(T,A) *) vec_##A##_o_reserve (NULL, -alloc_, \ (NULL, alloc_, offsetof (VEC(T,A),base.vec), \
offsetof (VEC(T,A),base.vec), \ sizeof (T) PASS_MEM_STAT); \
sizeof (T) \
PASS_MEM_STAT); \
} \ } \
\ \
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
...@@ -1078,9 +1116,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \ ...@@ -1078,9 +1116,8 @@ static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
\ \
if (len_) \ if (len_) \
{ \ { \
/* We must request exact size allocation, hence the negation. */ \ new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve_exact \
new_vec_ = (VEC (T,A) *)(vec_##A##_o_reserve \ (NULL, len_, \
(NULL, -len_, \
offsetof (VEC(T,A),base.vec), sizeof (T) \ offsetof (VEC(T,A),base.vec), sizeof (T) \
PASS_MEM_STAT)); \ PASS_MEM_STAT)); \
\ \
...@@ -1101,8 +1138,7 @@ static inline void VEC_OP (T,A,free) \ ...@@ -1101,8 +1138,7 @@ static inline void VEC_OP (T,A,free) \
static inline int VEC_OP (T,A,reserve) \ static inline int VEC_OP (T,A,reserve) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), \ int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
alloc_ < 0 ? -alloc_ : alloc_ \
VEC_CHECK_PASS); \ VEC_CHECK_PASS); \
\ \
if (extend) \ if (extend) \
...@@ -1114,13 +1150,28 @@ static inline int VEC_OP (T,A,reserve) \ ...@@ -1114,13 +1150,28 @@ static inline int VEC_OP (T,A,reserve) \
return extend; \ return extend; \
} \ } \
\ \
static inline int VEC_OP (T,A,reserve_exact) \
(VEC(T,A) **vec_, int alloc_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \
int extend = !VEC_OP (T,base,space) (VEC_BASE(*vec_), alloc_ \
VEC_CHECK_PASS); \
\
if (extend) \
*vec_ = (VEC(T,A) *) vec_##A##_o_reserve_exact \
(*vec_, alloc_, offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
\
return extend; \
} \
\
static inline void VEC_OP (T,A,safe_grow) \ static inline void VEC_OP (T,A,safe_grow) \
(VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \ (VEC(T,A) **vec_, int size_ VEC_CHECK_DECL MEM_STAT_DECL) \
{ \ { \
VEC_ASSERT (size_ >= 0 \ VEC_ASSERT (size_ >= 0 \
&& VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \ && VEC_OP(T,base,length) VEC_BASE(*vec_) <= (unsigned)size_, \
"grow", T, A); \ "grow", T, A); \
VEC_OP (T,A,reserve) (vec_, (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) - size_ \ VEC_OP (T,A,reserve_exact) (vec_, \
size_ - (int)(*vec_ ? VEC_BASE(*vec_)->num : 0) \
VEC_CHECK_PASS PASS_MEM_STAT); \ VEC_CHECK_PASS PASS_MEM_STAT); \
VEC_BASE (*vec_)->num = size_; \ VEC_BASE (*vec_)->num = size_; \
} \ } \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment