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