00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef GENERATOR_FILE
00025 #include "bconfig.h"
00026 #else
00027 #include "config.h"
00028 #endif
00029
00030 #include "system.h"
00031 #include "ggc.h"
00032 #include "vec.h"
00033 #include "coretypes.h"
00034 #include "tree.h"
00035 #include "toplev.h"
00036
00037 struct vec_prefix
00038 {
00039 unsigned num;
00040 unsigned alloc;
00041 void *vec[1];
00042 };
00043
00044
00045
00046
00047 static inline unsigned
00048 calculate_allocation (const struct vec_prefix *pfx, int reserve, bool exact)
00049 {
00050 unsigned alloc = 0;
00051 unsigned num = 0;
00052
00053 gcc_assert (reserve >= 0);
00054
00055 if (pfx)
00056 {
00057 alloc = pfx->alloc;
00058 num = pfx->num;
00059 }
00060 else if (!reserve)
00061
00062
00063 return 0;
00064
00065
00066 gcc_assert (alloc - num < (unsigned) reserve);
00067
00068 if (exact)
00069
00070 alloc = num + reserve;
00071 else
00072 {
00073
00074 if (!alloc)
00075 alloc = 4;
00076 else if (alloc < 16)
00077
00078 alloc = alloc * 2;
00079 else
00080
00081 alloc = (alloc * 3 / 2);
00082
00083
00084 if (alloc < num + reserve)
00085 alloc = num + reserve;
00086 }
00087 return alloc;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 static void *
00097 vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
00098 bool exact MEM_STAT_DECL)
00099 {
00100 struct vec_prefix *pfx = vec;
00101 unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
00102
00103 if (!alloc)
00104 return NULL;
00105
00106 vec = ggc_realloc_stat (vec, vec_offset + alloc * elt_size PASS_MEM_STAT);
00107 ((struct vec_prefix *)vec)->alloc = alloc;
00108 if (!pfx)
00109 ((struct vec_prefix *)vec)->num = 0;
00110
00111 return vec;
00112 }
00113
00114
00115
00116
00117
00118
00119 void *
00120 vec_gc_p_reserve (void *vec, int reserve MEM_STAT_DECL)
00121 {
00122 return vec_gc_o_reserve_1 (vec, reserve,
00123 offsetof (struct vec_prefix, vec),
00124 sizeof (void *), false
00125 PASS_MEM_STAT);
00126 }
00127
00128
00129
00130
00131
00132
00133 void *
00134 vec_gc_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
00135 {
00136 return vec_gc_o_reserve_1 (vec, reserve,
00137 offsetof (struct vec_prefix, vec),
00138 sizeof (void *), true
00139 PASS_MEM_STAT);
00140 }
00141
00142
00143
00144
00145
00146 void *
00147 vec_gc_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
00148 MEM_STAT_DECL)
00149 {
00150 return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
00151 PASS_MEM_STAT);
00152 }
00153
00154
00155
00156
00157
00158 void *
00159 vec_gc_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
00160 size_t elt_size MEM_STAT_DECL)
00161 {
00162 return vec_gc_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
00163 PASS_MEM_STAT);
00164 }
00165
00166
00167
00168 static void *
00169 vec_heap_o_reserve_1 (void *vec, int reserve, size_t vec_offset,
00170 size_t elt_size, bool exact MEM_STAT_DECL)
00171 {
00172 struct vec_prefix *pfx = vec;
00173 unsigned alloc = calculate_allocation (pfx, reserve, exact);
00174
00175 if (!alloc)
00176 return NULL;
00177
00178 vec = xrealloc (vec, vec_offset + alloc * elt_size);
00179 ((struct vec_prefix *)vec)->alloc = alloc;
00180 if (!pfx)
00181 ((struct vec_prefix *)vec)->num = 0;
00182
00183 return vec;
00184 }
00185
00186
00187
00188 void *
00189 vec_heap_p_reserve (void *vec, int reserve MEM_STAT_DECL)
00190 {
00191 return vec_heap_o_reserve_1 (vec, reserve,
00192 offsetof (struct vec_prefix, vec),
00193 sizeof (void *), false
00194 PASS_MEM_STAT);
00195 }
00196
00197
00198
00199 void *
00200 vec_heap_p_reserve_exact (void *vec, int reserve MEM_STAT_DECL)
00201 {
00202 return vec_heap_o_reserve_1 (vec, reserve,
00203 offsetof (struct vec_prefix, vec),
00204 sizeof (void *), true
00205 PASS_MEM_STAT);
00206 }
00207
00208
00209
00210 void *
00211 vec_heap_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size
00212 MEM_STAT_DECL)
00213 {
00214 return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, false
00215 PASS_MEM_STAT);
00216 }
00217
00218
00219
00220 void *
00221 vec_heap_o_reserve_exact (void *vec, int reserve, size_t vec_offset,
00222 size_t elt_size MEM_STAT_DECL)
00223 {
00224 return vec_heap_o_reserve_1 (vec, reserve, vec_offset, elt_size, true
00225 PASS_MEM_STAT);
00226 }
00227
00228 #if ENABLE_CHECKING
00229
00230
00231 void
00232 vec_assert_fail (const char *op, const char *struct_name,
00233 const char *file, unsigned int line, const char *function)
00234 {
00235 internal_error ("vector %s %s domain error, in %s at %s:%u",
00236 struct_name, op, function, trim_filename (file), line);
00237 }
00238 #endif