master
c 782 lines 23.4 KB
Raw
1 // Copyright (C) 2000 - 2002 Hewlett-Packard Company
2 //
3 // This program is free software; you can redistribute it and/or modify it
4 // under the term of the GNU Lesser General Public License as published by the
5 // Free Software Foundation; either version 2 of the License, or (at your
6 // option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful, but WITHOUT
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11 // for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with this program; if not, write to the Free Software Foundation,
15 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // _________________
17
18 // @(#) $Revision: 4.45 $ $Source: /judy/src/JudyCommon/JudyMallocIF.c $
19 //
20 // Judy malloc/free interface functions for Judy1 and JudyL.
21 //
22 // Compile with one of -DJUDY1 or -DJUDYL.
23 //
24 // Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
25 // calls at the interface level. (See also TRACEMF in lower-level code.)
26 // Use -DTRACEMI2 for a terser format suitable for trace analysis.
27 //
28 // There can be malloc namespace bits in the LSBs of "raw" addresses from most,
29 // but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
30 // test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
31 // only (for assertions). This test ensures that (a) all callers properly mask
32 // the namespace bits out before dereferencing a pointer (or else a core dump
33 // occurs), and (b) all callers send "raw" (unmasked) addresses to
34 // j__udy*Free*() calls.
35 //
36 // Note: Currently -DDEBUG turns on MALLOCBITS automatically.
37
38 #if (! (defined(JUDY1) || defined(JUDYL)))
39 #error: One of -DJUDY1 or -DJUDYL must be specified.
40 #endif
41
42 #ifdef JUDY1
43 #include "Judy1.h"
44 #else
45 #include "JudyL.h"
46 #endif
47
48 #include "JudyPrivate1L.h"
49
50 // Set "hidden" global j__uMaxWords to the maximum number of words to allocate
51 // to any one array (large enough to have a JPM, otherwise j__uMaxWords is
52 // ignored), to trigger a fake malloc error when the number is exceeded. Note,
53 // this code is always executed, not #ifdefd, because its virtually free.
54 //
55 // Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
56 // MAXINT, not zero, by default.
57
58 Word_t j__uMaxWords = ~0UL;
59
60 // This macro hides the faking of a malloc failure:
61 //
62 // Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
63 // complexity of first adding WordsNow, meaning the trigger point is not
64 // exactly where you might assume, but it shouldnt matter.
65
66 #define MALLOC(MallocFunc,WordsPrev,WordsNow) \
67 (((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
68
69 // Clear words starting at address:
70 //
71 // Note: Only use this for objects that care; in other cases, it doesnt
72 // matter if the objects memory is pre-zeroed.
73
74 #define ZEROWORDS(Addr,Words) \
75 { \
76 Word_t Words__ = (Words); \
77 PWord_t Addr__ = (PWord_t) (Addr); \
78 while (Words__--) *Addr__++ = 0UL; \
79 }
80
81 #ifdef TRACEMI
82
83 // TRACING SUPPORT:
84 //
85 // Note: For TRACEMI, use a format for address printing compatible with other
86 // tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
87 // part on 64-bit systems.
88 //
89 // TBD: The trace macros need fixing for alternate address types.
90 //
91 // Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
92 // engine used.
93
94 #include <stdio.h>
95
96 static Word_t j__udyMemSequence = 0L; // event sequence number.
97
98 #define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
99 #define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
100 #define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
101 #define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
102
103 #else
104
105 #ifdef TRACEMI2
106
107 #include <stdio.h>
108
109 #define b_pw cJU_BYTESPERWORD
110
111 #define TRACE_ALLOC5(a,b,c,d,e) \
112 (void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
113 #define TRACE_FREE5( a,b,c,d,e) \
114 (void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
115 #define TRACE_ALLOC6(a,b,c,d,e,f) \
116 (void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
117 #define TRACE_FREE6( a,b,c,d,e,f) \
118 (void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
119
120 static Word_t j__udyMemSequence = 0L; // event sequence number.
121
122 #else
123
124 #define TRACE_ALLOC5(a,b,c,d,e) // null.
125 #define TRACE_FREE5( a,b,c,d,e) // null.
126 #define TRACE_ALLOC6(a,b,c,d,e,f) // null.
127 #define TRACE_FREE6( a,b,c,d,e,f) // null.
128
129 #endif // ! TRACEMI2
130 #endif // ! TRACEMI
131
132
133 // MALLOC NAMESPACE SUPPORT:
134
135 #if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
136 #define MALLOCBITS 1
137 #endif
138
139 #ifdef MALLOCBITS
140 #define MALLOCBITS_VALUE 0x3 // bit pattern to use.
141 #define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
142
143 #define MALLOCBITS_SET( Type,Addr) \
144 ((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
145 #define MALLOCBITS_TEST(Type,Addr) \
146 assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
147 ((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
148 #else
149 #define MALLOCBITS_SET( Type,Addr) // null.
150 #define MALLOCBITS_TEST(Type,Addr) // null.
151 #endif
152
153
154 // SAVE ERROR INFORMATION IN A Pjpm:
155 //
156 // "Small" (invalid) Addr values are used to distinguish overrun and no-mem
157 // errors. (TBD, non-zero invalid values are no longer returned from
158 // lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
159
160 #define J__UDYSETALLOCERROR(Addr) \
161 { \
162 JU_ERRID(Pjpm) = __LINE__; \
163 if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
164 else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
165 return(0); \
166 }
167
168
169 // ****************************************************************************
170 // ALLOCATION FUNCTIONS:
171 //
172 // To help the compiler catch coding errors, each function returns a specific
173 // object type.
174 //
175 // Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
176 // sizeof(Word_t) to indicate the type of memory allocation failure. Other
177 // allocation functions convert this failure to a JU_ERRNO.
178
179
180 // Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
181 // that is, without malloc namespace or root pointer type bits:
182
183 FUNCTION Pjpm_t j__udyAllocJPM(void)
184 {
185 Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
186 Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
187
188 assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
189
190 if ((Word_t) Pjpm > sizeof(Word_t))
191 {
192 ZEROWORDS(Pjpm, Words);
193 Pjpm->jpm_TotalMemWords = Words;
194 }
195
196 TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
197 Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
198 // MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
199 return(Pjpm);
200
201 } // j__udyAllocJPM()
202
203
204 FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
205 {
206 Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
207 Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
208 Pjpm->jpm_TotalMemWords, Words);
209
210 assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
211
212 if ((Word_t) PjblRaw > sizeof(Word_t))
213 {
214 ZEROWORDS(P_JBL(PjblRaw), Words);
215 Pjpm->jpm_TotalMemWords += Words;
216 }
217 else { J__UDYSETALLOCERROR(PjblRaw); }
218
219 TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
220 j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
221 MALLOCBITS_SET(Pjbl_t, PjblRaw);
222 return(PjblRaw);
223
224 } // j__udyAllocJBL()
225
226
227 FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
228 {
229 Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
230 Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
231 Pjpm->jpm_TotalMemWords, Words);
232
233 assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
234
235 if ((Word_t) PjbbRaw > sizeof(Word_t))
236 {
237 ZEROWORDS(P_JBB(PjbbRaw), Words);
238 Pjpm->jpm_TotalMemWords += Words;
239 }
240 else { J__UDYSETALLOCERROR(PjbbRaw); }
241
242 TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
243 j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
244 MALLOCBITS_SET(Pjbb_t, PjbbRaw);
245 return(PjbbRaw);
246
247 } // j__udyAllocJBB()
248
249
250 FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
251 {
252 Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
253 Pjp_t PjpRaw;
254
255 PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
256
257 if ((Word_t) PjpRaw > sizeof(Word_t))
258 {
259 Pjpm->jpm_TotalMemWords += Words;
260 }
261 else { J__UDYSETALLOCERROR(PjpRaw); }
262
263 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
264 j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
265 MALLOCBITS_SET(Pjp_t, PjpRaw);
266 return(PjpRaw);
267
268 } // j__udyAllocJBBJP()
269
270
271 FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
272 {
273 Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
274 Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
275 Pjpm->jpm_TotalMemWords, Words);
276
277 assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
278
279 if ((Word_t) PjbuRaw > sizeof(Word_t))
280 {
281 Pjpm->jpm_TotalMemWords += Words;
282 }
283 else { J__UDYSETALLOCERROR(PjbuRaw); }
284
285 TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
286 j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
287 MALLOCBITS_SET(Pjbu_t, PjbuRaw);
288 return(PjbuRaw);
289
290 } // j__udyAllocJBU()
291
292
293 #if (defined(JUDYL) || (! defined(JU_64BIT)))
294
295 FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
296 {
297 Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
298 Pjll_t PjllRaw;
299
300 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
301
302 if ((Word_t) PjllRaw > sizeof(Word_t))
303 {
304 Pjpm->jpm_TotalMemWords += Words;
305 }
306 else { J__UDYSETALLOCERROR(PjllRaw); }
307
308 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
309 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
310 MALLOCBITS_SET(Pjll_t, PjllRaw);
311 return(PjllRaw);
312
313 } // j__udyAllocJLL1()
314
315 #endif // (JUDYL || (! JU_64BIT))
316
317
318 FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
319 {
320 Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
321 Pjll_t PjllRaw;
322
323 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
324
325 if ((Word_t) PjllRaw > sizeof(Word_t))
326 {
327 Pjpm->jpm_TotalMemWords += Words;
328 }
329 else { J__UDYSETALLOCERROR(PjllRaw); }
330
331 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
332 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
333 MALLOCBITS_SET(Pjll_t, PjllRaw);
334 return(PjllRaw);
335
336 } // j__udyAllocJLL2()
337
338
339 FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
340 {
341 Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
342 Pjll_t PjllRaw;
343
344 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
345
346 if ((Word_t) PjllRaw > sizeof(Word_t))
347 {
348 Pjpm->jpm_TotalMemWords += Words;
349 }
350 else { J__UDYSETALLOCERROR(PjllRaw); }
351
352 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
353 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
354 MALLOCBITS_SET(Pjll_t, PjllRaw);
355 return(PjllRaw);
356
357 } // j__udyAllocJLL3()
358
359
360 #ifdef JU_64BIT
361
362 FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
363 {
364 Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
365 Pjll_t PjllRaw;
366
367 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
368
369 if ((Word_t) PjllRaw > sizeof(Word_t))
370 {
371 Pjpm->jpm_TotalMemWords += Words;
372 }
373 else { J__UDYSETALLOCERROR(PjllRaw); }
374
375 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
376 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
377 MALLOCBITS_SET(Pjll_t, PjllRaw);
378 return(PjllRaw);
379
380 } // j__udyAllocJLL4()
381
382
383 FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
384 {
385 Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
386 Pjll_t PjllRaw;
387
388 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
389
390 if ((Word_t) PjllRaw > sizeof(Word_t))
391 {
392 Pjpm->jpm_TotalMemWords += Words;
393 }
394 else { J__UDYSETALLOCERROR(PjllRaw); }
395
396 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
397 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
398 MALLOCBITS_SET(Pjll_t, PjllRaw);
399 return(PjllRaw);
400
401 } // j__udyAllocJLL5()
402
403
404 FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
405 {
406 Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
407 Pjll_t PjllRaw;
408
409 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
410
411 if ((Word_t) PjllRaw > sizeof(Word_t))
412 {
413 Pjpm->jpm_TotalMemWords += Words;
414 }
415 else { J__UDYSETALLOCERROR(PjllRaw); }
416
417 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
418 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
419 MALLOCBITS_SET(Pjll_t, PjllRaw);
420 return(PjllRaw);
421
422 } // j__udyAllocJLL6()
423
424
425 FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
426 {
427 Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
428 Pjll_t PjllRaw;
429
430 PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
431
432 if ((Word_t) PjllRaw > sizeof(Word_t))
433 {
434 Pjpm->jpm_TotalMemWords += Words;
435 }
436 else { J__UDYSETALLOCERROR(PjllRaw); }
437
438 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
439 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
440 MALLOCBITS_SET(Pjll_t, PjllRaw);
441 return(PjllRaw);
442
443 } // j__udyAllocJLL7()
444
445 #endif // JU_64BIT
446
447
448 // Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
449 // other j__udyAlloc*() functions, they are returned non-raw, that is, without
450 // malloc namespace or root pointer type bits (the latter are added later by
451 // the caller):
452
453 FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
454 {
455 Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
456 Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
457
458 TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
459 j__udyMemSequence++, Pop1, Words, Pop1);
460 // MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
461 return(Pjlw);
462
463 } // j__udyAllocJLW()
464
465
466 FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
467 {
468 Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
469 Pjlb_t PjlbRaw;
470
471 PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
472
473 assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
474
475 if ((Word_t) PjlbRaw > sizeof(Word_t))
476 {
477 ZEROWORDS(P_JLB(PjlbRaw), Words);
478 Pjpm->jpm_TotalMemWords += Words;
479 }
480 else { J__UDYSETALLOCERROR(PjlbRaw); }
481
482 TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
483 j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
484 MALLOCBITS_SET(Pjlb_t, PjlbRaw);
485 return(PjlbRaw);
486
487 } // j__udyAllocJLB1()
488
489
490 #ifdef JUDYL
491
492 FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
493 {
494 Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
495 Pjv_t PjvRaw;
496
497 PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
498
499 if ((Word_t) PjvRaw > sizeof(Word_t))
500 {
501 Pjpm->jpm_TotalMemWords += Words;
502 }
503 else { J__UDYSETALLOCERROR(PjvRaw); }
504
505 TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
506 j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
507 MALLOCBITS_SET(Pjv_t, PjvRaw);
508 return(PjvRaw);
509
510 } // j__udyLAllocJV()
511
512 #endif // JUDYL
513
514
515 // ****************************************************************************
516 // FREE FUNCTIONS:
517 //
518 // To help the compiler catch coding errors, each function takes a specific
519 // object type to free.
520
521
522 // Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
523 // bits present, that is, they must be stripped by the caller using P_JPM():
524
525 FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
526 {
527 Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
528
529 // MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
530 JudyFree((Pvoid_t) PjpmFree, Words);
531
532 if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
533
534 // Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
535 // an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
536 // Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
537 // really will be 0, not cJU_LEAFW_MAXPOP1.
538
539 TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
540 j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
541
542
543 } // j__udyFreeJPM()
544
545
546 FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
547 {
548 Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
549
550 MALLOCBITS_TEST(Pjbl_t, Pjbl);
551 JudyFreeVirtual((Pvoid_t) Pjbl, Words);
552
553 Pjpm->jpm_TotalMemWords -= Words;
554
555 TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
556 j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
557
558
559 } // j__udyFreeJBL()
560
561
562 FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
563 {
564 Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
565
566 MALLOCBITS_TEST(Pjbb_t, Pjbb);
567 JudyFreeVirtual((Pvoid_t) Pjbb, Words);
568
569 Pjpm->jpm_TotalMemWords -= Words;
570
571 TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
572 j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
573
574
575 } // j__udyFreeJBB()
576
577
578 FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
579 {
580 Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
581
582 MALLOCBITS_TEST(Pjp_t, Pjp);
583 JudyFree((Pvoid_t) Pjp, Words);
584
585 Pjpm->jpm_TotalMemWords -= Words;
586
587 TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
588 j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
589
590
591 } // j__udyFreeJBBJP()
592
593
594 FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
595 {
596 Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
597
598 MALLOCBITS_TEST(Pjbu_t, Pjbu);
599 JudyFreeVirtual((Pvoid_t) Pjbu, Words);
600
601 Pjpm->jpm_TotalMemWords -= Words;
602
603 TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
604 j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
605
606
607 } // j__udyFreeJBU()
608
609
610 #if (defined(JUDYL) || (! defined(JU_64BIT)))
611
612 FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
613 {
614 Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
615
616 MALLOCBITS_TEST(Pjll_t, Pjll);
617 JudyFree((Pvoid_t) Pjll, Words);
618
619 Pjpm->jpm_TotalMemWords -= Words;
620
621 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
622 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
623
624
625 } // j__udyFreeJLL1()
626
627 #endif // (JUDYL || (! JU_64BIT))
628
629
630 FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
631 {
632 Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
633
634 MALLOCBITS_TEST(Pjll_t, Pjll);
635 JudyFree((Pvoid_t) Pjll, Words);
636
637 Pjpm->jpm_TotalMemWords -= Words;
638
639 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
640 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
641
642
643 } // j__udyFreeJLL2()
644
645
646 FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
647 {
648 Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
649
650 MALLOCBITS_TEST(Pjll_t, Pjll);
651 JudyFree((Pvoid_t) Pjll, Words);
652
653 Pjpm->jpm_TotalMemWords -= Words;
654
655 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
656 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
657
658
659 } // j__udyFreeJLL3()
660
661
662 #ifdef JU_64BIT
663
664 FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
665 {
666 Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
667
668 MALLOCBITS_TEST(Pjll_t, Pjll);
669 JudyFree((Pvoid_t) Pjll, Words);
670
671 Pjpm->jpm_TotalMemWords -= Words;
672
673 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
674 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
675
676
677 } // j__udyFreeJLL4()
678
679
680 FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
681 {
682 Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
683
684 MALLOCBITS_TEST(Pjll_t, Pjll);
685 JudyFree((Pvoid_t) Pjll, Words);
686
687 Pjpm->jpm_TotalMemWords -= Words;
688
689 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
690 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
691
692
693 } // j__udyFreeJLL5()
694
695
696 FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
697 {
698 Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
699
700 MALLOCBITS_TEST(Pjll_t, Pjll);
701 JudyFree((Pvoid_t) Pjll, Words);
702
703 Pjpm->jpm_TotalMemWords -= Words;
704
705 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
706 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
707
708
709 } // j__udyFreeJLL6()
710
711
712 FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
713 {
714 Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
715
716 MALLOCBITS_TEST(Pjll_t, Pjll);
717 JudyFree((Pvoid_t) Pjll, Words);
718
719 Pjpm->jpm_TotalMemWords -= Words;
720
721 TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
722 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
723
724
725 } // j__udyFreeJLL7()
726
727 #endif // JU_64BIT
728
729
730 // Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
731 // bits present, that is, they are stripped by P_JLW():
732
733 FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
734 {
735 Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
736
737 // MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
738 JudyFree((Pvoid_t) Pjlw, Words);
739
740 if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
741
742 TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
743 j__udyMemSequence++, Pop1, Words, Pop1 - 1);
744
745
746 } // j__udyFreeJLW()
747
748
749 FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
750 {
751 Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
752
753 MALLOCBITS_TEST(Pjlb_t, Pjlb);
754 JudyFree((Pvoid_t) Pjlb, Words);
755
756 Pjpm->jpm_TotalMemWords -= Words;
757
758 TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
759 j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
760
761
762 } // j__udyFreeJLB1()
763
764
765 #ifdef JUDYL
766
767 FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
768 {
769 Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
770
771 MALLOCBITS_TEST(Pjv_t, Pjv);
772 JudyFree((Pvoid_t) Pjv, Words);
773
774 Pjpm->jpm_TotalMemWords -= Words;
775
776 TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
777 j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
778
779
780 } // j__udyLFreeJV()
781
782 #endif // JUDYL