This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch]: mallocable vectors


Hi,
this patch splits the type-safe vectors into two kinds - gc and malloc
variants. You now have to specify the allocation method when defining
the vector type.  You don't need to remember it when using the vector
(except that freeing becomes mandatory for the mallocable ones :).

Danny, does this suit you?

booted & tested on i686-pc-linux-gnu, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2004-09-06  Nathan Sidwell  <nathan@codesourcery.com>

	* vec.c (vec_p_reserve, vec_o_reserve): Rename to ...
	(vec_gc_p_reserve, vec_gc_o_reserve): ... here. Clone to
	(vec_heap_p_reserve, vec_heap_o_reserve): ... here, adjust.
	(vec_gc_free, vec_heap_free): New.
	* vec.h (DEF_VEC_GC_P, DEF_VEC_MALLOC_P): New.
	(DEF_VEC_P): Add allocator argument. Adjust.
	(DEF_VEC_GC_O, DEF_VEC_MALLOC_O): New.
	(DEF_VEC_O): Add allocator argument. Adjust.
	(VEC(free)): New.

	* tree.h (tree): Define a GC'd vector.
	* lamba-code.c (lambda_loop): Likewise.
	* value-prof.h (histogram_value): Likewise.
	* cp/cp-tree.h (tree_pair_s): Likewise.
	* cp/name-lookup.h (cxx_saved_binding, cp_class_binding): Likewise.
	* cp/semantics.c (deferred_access): Likewise.

Index: lambda-code.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda-code.c,v
retrieving revision 2.2
diff -c -3 -p -r2.2 lambda-code.c
*** lambda-code.c	5 Sep 2004 16:04:59 -0000	2.2
--- lambda-code.c	6 Sep 2004 13:27:02 -0000
*************** find_induction_var_from_exit_cond (struc
*** 1406,1412 ****
    return TREE_OPERAND (test, 0);
  }
  
! DEF_VEC_P(lambda_loop);
  /* Generate a lambda loopnest from a gcc loopnest LOOP_NEST.
     Return the new loop nest.  
     INDUCTIONVARS is a pointer to an array of induction variables for the
--- 1406,1412 ----
    return TREE_OPERAND (test, 0);
  }
  
! DEF_VEC_GC_P(lambda_loop);
  /* Generate a lambda loopnest from a gcc loopnest LOOP_NEST.
     Return the new loop nest.  
     INDUCTIONVARS is a pointer to an array of induction variables for the
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.613
diff -c -3 -p -r1.613 tree.h
*** tree.h	6 Sep 2004 10:08:13 -0000	1.613
--- tree.h	6 Sep 2004 13:27:37 -0000
*************** extern const unsigned char tree_code_len
*** 76,83 ****
  
  extern const char *const tree_code_name[];
  
! /* A vector of trees.  */
! DEF_VEC_P(tree);
  
  
  /* Classify which part of the compiler has defined a given builtin function.
--- 76,83 ----
  
  extern const char *const tree_code_name[];
  
! /* A garbage collected vector of trees.  */
! DEF_VEC_GC_P(tree);
  
  
  /* Classify which part of the compiler has defined a given builtin function.
Index: value-prof.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/value-prof.h,v
retrieving revision 1.7
diff -c -3 -p -r1.7 value-prof.h
*** value-prof.h	1 Sep 2004 20:58:55 -0000	1.7
--- value-prof.h	6 Sep 2004 13:27:38 -0000
*************** struct histogram_value_t GTY(())
*** 66,72 ****
  
  typedef struct histogram_value_t *histogram_value;
  
! DEF_VEC_P(histogram_value);
  
  typedef VEC(histogram_value) *histogram_values;
  
--- 66,72 ----
  
  typedef struct histogram_value_t *histogram_value;
  
! DEF_VEC_GC_P(histogram_value);
  
  typedef VEC(histogram_value) *histogram_values;
  
Index: vec.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/vec.c,v
retrieving revision 2.7
diff -c -3 -p -r2.7 vec.c
*** vec.c	5 Sep 2004 15:24:15 -0000	2.7
--- vec.c	6 Sep 2004 13:27:38 -0000
*************** struct vec_prefix 
*** 39,49 ****
     VEC can be NULL, to create a new vector.  */
  
  void *
! vec_p_reserve (void *vec, int reserve MEM_STAT_DECL)
  {
!   return vec_o_reserve (vec, reserve,
! 			offsetof (struct vec_prefix, vec), sizeof (void *)
! 			PASS_MEM_STAT);
  }
  
  /* Ensure there are at least RESERVE free slots in VEC, if RESERVE >=
--- 39,49 ----
     VEC can be NULL, to create a new vector.  */
  
  void *
! vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
  {
!   return vec_gc_o_reserve (vec, reserve,
! 			   offsetof (struct vec_prefix, vec), sizeof (void *)
! 			   PASS_MEM_STAT);
  }
  
  /* Ensure there are at least RESERVE free slots in VEC, if RESERVE >=
*************** vec_p_reserve (void *vec, int reserve ME
*** 53,60 ****
     ELT_SIZE sized elements.  */
  
  void *
! vec_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
! 	       MEM_STAT_DECL)
  {
    struct vec_prefix *pfx = vec;
    unsigned alloc = pfx ? pfx->num : 0;
--- 53,60 ----
     ELT_SIZE sized elements.  */
  
  void *
! vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
! 		   MEM_STAT_DECL)
  {
    struct vec_prefix *pfx = vec;
    unsigned alloc = pfx ? pfx->num : 0;
*************** vec_o_reserve (void *vec, int reserve, s
*** 77,82 ****
--- 77,141 ----
    return vec;
  }
  
+ /* Explicitly release a vector.  */
+ 
+ void
+ vec_gc_free (void *vec)
+ {
+   ggc_free (vec);
+ }
+ 
+ /* Ensure there are at least RESERVE free slots in VEC, if RESERVE >=
+    0.  If RESERVE < 0 increase the current allocation exponentially.
+    VEC can be NULL, to create a new vector.  */
+ 
+ void *
+ vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
+ {
+   return vec_heap_o_reserve (vec, reserve,
+ 			     offsetof (struct vec_prefix, vec), sizeof (void *)
+ 			     PASS_MEM_STAT);
+ }
+ 
+ /* Ensure there are at least RESERVE free slots in VEC, if RESERVE >=
+    0.  If RESERVE < 0, increase the current allocation exponentially.
+    VEC can be NULL, in which case a new vector is created.  The
+    vector's trailing array is at VEC_OFFSET offset and consists of
+    ELT_SIZE sized elements.  */
+ 
+ void *
+ vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
+ 		    MEM_STAT_DECL)
+ {
+   struct vec_prefix *pfx = vec;
+   unsigned alloc = pfx ? pfx->num : 0;
+ 
+   if (reserve >= 0)
+     alloc += reserve;
+   else if (alloc)
+     alloc *= 2;
+   else
+     alloc = 4;
+ 
+   if (pfx && pfx->alloc >= alloc)
+     abort ();
+   
+   vec = xrealloc (vec, vec_offset + alloc * elt_size);
+   ((struct vec_prefix *)vec)->alloc = alloc;
+   if (!pfx)
+     ((struct vec_prefix *)vec)->num = 0;
+   
+   return vec;
+ }
+ 
+ /* Explicitly release a vector.  */
+ 
+ void
+ vec_heap_free (void *vec)
+ {
+   free (vec);
+ }
+ 
  #if ENABLE_CHECKING
  /* Issue a vector domain error, and then fall over.  */
  
Index: vec.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/vec.h,v
retrieving revision 2.18
diff -c -3 -p -r2.18 vec.h
*** vec.h	5 Sep 2004 16:05:06 -0000	2.18
--- vec.h	7 Sep 2004 10:24:48 -0000
*************** Software Foundation, 59 Temple Place - S
*** 78,96 ****
     The 'lower_bound' function will determine where to place an item in the
     array using insert that will maintain sorted order.
  
     If you need to directly manipulate a vector, then the 'address'
     accessor will return the address of the start of the vector.  Also
     the 'space' predicate will tell you whether there is spare capacity
     in the vector.  You will not normally need to use these two functions.
     
!    Vector types are defined using a DEF_VEC_{O,P}(TYPEDEF) macro, and
!    variables of vector type are declared using a VEC(TYPEDEF)
!    macro. The characters O and P indicate whether TYPEDEF is a pointer
!    (P) or object (O) type.
  
     An example of their use would be,
  
!    DEF_VEC_P(tree);	// define a vector of tree pointers.  This must
     			// appear at file scope.
  
     struct my_struct {
--- 78,102 ----
     The 'lower_bound' function will determine where to place an item in the
     array using insert that will maintain sorted order.
  
+    Both garbage collected and explicitly managed vector types are
+    creatable.  The allocation mechanism is specified when the type is
+    defined, and is therefore part of the type.
+    
     If you need to directly manipulate a vector, then the 'address'
     accessor will return the address of the start of the vector.  Also
     the 'space' predicate will tell you whether there is spare capacity
     in the vector.  You will not normally need to use these two functions.
     
!    Vector types are defined using a DEF_VEC_{GC,MALLOC}_{O,P}(TYPEDEF)
!    macro, and variables of vector type are declared using a
!    VEC(TYPEDEF) macro.  The tags GC and MALLOC specify the allocation
!    method -- garbage collected or explicit malloc/free calls.  The
!    characters O and P indicate whether TYPEDEF is a pointer (P) or
!    object (O) type.
  
     An example of their use would be,
  
!    DEF_VEC_GC_P(tree);	// define a gc'd vector of tree pointers.  This must
     			// appear at file scope.
  
     struct my_struct {
*************** Software Foundation, 59 Temple Place - S
*** 158,163 ****
--- 164,176 ----
  
  #define VEC_alloc(TDEF,A)	(VEC_OP(TDEF,alloc)(A MEM_STAT_INFO))
  
+ /* Free a vector.
+    void VEC_T_alloc(VEC(T) *&);
+ 
+    Free a vector and set it to NULL.  */
+ 
+ #define VEC_free(TDEF,V)	(VEC_OP(TDEF,free)(&V))
+ 
  /* Use these to determine the required size and initialization of a
     vector embedded within another structure (as the final member).
     
*************** Software Foundation, 59 Temple Place - S
*** 317,324 ****
  
  #if !IN_GENGTYPE
  /* Reallocate an array of elements with prefix.  */
! extern void *vec_p_reserve (void *, int MEM_STAT_DECL);
! extern void *vec_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
  
  #if ENABLE_CHECKING
  #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
--- 330,341 ----
  
  #if !IN_GENGTYPE
  /* Reallocate an array of elements with prefix.  */
! extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
! extern void *vec_gc_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
! extern void vec_gc_free (void *);
! extern void *vec_heap_p_reserve (void *, int MEM_STAT_DECL);
! extern void *vec_heap_o_reserve (void *, int, size_t, size_t MEM_STAT_DECL);
! extern void vec_heap_free (void *);
  
  #if ENABLE_CHECKING
  #define VEC_CHECK_INFO ,__FILE__,__LINE__,__FUNCTION__
*************** typedef struct VEC (TDEF) GTY(())					  
*** 359,368 ****
  
  /* Vector of pointer to object.  */
  #if IN_GENGTYPE
! {"DEF_VEC_P", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
  #else
    
! #define DEF_VEC_P(TDEF)							  \
  VEC_TDEF (TDEF);							  \
  									  \
  static inline unsigned VEC_OP (TDEF,length)				  \
--- 376,388 ----
  
  /* Vector of pointer to object.  */
  #if IN_GENGTYPE
! {"DEF_VEC_GC_P", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
! {"DEF_VEC_MALLOC_P", "", NULL},
  #else
+ #define DEF_VEC_GC_P(TDEF) DEF_VEC_P(TDEF,gc)
+ #define DEF_VEC_MALLOC_P(TDEF) DEF_VEC_P(TDEF,heap)
    
! #define DEF_VEC_P(TDEF,a)						  \
  VEC_TDEF (TDEF);							  \
  									  \
  static inline unsigned VEC_OP (TDEF,length)				  \
*************** static inline int VEC_OP (TDEF,iterate)	
*** 405,411 ****
  static inline VEC (TDEF) *VEC_OP (TDEF,alloc)				  \
       (int alloc_ MEM_STAT_DECL)						  \
  {									  \
!   return (VEC (TDEF) *) vec_p_reserve (NULL, alloc_ - !alloc_ PASS_MEM_STAT);\
  }									  \
  									  \
  static inline size_t VEC_OP (TDEF,embedded_size)			  \
--- 425,438 ----
  static inline VEC (TDEF) *VEC_OP (TDEF,alloc)				  \
       (int alloc_ MEM_STAT_DECL)						  \
  {									  \
!   return (VEC (TDEF) *) vec_##a##_p_reserve (NULL, alloc_ - !alloc_ PASS_MEM_STAT);\
! }									  \
! 									  \
! static inline void VEC_OP (TDEF,free)					  \
!      (VEC (TDEF) **vec_)						  \
! {									  \
!   vec_##a##_free (*vec_);						  \
!   *vec_ = NULL;								  \
  }									  \
  									  \
  static inline size_t VEC_OP (TDEF,embedded_size)			  \
*************** static inline int VEC_OP (TDEF,reserve)	
*** 434,440 ****
    int extend = VEC_OP (TDEF,space) (*vec_, alloc_);			  \
  		  							  \
    if (extend)	  							  \
!     *vec_ = (VEC (TDEF) *) vec_p_reserve (*vec_, alloc_ PASS_MEM_STAT);   \
  		  							  \
    return extend;							  \
  }									  \
--- 461,467 ----
    int extend = VEC_OP (TDEF,space) (*vec_, alloc_);			  \
  		  							  \
    if (extend)	  							  \
!     *vec_ = (VEC (TDEF) *) vec_##a##_p_reserve (*vec_, alloc_ PASS_MEM_STAT);   \
  		  							  \
    return extend;							  \
  }									  \
*************** struct vec_swallow_trailing_semi
*** 577,586 ****
  
  /* Vector of object.  */
  #if IN_GENGTYPE
! {"DEF_VEC_O", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
  #else
    
! #define DEF_VEC_O(TDEF)							  \
  VEC_TDEF (TDEF);							  \
  									  \
  static inline unsigned VEC_OP (TDEF,length)				  \
--- 604,617 ----
  
  /* Vector of object.  */
  #if IN_GENGTYPE
! {"DEF_VEC_GC_O", VEC_STRINGIFY (VEC_TDEF (#)) ";", NULL},
! {"DEF_VEC_MALLOC_O", "", NULL},
  #else
    
! #define DEF_VEC_GC_O(TDEF) DEF_VEC_O(TDEF,gc)
! #define DEF_VEC_MALLOC_O(TDEF) DEF_VEC_O(TDEF,heap)
! 
! #define DEF_VEC_O(TDEF,a)						  \
  VEC_TDEF (TDEF);							  \
  									  \
  static inline unsigned VEC_OP (TDEF,length)				  \
*************** static inline int VEC_OP (TDEF,iterate)	
*** 623,633 ****
  static inline VEC (TDEF) *VEC_OP (TDEF,alloc)      			  \
       (int alloc_ MEM_STAT_DECL)						  \
  {									  \
!   return (VEC (TDEF) *) vec_o_reserve (NULL, alloc_ - !alloc_,		  \
                                         offsetof (VEC(TDEF),vec), sizeof (TDEF)\
                                         PASS_MEM_STAT);			  \
  }									  \
  									  \
  static inline size_t VEC_OP (TDEF,embedded_size)			  \
       (int alloc_)							  \
  {									  \
--- 654,671 ----
  static inline VEC (TDEF) *VEC_OP (TDEF,alloc)      			  \
       (int alloc_ MEM_STAT_DECL)						  \
  {									  \
!   return (VEC (TDEF) *) vec_##a##_o_reserve (NULL, alloc_ - !alloc_,	  \
                                         offsetof (VEC(TDEF),vec), sizeof (TDEF)\
                                         PASS_MEM_STAT);			  \
  }									  \
  									  \
+ static inline void VEC_OP (TDEF,free)					  \
+      (VEC (TDEF) **vec_)						  \
+ {									  \
+   vec_##a##_free (*vec_);						  \
+   *vec_ = NULL;								  \
+ }									  \
+ 									  \
  static inline size_t VEC_OP (TDEF,embedded_size)			  \
       (int alloc_)							  \
  {									  \
*************** static inline int VEC_OP (TDEF,reserve)	
*** 654,660 ****
    int extend = VEC_OP (TDEF,space) (*vec_, alloc_);			  \
  									  \
    if (extend)								  \
!     *vec_ = (VEC (TDEF) *) vec_o_reserve (*vec_, alloc_,		  \
  			   offsetof (VEC(TDEF),vec), sizeof (TDEF)	  \
  			   PASS_MEM_STAT);				  \
  									  \
--- 692,698 ----
    int extend = VEC_OP (TDEF,space) (*vec_, alloc_);			  \
  									  \
    if (extend)								  \
!     *vec_ = (VEC (TDEF) *) vec_##a##_o_reserve (*vec_, alloc_,		  \
  			   offsetof (VEC(TDEF),vec), sizeof (TDEF)	  \
  			   PASS_MEM_STAT);				  \
  									  \
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1042
diff -c -3 -p -r1.1042 cp-tree.h
*** cp/cp-tree.h	1 Sep 2004 03:45:27 -0000	1.1042
--- cp/cp-tree.h	6 Sep 2004 13:28:00 -0000
*************** typedef struct tree_pair_s GTY (())
*** 955,961 ****
    tree value;
  } tree_pair_s;
  typedef tree_pair_s *tree_pair_p;
! DEF_VEC_O (tree_pair_s);
  
  /* This is a few header flags for 'struct lang_type'.  Actually,
     all but the first are used only for lang_type_class; they
--- 955,961 ----
    tree value;
  } tree_pair_s;
  typedef tree_pair_s *tree_pair_p;
! DEF_VEC_GC_O (tree_pair_s);
  
  /* This is a few header flags for 'struct lang_type'.  Actually,
     all but the first are used only for lang_type_class; they
Index: cp/name-lookup.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.h,v
retrieving revision 1.27
diff -c -3 -p -r1.27 name-lookup.h
*** cp/name-lookup.h	14 Jul 2004 15:34:30 -0000	1.27
--- cp/name-lookup.h	6 Sep 2004 13:28:01 -0000
*************** typedef struct cxx_saved_binding GTY(())
*** 91,97 ****
    tree real_type_value;
  } cxx_saved_binding;
  
! DEF_VEC_O(cxx_saved_binding);
  
  extern tree identifier_type_value (tree);
  extern void set_identifier_type_value (tree, tree);
--- 91,97 ----
    tree real_type_value;
  } cxx_saved_binding;
  
! DEF_VEC_GC_O(cxx_saved_binding);
  
  extern tree identifier_type_value (tree);
  extern void set_identifier_type_value (tree, tree);
*************** typedef struct cp_class_binding GTY(())
*** 132,138 ****
    tree identifier;
  } cp_class_binding;
  
! DEF_VEC_O(cp_class_binding);
  
  /* For each binding contour we allocate a binding_level structure
     which records the names defined in that contour.
--- 132,138 ----
    tree identifier;
  } cp_class_binding;
  
! DEF_VEC_GC_O(cp_class_binding);
  
  /* For each binding contour we allocate a binding_level structure
     which records the names defined in that contour.
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.428
diff -c -3 -p -r1.428 semantics.c
*** cp/semantics.c	30 Aug 2004 16:03:47 -0000	1.428
--- cp/semantics.c	6 Sep 2004 13:28:08 -0000
*************** typedef struct deferred_access GTY(())
*** 138,144 ****
    enum deferring_kind deferring_access_checks_kind;
    
  } deferred_access;
! DEF_VEC_O (deferred_access);
  
  /* Data for deferred access checking.  */
  static GTY(()) VEC (deferred_access) *deferred_access_stack;
--- 138,144 ----
    enum deferring_kind deferring_access_checks_kind;
    
  } deferred_access;
! DEF_VEC_GC_O (deferred_access);
  
  /* Data for deferred access checking.  */
  static GTY(()) VEC (deferred_access) *deferred_access_stack;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]