/* Vector API for GNU compiler.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Nathan Sidwell <nathan@codesourcery.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#ifndef GCC_VEC_H
#define GCC_VEC_H
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);
+extern void dump_vec_loc_statistics (void);
+#ifdef GATHER_STATISTICS
+void vec_heap_free (void *);
+#else
#define vec_heap_free(V) free (V)
+#endif
#if ENABLE_CHECKING
#define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
} VEC(T,B)
#define VEC_T_GTY(T,B) \
-typedef struct VEC(T,B) GTY(()) \
+typedef struct GTY(()) VEC(T,B) \
{ \
unsigned num; \
unsigned alloc; \
/* Derived vector type, user visible. */
#define VEC_TA_GTY(T,B,A,GTY) \
-typedef struct VEC(T,A) GTY \
+typedef struct GTY VEC(T,A) \
+{ \
+ VEC(T,B) base; \
+} VEC(T,A)
+
+#define VEC_TA(T,B,A) \
+typedef struct VEC(T,A) \
{ \
VEC(T,B) base; \
} VEC(T,A)
} \
\
VEC_T(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_P(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_I(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_I(T,A) \
+DEF_VEC_NONALLOC_FUNCS_I(T,A) \
struct vec_swallow_trailing_semi
/* Vector of pointer to object. */
} \
\
VEC_T_GTY(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_P(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_P(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_P(T,A) \
+DEF_VEC_NONALLOC_FUNCS_P(T,A) \
struct vec_swallow_trailing_semi
#define DEF_VEC_FUNC_P(T) \
} \
else \
{ \
- *ptr = 0; \
+ *ptr = (T) 0; \
return 0; \
} \
} \
{ \
return (VEC(T,A) *) vec_##A##_p_reserve_exact (NULL, alloc_ \
PASS_MEM_STAT); \
-} \
- \
+}
+
+
+#define DEF_VEC_NONALLOC_FUNCS_P(T,A) \
static inline void VEC_OP (T,A,free) \
(VEC(T,A) **vec_) \
{ \
/* Vector of object. */
#define DEF_VEC_O(T) \
VEC_T_GTY(T,base); \
-VEC_TA_GTY(T,base,none,); \
+VEC_TA(T,base,none); \
DEF_VEC_FUNC_O(T) \
struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_O(T,A) \
-VEC_TA_GTY(T,base,A,); \
+VEC_TA(T,base,A); \
DEF_VEC_ALLOC_FUNC_O(T,A) \
+DEF_VEC_NONALLOC_FUNCS_O(T,A) \
struct vec_swallow_trailing_semi
#define DEF_VEC_FUNC_O(T) \
offsetof (VEC(T,A),base.vec), \
sizeof (T) \
PASS_MEM_STAT); \
-} \
- \
+}
+
+#define DEF_VEC_NONALLOC_FUNCS_O(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
{ \
size_t len_ = vec_ ? vec_->num : 0; \
return (VEC(T,A) *) vec_##A##_o_reserve_exact \
(NULL, alloc_, offsetof (VEC(T,A),base.vec), \
sizeof (T) PASS_MEM_STAT); \
-} \
- \
+}
+
+#define DEF_VEC_NONALLOC_FUNCS_I(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,copy) (VEC(T,base) *vec_ MEM_STAT_DECL) \
{ \
size_t len_ = vec_ ? vec_->num : 0; \
VEC_CHECK_PASS); \
}
+/* We support a vector which starts out with space on the stack and
+ switches to heap space when forced to reallocate. This works a
+ little differently. Instead of DEF_VEC_ALLOC_P(TYPE, heap|gc), use
+ DEF_VEC_ALLOC_P_STACK(TYPE). This uses alloca to get the initial
+ space; because alloca can not be usefully called in an inline
+ function, and because a macro can not define a macro, you must then
+ write a #define for each type:
+
+ #define VEC_{TYPE}_stack_alloc(alloc) \
+ VEC_stack_alloc({TYPE}, alloc)
+
+ This is really a hack and perhaps can be made better. Note that
+ this macro will wind up evaluating the ALLOC parameter twice.
+
+ Only the initial allocation will be made using alloca, so pass a
+ reasonable estimate that doesn't use too much stack space; don't
+ pass zero. Don't return a VEC(TYPE,stack) vector from the function
+ which allocated it. */
+
+extern void *vec_stack_p_reserve (void *, int MEM_STAT_DECL);
+extern void *vec_stack_p_reserve_exact (void *, int MEM_STAT_DECL);
+extern void *vec_stack_p_reserve_exact_1 (int, void *);
+extern void *vec_stack_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
+extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
+ MEM_STAT_DECL);
+extern void vec_stack_free (void *);
+
+#ifdef GATHER_STATISTICS
+#define VEC_stack_alloc(T,alloc,name,line,function) \
+ (VEC_OP (T,stack,alloc1) \
+ (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
+#else
+#define VEC_stack_alloc(T,alloc) \
+ (VEC_OP (T,stack,alloc1) \
+ (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
+#endif
+
+#define DEF_VEC_ALLOC_P_STACK(T) \
+VEC_TA(T,base,stack); \
+DEF_VEC_ALLOC_FUNC_P_STACK(T) \
+DEF_VEC_NONALLOC_FUNCS_P(T,stack) \
+struct vec_swallow_trailing_semi
+
+#define DEF_VEC_ALLOC_FUNC_P_STACK(T) \
+static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
+ (int alloc_, VEC(T,stack)* space) \
+{ \
+ return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+}
+
+#define DEF_VEC_ALLOC_O_STACK(T) \
+VEC_TA(T,base,stack); \
+DEF_VEC_ALLOC_FUNC_O_STACK(T) \
+DEF_VEC_NONALLOC_FUNCS_O(T,stack) \
+struct vec_swallow_trailing_semi
+
+#define DEF_VEC_ALLOC_FUNC_O_STACK(T) \
+static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
+ (int alloc_, VEC(T,stack)* space) \
+{ \
+ return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+}
+
+#define DEF_VEC_ALLOC_I_STACK(T) \
+VEC_TA(T,base,stack); \
+DEF_VEC_ALLOC_FUNC_I_STACK(T) \
+DEF_VEC_NONALLOC_FUNCS_I(T,stack) \
+struct vec_swallow_trailing_semi
+
+#define DEF_VEC_ALLOC_FUNC_I_STACK(T) \
+static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
+ (int alloc_, VEC(T,stack)* space) \
+{ \
+ return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+}
+
#endif /* GCC_VEC_H */