1 /********************************************************************/ 2 /* */ 3 /* heaputl.h Procedures for heap allocation and maintenance. */ 4 /* Copyright (C) 1989 - 2019 Thomas Mertes */ 5 /* */ 6 /* This file is part of the Seed7 Runtime Library. */ 7 /* */ 8 /* The Seed7 Runtime Library is free software; you can */ 9 /* redistribute it and/or modify it under the terms of the GNU */ 10 /* Lesser General Public License as published by the Free Software */ 11 /* Foundation; either version 2.1 of the License, or (at your */ 12 /* option) any later version. */ 13 /* */ 14 /* The Seed7 Runtime Library is distributed in the hope that it */ 15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */ 16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */ 17 /* PURPOSE. See the GNU Lesser General Public License for more */ 18 /* details. */ 19 /* */ 20 /* You should have received a copy of the GNU Lesser General */ 21 /* Public License along with this program; if not, write to the */ 22 /* Free Software Foundation, Inc., 51 Franklin Street, */ 23 /* Fifth Floor, Boston, MA 02110-1301, USA. */ 24 /* */ 25 /* Module: Seed7 Runtime Library */ 26 /* File: seed7/src/heaputl.h */ 27 /* Changes: 1992 - 1994, 2008, 2010, 2011 Thomas Mertes */ 28 /* Content: Procedures for heap allocation and maintenance. */ 29 /* */ 30 /********************************************************************/ 31 32 33 #if DO_HEAP_STATISTIC 34 typedef struct { 35 unsigned long stri; 36 memSizeType stri_elems; 37 unsigned long bstri; 38 memSizeType bstri_elems; 39 unsigned long array; 40 memSizeType arr_elems; 41 memSizeType rtl_arr_elems; 42 unsigned long hash; 43 memSizeType hsh_elems; 44 unsigned long helem; 45 unsigned long rtl_helem; 46 unsigned long set; 47 memSizeType set_elems; 48 unsigned long stru; 49 memSizeType sct_elems; 50 unsigned long big; 51 memSizeType big_elems; 52 unsigned long ident; 53 unsigned long idt; 54 memSizeType idt_bytes; 55 unsigned long entity; 56 unsigned long property; 57 unsigned long object; 58 unsigned long node; 59 unsigned long token; 60 unsigned long owner; 61 unsigned long stack; 62 unsigned long typelist_elems; 63 unsigned long type; 64 unsigned long list_elem; 65 unsigned long block; 66 unsigned long loclist; 67 unsigned long infil; 68 unsigned long prog; 69 unsigned long polldata; 70 unsigned long prepared_stmt; 71 memSizeType prepared_stmt_bytes; 72 unsigned long fetch_data; 73 memSizeType fetch_data_bytes; 74 unsigned long sql_func; 75 unsigned long files; 76 unsigned long win; 77 memSizeType win_bytes; 78 unsigned long database; 79 memSizeType database_bytes; 80 unsigned long process; 81 unsigned long fnam; 82 memSizeType fnam_bytes; 83 unsigned long symb; 84 memSizeType symb_bytes; 85 memSizeType byte; 86 } countType; 87 88 #ifdef DO_INIT 89 countType count = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94 0}; 95 #else 96 EXTERN countType count; 97 #endif 98 99 #if BIGINT_LIB == BIG_RTL_LIBRARY 100 extern const size_t sizeof_bigDigitType; 101 extern const size_t sizeof_bigIntRecord; 102 #endif 103 extern size_t sizeof_pollRecord; 104 extern size_t sizeof_processRecord; 105 106 #endif 107 108 109 /* Some stupid operating systems have under some compilers */ 110 /* limitations on how much memory can be requested with malloc. */ 111 /* This is the case if the malloc function has an 16 bit */ 112 /* unsigned argument. If this is the case the only solution */ 113 /* is to check if the SIZE is under 2**16 - 1 . Here we use */ 114 /* a little bit lower value to be on the save side. Note */ 115 /* that if such an operating system has another function to */ 116 /* request more bytes it can be substituted here. */ 117 118 #if USE_MAXIMUM_MALLOC_CHECK 119 #define MALLOC(size) ((size) <= 65500 ? malloc((size_t) (size)) : NULL) 120 #define REALLOC(ptr, size) ((size) <= 65500 ? realloc(ptr, (size_t) (size)) : NULL) 121 #else 122 #ifdef OUT_OF_ORDER 123 #ifndef DO_INIT 124 EXTERN int successful_mallocs; 125 #endif 126 #define MALLOC(size) (printf("%s(%d) %d\n", __FILE__, __LINE__, successful_mallocs), (successful_mallocs-- != 0 ? malloc((size_t) (size)) : NULL)) 127 #endif 128 #define MALLOC(size) malloc((size_t) (size)) 129 #define REALLOC(ptr, size) realloc(ptr, (size_t) (size)) 130 #endif 131 132 133 #if USE_CHUNK_ALLOCS 134 typedef struct { 135 char *freemem; 136 char *start; 137 char *beyond; 138 memSizeType size; 139 memSizeType total_size; 140 memSizeType lost_bytes; 141 unsigned int number_of_chunks; 142 } chunkType; 143 144 #ifdef DO_INIT 145 chunkType chunk = {NULL, NULL, NULL, 0, 0, 0, 0}; 146 #else 147 EXTERN chunkType chunk; 148 #endif 149 #endif 150 151 152 #if DO_HEAPSIZE_COMPUTATION 153 #ifdef DO_INIT 154 memSizeType hs = 0; 155 #else 156 EXTERN memSizeType hs; 157 #endif 158 #define HS_ADD(size) hs += (memSizeType) (size) 159 #define HS_SUB(size) hs -= (memSizeType) (size) 160 #else 161 #define HS_ADD(size) 162 #define HS_SUB(size) 163 #endif 164 165 166 #if DO_HEAP_STATISTIC 167 #define USTRI_ADD(len,cnt,byt) cnt++, byt += (memSizeType) (len) 168 #define USTRI_SUB(len,cnt,byt) cnt--, byt -= (memSizeType) (len) 169 #define STRI_ADD(len) count.stri++, count.stri_elems += (memSizeType) (len) 170 #define STRI_SUB(len) count.stri--, count.stri_elems -= (memSizeType) (len) 171 #define BSTRI_ADD(len) count.bstri++, count.bstri_elems += (memSizeType) (len) 172 #define BSTRI_SUB(len) count.bstri--, count.bstri_elems -= (memSizeType) (len) 173 #define ARR_ADD(len) count.array++, count.arr_elems += (memSizeType) (len) 174 #define ARR_SUB(len) count.array--, count.arr_elems -= (memSizeType) (len) 175 #define HSH_ADD(len) count.hash++, count.hsh_elems += (memSizeType) (len) 176 #define HSH_SUB(len) count.hash--, count.hsh_elems -= (memSizeType) (len) 177 #define SET_ADD(len) count.set++, count.set_elems += (memSizeType) (len) 178 #define SET_SUB(len) count.set--, count.set_elems -= (memSizeType) (len) 179 #define SCT_ADD(len) count.stru++, count.sct_elems += (memSizeType) (len) 180 #define SCT_SUB(len) count.stru--, count.sct_elems -= (memSizeType) (len) 181 #define BIG_ADD(len) count.big++, count.big_elems += (memSizeType) (len) 182 #define BIG_SUB(len) count.big--, count.big_elems -= (memSizeType) (len) 183 #define REC_ADD(cnt) cnt++ 184 #define REC_SUB(cnt) cnt-- 185 #define REC2_ADD(size,cnt,byt) cnt++, byt += (memSizeType) (size) 186 #define REC2_SUB(size,cnt,byt) cnt--, byt -= (memSizeType) (size) 187 #define BYT_ADD(size) count.byte += (memSizeType) (size) 188 #define BYT_SUB(size) count.byte -= (memSizeType) (size) 189 #define RTL_L_ELEM_ADD 190 #define RTL_L_ELEM_SUB 191 #define RTL_ARR_ADD(len) count.array++, count.rtl_arr_elems += (memSizeType) (len) 192 #define RTL_ARR_SUB(len) count.array--, count.rtl_arr_elems -= (memSizeType) (len) 193 #define RTL_HSH_ADD(len) count.hash++, count.hsh_elems += (memSizeType) (len) 194 #define RTL_HSH_SUB(len) count.hash--, count.hsh_elems -= (memSizeType) (len) 195 #else 196 #define USTRI_ADD(len,cnt,byt) 197 #define USTRI_SUB(len,cnt,byt) 198 #define STRI_ADD(len) 199 #define STRI_SUB(len) 200 #define BSTRI_ADD(len) 201 #define BSTRI_SUB(len) 202 #define ARR_ADD(len) 203 #define ARR_SUB(len) 204 #define HSH_ADD(len) 205 #define HSH_SUB(len) 206 #define SET_ADD(len) 207 #define SET_SUB(len) 208 #define SCT_ADD(len) 209 #define SCT_SUB(len) 210 #define BIG_ADD(len) 211 #define BIG_SUB(len) 212 #define REC_ADD(cnt) 213 #define REC_SUB(cnt) 214 #define REC2_ADD(size,cnt,byt) 215 #define REC2_SUB(size,cnt,byt) 216 #define BYT_ADD(size) 217 #define BYT_SUB(size) 218 #define RTL_L_ELEM_ADD 219 #define RTL_L_ELEM_SUB 220 #define RTL_ARR_ADD(len) 221 #define RTL_ARR_SUB(len) 222 #define RTL_HSH_ADD(len) 223 #define RTL_HSH_SUB(len) 224 #endif 225 226 227 #if DO_HEAP_CHECK 228 #define H_CHECK1(len) , check_heap( (long) (len), __FILE__, __LINE__) 229 #define H_CHECK2(len) , check_heap(- (long) (len), __FILE__, __LINE__) 230 #else 231 #define H_CHECK1(len) 232 #define H_CHECK2(len) 233 #endif 234 235 236 #if DO_HEAP_LOG 237 #define H_LOG1(len) , printf("\nmalloc(%ld)\n", (long) (len)) H_CHECK1(len) 238 #define H_LOG2(len) , printf("\nmfree(%ld)\n", (long) (len)) H_CHECK2(len) 239 #else 240 #define H_LOG1(len) H_CHECK1(len) 241 #define H_LOG2(len) H_CHECK2(len) 242 #endif 243 244 245 #define SIZ_USTRI(len) ((len) + NULL_TERMINATION_LEN) 246 #define SIZ_CSTRI(len) ((len) + NULL_TERMINATION_LEN) 247 #define SIZ_WSTRI(len) (sizeof(wcharType) * ((len) + NULL_TERMINATION_LEN)) 248 #define SIZ_STRI(len) ((sizeof(striRecord) - sizeof(strElemType)) + (len) * sizeof(strElemType)) 249 #define SIZ_BSTRI(len) ((sizeof(bstriRecord) - sizeof(ucharType)) + (len) * sizeof(ucharType)) 250 #define SIZ_ARR(len) ((sizeof(arrayRecord) - sizeof(objectRecord)) + (len) * sizeof(objectRecord)) 251 #define SIZ_HSH(len) ((sizeof(hashRecord) - sizeof(hashElemType)) + (len) * sizeof(hashElemType)) 252 #define SIZ_SET(len) ((sizeof(setRecord) - sizeof(bitSetType)) + (len) * sizeof(bitSetType)) 253 #define SIZ_SCT(len) ((sizeof(structRecord) - sizeof(objectRecord)) + (len) * sizeof(objectRecord)) 254 #define SIZ_BIG(len) ((sizeof_bigIntRecord - sizeof_bigDigitType) + (len) * sizeof_bigDigitType) 255 #define SIZ_REC(rec) (sizeof(rec)) 256 #define SIZ_TAB(tp, nr) (sizeof(tp) * (nr)) 257 #define SIZ_RTL_L_ELEM (sizeof(rtlListRecord)) 258 #define SIZ_RTL_ARR(len) ((sizeof(rtlArrayRecord) - sizeof(rtlObjectType)) + (len) * sizeof(rtlObjectType)) 259 #define SIZ_RTL_HSH(len) ((sizeof(rtlHashRecord) - sizeof(rtlHashElemType)) + (len) * sizeof(rtlHashElemType)) 260 261 #define MAX_USTRI_LEN (MAX_MEMSIZETYPE - NULL_TERMINATION_LEN) 262 #define MAX_CSTRI_LEN (MAX_MEMSIZETYPE - NULL_TERMINATION_LEN) 263 #define MAX_WSTRI_LEN (MAX_MEMSIZETYPE / sizeof(wcharType) - NULL_TERMINATION_LEN) 264 #define MAX_STRI_LEN ((MAX_MEMSIZETYPE - sizeof(striRecord) + sizeof(strElemType)) / sizeof(strElemType)) 265 #define MAX_BSTRI_LEN ((MAX_MEMSIZETYPE - sizeof(bstriRecord) + sizeof(ucharType)) / sizeof(ucharType)) 266 #define MAX_SET_LEN ((MAX_MEMSIZETYPE - sizeof(setRecord) + sizeof(bitSetType)) / sizeof(bitSetType)) 267 #define MAX_ARR_LEN ((MAX_MEMSIZETYPE - sizeof(arrayRecord) + sizeof(objectRecord)) / sizeof(objectRecord)) 268 #define MAX_RTL_ARR_LEN ((MAX_MEMSIZETYPE - sizeof(rtlArrayRecord) + sizeof(rtlObjectType)) / sizeof(rtlObjectType)) 269 270 #define MAX_ARR_INDEX ((MAX_MEM_INDEX - sizeof(arrayRecord) + sizeof(objectRecord)) / sizeof(objectRecord)) 271 #define MAX_RTL_ARR_INDEX ((MAX_MEM_INDEX - sizeof(rtlArrayRecord) + sizeof(rtlObjectType)) / sizeof(rtlObjectType)) 272 273 #if DO_HEAPSIZE_COMPUTATION 274 #if DO_HEAP_STATISTIC 275 #define CALC_HS(cnt_hs, cnt) (cnt_hs, cnt) 276 #else 277 #define CALC_HS(cnt_hs, cnt) (cnt_hs) 278 #endif 279 #define CNT(cnt) cnt, 280 #define CNT3(cnt2, cnt1) (cnt2, cnt1) 281 #else 282 #define CALC_HS(cnt_hs, cnt) 283 #define CNT(cnt) 284 #define CNT3(cnt2, cnt1) 285 #endif 286 287 #define CNT1_USTRI(L,S,C,B) CALC_HS(HS_ADD(S), USTRI_ADD(L,C,B) H_LOG1(S)) 288 #define CNT2_USTRI(L,S,C,B) CALC_HS(HS_SUB(S), USTRI_SUB(L,C,B) H_LOG2(S)) 289 #define CNT1_STRI(len,size) CALC_HS(HS_ADD(size), STRI_ADD(len) H_LOG1(size)) 290 #define CNT2_STRI(len,size) CALC_HS(HS_SUB(size), STRI_SUB(len) H_LOG2(size)) 291 #define CNT1_BSTRI(len,size) CALC_HS(HS_ADD(size), BSTRI_ADD(len) H_LOG1(size)) 292 #define CNT2_BSTRI(len,size) CALC_HS(HS_SUB(size), BSTRI_SUB(len) H_LOG2(size)) 293 #define CNT1_ARR(len,size) CALC_HS(HS_ADD(size), ARR_ADD(len) H_LOG1(size)) 294 #define CNT2_ARR(len,size) CALC_HS(HS_SUB(size), ARR_SUB(len) H_LOG2(size)) 295 #define CNT1_HSH(len,size) CALC_HS(HS_ADD(size), HSH_ADD(len) H_LOG1(size)) 296 #define CNT2_HSH(len,size) CALC_HS(HS_SUB(size), HSH_SUB(len) H_LOG2(size)) 297 #define CNT1_SET(len,size) CALC_HS(HS_ADD(size), SET_ADD(len) H_LOG1(size)) 298 #define CNT2_SET(len,size) CALC_HS(HS_SUB(size), SET_SUB(len) H_LOG2(size)) 299 #define CNT1_SCT(len,size) CALC_HS(HS_ADD(size), SCT_ADD(len) H_LOG1(size)) 300 #define CNT2_SCT(len,size) CALC_HS(HS_SUB(size), SCT_SUB(len) H_LOG2(size)) 301 #define CNT1_BIG(len,size) CALC_HS(HS_ADD(size), BIG_ADD(len) H_LOG1(size)) 302 #define CNT2_BIG(len,size) CALC_HS(HS_SUB(size), BIG_SUB(len) H_LOG2(size)) 303 #define CNT1_REC(size,cnt) CALC_HS(HS_ADD(size), REC_ADD(cnt) H_LOG1(size)) 304 #define CNT2_REC(size,cnt) CALC_HS(HS_SUB(size), REC_SUB(cnt) H_LOG2(size)) 305 #define CNT1_REC2(size,cnt,byt) CALC_HS(HS_ADD(size), REC2_ADD(size,cnt,byt) H_LOG1(size)) 306 #define CNT2_REC2(size,cnt,byt) CALC_HS(HS_SUB(size), REC2_SUB(size,cnt,byt) H_LOG2(size)) 307 #define CNT1_BYT(size) CALC_HS(HS_ADD(size), BYT_ADD(size) H_LOG1(size)) 308 #define CNT2_BYT(size) CALC_HS(HS_SUB(size), BYT_SUB(size) H_LOG2(size)) 309 #define CNT1_RTL_L_ELEM(size) CALC_HS(HS_ADD(size), RTL_L_ELEM_ADD H_LOG1(size)) 310 #define CNT2_RTL_L_ELEM(size) CALC_HS(HS_SUB(size), RTL_L_ELEM_SUB H_LOG2(size)) 311 #define CNT1_RTL_ARR(len,size) CALC_HS(HS_ADD(size), RTL_ARR_ADD(len) H_LOG1(size)) 312 #define CNT2_RTL_ARR(len,size) CALC_HS(HS_SUB(size), RTL_ARR_SUB(len) H_LOG2(size)) 313 #define CNT1_RTL_HSH(len,size) CALC_HS(HS_ADD(size), RTL_HSH_ADD(len) H_LOG1(size)) 314 #define CNT2_RTL_HSH(len,size) CALC_HS(HS_SUB(size), RTL_HSH_SUB(len) H_LOG2(size)) 315 316 317 #define ALLOC_HEAP(var,tp,byt) ((var = (tp) MALLOC(byt)) != NULL) 318 #define REALLOC_HEAP(var,tp,byt) ((tp) REALLOC(var, byt)) 319 #define FREE_HEAP(var,byt) (free((void *) var)) 320 321 322 #define ALLOC_USTRI(var,len) ALLOC_HEAP(var, ustriType, SIZ_USTRI(len)) 323 #define UNALLOC_USTRI(var,len) FREE_HEAP(var, SIZ_USTRI(len)) 324 #define FREE_USTRI(var,L,cnt,byt) (CNT(CNT2_USTRI(L, SIZ_USTRI(L), cnt, byt)) FREE_HEAP(var, SIZ_USTRI(L))) 325 #define REALLOC_USTRI(var,L1,L2) REALLOC_HEAP(var, ustriType, SIZ_USTRI(L2)) 326 #define COUNT_USTRI(len,cnt,byt) CNT1_USTRI(len, SIZ_USTRI(len), cnt, byt) 327 #define COUNT3_USTRI(L1,L2,CT,byt) CNT3(CNT2_USTRI(L1, SIZ_USTRI(L1), CT, byt), CNT1_USTRI(L2, SIZ_USTRI(L2), CT, byt)) 328 329 330 #define ALLOC_CSTRI(var,len) ALLOC_HEAP(var, cstriType, SIZ_CSTRI(len)) 331 #define REALLOC_CSTRI(var,len) ((cstriType) REALLOC_HEAP(var, ustriType, SIZ_CSTRI(len))) 332 #define UNALLOC_CSTRI(var,len) FREE_HEAP(var, SIZ_CSTRI(len)) 333 334 335 #define ALLOC_WSTRI(var,len) ALLOC_HEAP(var, wstriType, SIZ_WSTRI(len)) 336 #define REALLOC_WSTRI(var,len) ((wstriType) REALLOC_HEAP(var, ustriType, SIZ_WSTRI(len))) 337 #define UNALLOC_WSTRI(var,len) FREE_HEAP(var, SIZ_WSTRI(len)) 338 339 340 #if WITH_STRI_CAPACITY 341 #if ALLOW_STRITYPE_SLICES 342 #define HEAP_ALLOC_STRI(var,cap) (ALLOC_HEAP(var,striType,SIZ_STRI(cap))?((var)->mem=(var)->mem1,(var)->capacity=(cap),CNT(CNT1_STRI(cap,SIZ_STRI(cap))) TRUE):FALSE) 343 #define HEAP_REALLOC_STRI(v1,v2,c1,c2) if((v1=REALLOC_HEAP(v2,striType,SIZ_STRI(c2)))!=NULL){(v1)->mem=(v1)->mem1,(v1)->capacity=(c2);} 344 #else 345 #define HEAP_ALLOC_STRI(var,cap) (ALLOC_HEAP(var,striType,SIZ_STRI(cap))?((var)->capacity=(cap),CNT(CNT1_STRI(cap,SIZ_STRI(cap))) TRUE):FALSE) 346 #define HEAP_REALLOC_STRI(v1,v2,c1,c2) if((v1=REALLOC_HEAP(v2,striType,SIZ_STRI(c2)))!=NULL)(v1)->capacity=(c2); 347 #endif 348 #else 349 #if ALLOW_STRITYPE_SLICES 350 #define HEAP_ALLOC_STRI(var,len) (ALLOC_HEAP(var,striType,SIZ_STRI(len))?((var)->mem=(var)->mem1,CNT(CNT1_STRI(len,SIZ_STRI(len))) TRUE):FALSE) 351 #define HEAP_REALLOC_STRI(v1,v2,l1,l2) if((v1=REALLOC_HEAP(v2,striType,SIZ_STRI(l2)))!=NULL)(v1)->mem=(v1)->mem1; 352 #else 353 #define HEAP_ALLOC_STRI(var,len) (ALLOC_HEAP(var,striType,SIZ_STRI(len))?(CNT(CNT1_STRI(len,SIZ_STRI(len))) TRUE):FALSE) 354 #define HEAP_REALLOC_STRI(v1,v2,l1,l2) v1=REALLOC_HEAP(v2,striType,SIZ_STRI(l2)); 355 #endif 356 #endif 357 #define HEAP_FREE_STRI(var,len) (CNT(CNT2_STRI((var)->capacity,SIZ_STRI((var)->capacity))) FREE_HEAP(var,SIZ_STRI((var)->capacity))) 358 #define COUNT3_STRI(cap1,cap2) CNT3(CNT2_STRI(cap1, SIZ_STRI(cap1)), CNT1_STRI(cap2, SIZ_STRI(cap2))) 359 #define COUNT_GROW_STRI(len1,len2) 360 #define COUNT_GROW2_STRI(len1,len2) 361 #define COUNT_SHRINK_STRI(len1,len2) 362 363 364 #if WITH_STRI_FREELIST 365 #if WITH_STRI_CAPACITY 366 367 #define MAX_STRI_LEN_IN_FREELIST 19 368 #define STRI_FREELIST_ARRAY_SIZE MAX_STRI_LEN_IN_FREELIST + 1 369 370 #ifdef DO_INIT 371 freeListElemType sflist[STRI_FREELIST_ARRAY_SIZE] = { 372 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 373 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 374 #if WITH_ADJUSTED_STRI_FREELIST 375 unsigned int sflist_allowed[STRI_FREELIST_ARRAY_SIZE] = { 376 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 377 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 378 boolType sflist_was_full[STRI_FREELIST_ARRAY_SIZE] = { 379 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 381 #else 382 unsigned int sflist_allowed[STRI_FREELIST_ARRAY_SIZE] = { 383 160, 40, 40, 40, 40, 40, 40, 40, 40, 40, 384 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}; 385 #endif 386 #else 387 EXTERN freeListElemType sflist[STRI_FREELIST_ARRAY_SIZE]; 388 EXTERN unsigned int sflist_allowed[STRI_FREELIST_ARRAY_SIZE]; 389 EXTERN boolType sflist_was_full[STRI_FREELIST_ARRAY_SIZE]; 390 #endif 391 392 #define POP_STRI_OK(len) (len) < STRI_FREELIST_ARRAY_SIZE && sflist[len] != NULL 393 #define PUSH_STRI_OK(var) (var)->capacity < STRI_FREELIST_ARRAY_SIZE && sflist_allowed[(var)->capacity] > 0 394 395 #define POP_STRI(var,len) (var = (striType) sflist[len], sflist[len] = sflist[len]->next, sflist_allowed[len]++, TRUE) 396 #define PUSH_STRI(var,len) { ((freeListElemType) var)->next = sflist[len]; sflist[len] = (freeListElemType) var; sflist_allowed[len]--; } 397 398 #if WITH_ADJUSTED_STRI_FREELIST 399 #define ADJUST_ALLOWED_LEN(len) (sflist_was_full[len] ? (sflist_was_full[len]=0, sflist_allowed[len] < 65536 ? sflist_allowed[len]<<=1 : 0) : 0) 400 401 #define ALLOC_SFLIST_STRI(var,len) (ADJUST_ALLOWED_LEN(len), HEAP_ALLOC_STRI(var, len)) 402 #define FREE_SFLIST_STRI(var,len) { sflist_was_full[len]=1; HEAP_FREE_STRI(var, len); } 403 404 #define POP_OR_ALLOC_STRI(var,len) (sflist[len] != NULL ? POP_STRI(var, len) : ALLOC_SFLIST_STRI(var,len)) 405 #define PUSH_OR_FREE_STRI(var,len) { if (sflist_allowed[len] > 0) PUSH_STRI(var, len) else FREE_SFLIST_STRI(var, len) } 406 407 #define ALLOC_STRI_SIZE_OK(var,len) ((len) < STRI_FREELIST_ARRAY_SIZE ? POP_OR_ALLOC_STRI(var,len) : HEAP_ALLOC_STRI(var, len)) 408 #define ALLOC_STRI_CHECK_SIZE(var,len) ((len) < STRI_FREELIST_ARRAY_SIZE ? POP_OR_ALLOC_STRI(var,len) : ((len)<=MAX_STRI_LEN?HEAP_ALLOC_STRI(var, len):(var=NULL, FALSE))) 409 #define FREE_STRI(var,len) if ((var)->capacity < STRI_FREELIST_ARRAY_SIZE) PUSH_OR_FREE_STRI(var, (var)->capacity) else HEAP_FREE_STRI(var, len); 410 411 #else 412 413 #define ALLOC_STRI_SIZE_OK(var,len) (POP_STRI_OK(len) ? POP_STRI(var, len) : HEAP_ALLOC_STRI(var, len)) 414 #define ALLOC_STRI_CHECK_SIZE(var,len) (POP_STRI_OK(len) ? POP_STRI(var, len) : ((len)<=MAX_STRI_LEN?HEAP_ALLOC_STRI(var, len):(var=NULL, FALSE))) 415 #define FREE_STRI(var,len) if (PUSH_STRI_OK(var)) PUSH_STRI(var, (var)->capacity) else HEAP_FREE_STRI(var, len); 416 #endif 417 418 #else 419 420 #define MAX_STRI_LEN_IN_FREELIST 1 421 422 #ifdef DO_INIT 423 freeListElemType sflist = NULL; 424 unsigned int sflist_allowed = 40; 425 #else 426 EXTERN freeListElemType sflist; 427 EXTERN unsigned int sflist_allowed; 428 #endif 429 430 #define POP_STRI_OK(len) (len) == 1 && sflist != NULL 431 #define PUSH_STRI_OK(var) (var)->size == 1 && sflist_allowed > 0 432 433 #define POP_STRI(var) (var = (striType) sflist, sflist = sflist->next, sflist_allowed++, TRUE) 434 #define PUSH_STRI(var) {((freeListElemType) var)->next = sflist; sflist = (freeListElemType) var; sflist_allowed--; } 435 436 #define ALLOC_STRI_SIZE_OK(var,len) (POP_STRI_OK(len) ? POP_STRI(var) : HEAP_ALLOC_STRI(var, len)) 437 #define ALLOC_STRI_CHECK_SIZE(var,len) (POP_STRI_OK(len) ? POP_STRI(var) : ((len)<=MAX_STRI_LEN?HEAP_ALLOC_STRI(var, len):(var=NULL, FALSE))) 438 #define FREE_STRI(var,len) if (PUSH_STRI_OK(var)) PUSH_STRI(var) else HEAP_FREE_STRI(var, len); 439 440 #endif 441 #else 442 443 #define ALLOC_STRI_SIZE_OK(var,len) HEAP_ALLOC_STRI(var, len) 444 #define ALLOC_STRI_CHECK_SIZE(var,len) ((len)<=MAX_STRI_LEN?HEAP_ALLOC_STRI(var, len):(var=NULL, FALSE)) 445 #define FREE_STRI(var,len) HEAP_FREE_STRI(var,len) 446 447 #endif 448 449 #if WITH_STRI_CAPACITY 450 #define GROW_STRI(v1,v2,l1,l2) ((l2)>(v2)->capacity?(v1=growStri(v2,l2)):(v1=(v2))) 451 #define SHRINK_STRI(v1,v2,l1,l2) ((l2)<(v2)->capacity>>2?(v1=shrinkStri(v2,l2)):(v1=(v2))) 452 #define MIN_GROW_SHRINK_CAPACITY 8 453 #define SHRINK_REASON(v2,l2) ((v2)->capacity>MIN_GROW_SHRINK_CAPACITY&&(l2)<(v2)->capacity>>2) 454 #else 455 #define GROW_STRI(v1,v2,l1,l2) if((l2) <= MAX_STRI_LEN){HEAP_REALLOC_STRI(v1,v2,l1,l2)}else v1=NULL; 456 #define SHRINK_STRI(v1,v2,l1,l2) HEAP_REALLOC_STRI(v1,v2,l1,l2) 457 #endif 458 459 #define REALLOC_STRI_SIZE_OK(v1,v2,l1,l2) HEAP_REALLOC_STRI(v1,v2,l1,l2) 460 #define REALLOC_STRI_CHECK_SIZE(v1,v2,l1,l2) if((l2) <= MAX_STRI_LEN){HEAP_REALLOC_STRI(v1,v2,l1,l2)}else v1=NULL; 461 /* The following macro is used if the new size is smaller or equal to the current one. */ 462 #define REALLOC_STRI_SIZE_SMALLER(v1,v2,l1,l2) HEAP_REALLOC_STRI(v1,v2,l1,l2) 463 464 #if ALLOW_STRITYPE_SLICES 465 #define GET_DESTINATION_ORIGIN(dest) (dest)->mem1 466 #define SLICE_OVERLAPPING2(var,origin,beyond) ((var)->mem>=(origin)&&(var)->mem<(beyond)) 467 #if WITH_STRI_CAPACITY 468 #define GET_DESTINATION_BEYOND(dest) &(dest)->mem1[(dest)->capacity] 469 #define SLICE_OVERLAPPING(var,dest) ((var)->mem>=(dest)->mem1&&(var)->mem<&(dest)->mem1[(dest)->capacity]) 470 #define SET_SLICE_CAPACITY(var,cap) (var)->capacity = (cap) 471 #else 472 #define GET_DESTINATION_BEYOND(dest) &(dest)->mem1[(dest)->size] 473 #define SLICE_OVERLAPPING(var,dest) ((var)->mem>=(dest)->mem1&&(var)->mem<&(dest)->mem1[(dest)->size]) 474 #define SET_SLICE_CAPACITY(var,cap) 475 #endif 476 #endif 477 478 479 #if ALLOW_BSTRITYPE_SLICES 480 #define ALLOC_BSTRI_SIZE_OK(var,len) (ALLOC_HEAP(var, bstriType, SIZ_BSTRI(len))?(var->mem = var->mem1, CNT(CNT1_BSTRI(len, SIZ_BSTRI(len))) TRUE):FALSE) 481 #define REALLOC_BSTRI_SIZE_OK(v1,v2,l1,l2) ((v1=REALLOC_HEAP(v2, bstriType, SIZ_BSTRI(l2)))?((v1)->mem=(v1)->mem1,0):0) 482 #else 483 #define ALLOC_BSTRI_SIZE_OK(var,len) (ALLOC_HEAP(var, bstriType, SIZ_BSTRI(len))?CNT(CNT1_BSTRI(len, SIZ_BSTRI(len))) TRUE:FALSE) 484 #define REALLOC_BSTRI_SIZE_OK(v1,v2,l1,l2) (v1=REALLOC_HEAP(v2, bstriType, SIZ_BSTRI(l2)),0) 485 #endif 486 487 #define ALLOC_BSTRI_CHECK_SIZE(var,len) ((len) <= MAX_BSTRI_LEN?ALLOC_BSTRI_SIZE_OK(var, len):(var=NULL,FALSE)) 488 #define FREE_BSTRI(var,len) (CNT(CNT2_BSTRI(len, SIZ_BSTRI(len))) FREE_HEAP(var, SIZ_BSTRI(len))) 489 #define REALLOC_BSTRI_CHECK_SIZE(v1,v2,l1,l2) ((l2) <= MAX_BSTRI_LEN?REALLOC_BSTRI_SIZE_OK(v1,v2,l1,l2):(v1=NULL,0)) 490 #define COUNT3_BSTRI(len1,len2) CNT3(CNT2_BSTRI(len1, SIZ_BSTRI(len1)), CNT1_BSTRI(len2, SIZ_BSTRI(len2))) 491 492 493 #define ALLOC_RTL_L_ELEM(var) (ALLOC_HEAP(var, rtlListType, SIZ_RTL_L_ELEM)?CNT(CNT1_RTL_L_ELEM(SIZ_RTL_L_ELEM)) TRUE:FALSE) 494 #define FREE_RTL_L_ELEM(var) (CNT(CNT2_RTL_L_ELEM(SIZ_RTL_L_ELEM)) FREE_HEAP(var, SIZ_RTL_L_ELEM)) 495 496 497 #define ALLOC_ARRAY(var,len) (ALLOC_HEAP(var, arrayType, SIZ_ARR(len))?CNT(CNT1_ARR(len, SIZ_ARR(len))) TRUE:FALSE) 498 #define FREE_ARRAY(var,len) (CNT(CNT2_ARR(len, SIZ_ARR(len))) FREE_HEAP(var, SIZ_ARR(len))) 499 #define REALLOC_ARRAY(var,ln1,ln2) REALLOC_HEAP(var, arrayType, SIZ_ARR(ln2)) 500 #define COUNT3_ARRAY(len1,len2) CNT3(CNT2_ARR(len1, SIZ_ARR(len1)), CNT1_ARR(len2, SIZ_ARR(len2))) 501 502 503 #define ALLOC_RTL_ARRAY(var,len) (ALLOC_HEAP(var, rtlArrayType, SIZ_RTL_ARR(len))?CNT(CNT1_RTL_ARR(len, SIZ_RTL_ARR(len))) TRUE:FALSE) 504 #define FREE_RTL_ARRAY(var,len) (CNT(CNT2_RTL_ARR(len, SIZ_RTL_ARR(len))) FREE_HEAP(var, SIZ_RTL_ARR(len))) 505 #define REALLOC_RTL_ARRAY(var,ln1,ln2) REALLOC_HEAP(var, rtlArrayType, SIZ_RTL_ARR(ln2)) 506 #define COUNT3_RTL_ARRAY(len1,len2) CNT3(CNT2_RTL_ARR(len1, SIZ_RTL_ARR(len1)), CNT1_RTL_ARR(len2, SIZ_RTL_ARR(len2))) 507 508 509 #define ALLOC_HASH(var,len) (ALLOC_HEAP(var, hashType, SIZ_HSH(len))?CNT(CNT1_HSH(len, SIZ_HSH(len))) TRUE:FALSE) 510 #define FREE_HASH(var,len) (CNT(CNT2_HSH(len, SIZ_HSH(len))) FREE_HEAP(var, SIZ_HSH(len))) 511 #define REALLOC_HASH(var,ln1,ln2) REALLOC_HEAP(var, hashType, SIZ_HSH(ln2)) 512 #define COUNT3_HASH(len1,len2) CNT3(CNT2_HSH(len1, SIZ_HSH(len1)), CNT1_HSH(len2, SIZ_HSH(len2))) 513 514 515 #define ALLOC_RTL_HASH(var,len) (ALLOC_HEAP(var, rtlHashType, SIZ_RTL_HSH(len))?CNT(CNT1_RTL_HSH(len, SIZ_RTL_HSH(len))) TRUE:FALSE) 516 #define FREE_RTL_HASH(var,len) (CNT(CNT2_RTL_HSH(len, SIZ_RTL_HSH(len))) FREE_HEAP(var, SIZ_RTL_HSH(len))) 517 #define REALLOC_RTL_HASH(var,ln1,ln2) REALLOC_HEAP(var, rtlHashType, SIZ_RTL_HSH(ln2)) 518 #define COUNT3_RTL_HASH(len1,len2) CNT3(CNT2_RTL_HSH(len1, SIZ_RTL_HSH(len1)), CNT1_RTL_HSH(len2, SIZ_RTL_HSH(len2))) 519 520 521 #define ALLOC_SET(var,len) (ALLOC_HEAP(var, setType, SIZ_SET(len))?CNT(CNT1_SET(len, SIZ_SET(len))) TRUE:FALSE) 522 #define FREE_SET(var,len) (CNT(CNT2_SET(len, SIZ_SET(len))) FREE_HEAP(var, SIZ_SET(len))) 523 #define REALLOC_SET(var,len1,len2) REALLOC_HEAP(var, setType, SIZ_SET(len2)) 524 #define COUNT3_SET(len1,len2) CNT3(CNT2_SET(len1, SIZ_SET(len1)), CNT1_SET(len2, SIZ_SET(len2))) 525 526 527 #define ALLOC_STRUCT(var,len) (ALLOC_HEAP(var, structType, SIZ_SCT(len))?CNT(CNT1_SCT(len, SIZ_SCT(len))) TRUE:FALSE) 528 #define FREE_STRUCT(var,len) (CNT(CNT2_SCT(len, SIZ_SCT(len))) FREE_HEAP(var, SIZ_SCT(len))) 529 #define REALLOC_STRUCT(var,ln1,ln2) REALLOC_HEAP(var, structType, SIZ_SCT(ln2)) 530 #define COUNT3_STRUCT(len1,len2) CNT3(CNT2_SCT(len1, SIZ_SCT(len1)), CNT1_SCT(len2, SIZ_SCT(len2))) 531 532 533 #define ALLOC_RTL_STRUCT(var,len) (ALLOC_HEAP(var, rtlStructType, SIZ_SCT(len))?CNT(CNT1_SCT(len, SIZ_SCT(len))) TRUE:FALSE) 534 #define FREE_RTL_STRUCT(var,len) (CNT(CNT2_SCT(len, SIZ_SCT(len))) FREE_HEAP(var, SIZ_SCT(len))) 535 #define REALLOC_RTL_STRUCT(var,ln1,ln2) REALLOC_HEAP(var, rtlStructType, SIZ_SCT(ln2)) 536 #define COUNT3_RTL_STRUCT(len1,len2) CNT3(CNT2_SCT(len1, SIZ_SCT(len1)), CNT1_SCT(len2, SIZ_SCT(len2))) 537 538 539 #define ALLOC_RECORD(var,rec,cnt) (ALLOC_HEAP(var, rec*, SIZ_REC(rec))?CNT(CNT1_REC(SIZ_REC(rec), cnt)) TRUE:FALSE) 540 #define FREE_RECORD(var,rec,cnt) (CNT(CNT2_REC(SIZ_REC(rec), cnt)) FREE_HEAP(var, SIZ_REC(rec))) 541 542 543 #define ALLOC_RECORD2(var,rec,cnt,byt) (ALLOC_HEAP(var, rec*, SIZ_REC(rec))?CNT(CNT1_REC2(SIZ_REC(rec), cnt, byt)) TRUE:FALSE) 544 #define FREE_RECORD2(var,rec,cnt,byt) (CNT(CNT2_REC2(SIZ_REC(rec), cnt, byt)) FREE_HEAP(var, SIZ_REC(rec))) 545 546 547 #define ALLOC_BYTES(var,byt) (ALLOC_HEAP(var, char *, byt)?CNT(CNT1_BYT(byt)) TRUE:FALSE) 548 #define ALLOC_UBYTES(var,byt) (ALLOC_HEAP(var, unsigned char *, byt)?CNT(CNT1_BYT(byt)) TRUE:FALSE) 549 #define FREE_BYTES(var,byt) (CNT(CNT2_BYT(byt)) FREE_HEAP(var, byt)) 550 551 552 #define ALLOC_TABLE(var,tp,nr) (ALLOC_HEAP(var, tp *, SIZ_TAB(tp,nr))?CNT(CNT1_BYT(SIZ_TAB(tp,nr))) TRUE:FALSE) 553 #define FREE_TABLE(var,tp,nr) (CNT(CNT2_BYT(SIZ_TAB(tp, nr))) FREE_HEAP(var, SIZ_TAB(tp, nr))) 554 #define REALLOC_TABLE(var,tp,n1,n2) REALLOC_HEAP(var, tp *, SIZ_TAB(tp, n2)) 555 #define COUNT3_TABLE(tp,nr1,nr2) CNT3(CNT2_BYT(SIZ_TAB(tp, nr1)), CNT1_BYT(SIZ_TAB(tp, nr2))) 556 557 558 void setupStack (void); 559 #if CHECK_STACK 560 boolType checkStack (boolType inLogMacro); 561 memSizeType getMaxStackSize (void); 562 #endif 563 #if WITH_STRI_CAPACITY 564 striType growStri (striType stri, memSizeType len); 565 striType shrinkStri (striType stri, memSizeType len); 566 #endif 567 #if DO_HEAP_CHECK 568 void check_heap (long, const char *, unsigned int); 569 #endif 570 #if !DO_HEAP_STATISTIC 571 void heapStatistic (void); 572 #endif 573