summaryrefslogtreecommitdiffstats
path: root/libnetdata/libjudy/src/JudyL/JudyLMallocIF.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/libjudy/src/JudyL/JudyLMallocIF.c')
-rw-r--r--libnetdata/libjudy/src/JudyL/JudyLMallocIF.c782
1 files changed, 782 insertions, 0 deletions
diff --git a/libnetdata/libjudy/src/JudyL/JudyLMallocIF.c b/libnetdata/libjudy/src/JudyL/JudyLMallocIF.c
new file mode 100644
index 00000000..9a7d02f2
--- /dev/null
+++ b/libnetdata/libjudy/src/JudyL/JudyLMallocIF.c
@@ -0,0 +1,782 @@
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the term of the GNU Lesser General Public License as published by the
+// Free Software Foundation; either version 2 of the License, or (at your
+// option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+// for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// _________________
+
+// @(#) $Revision: 4.45 $ $Source: /judy/src/JudyCommon/JudyMallocIF.c $
+//
+// Judy malloc/free interface functions for Judy1 and JudyL.
+//
+// Compile with one of -DJUDY1 or -DJUDYL.
+//
+// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
+// calls at the interface level. (See also TRACEMF in lower-level code.)
+// Use -DTRACEMI2 for a terser format suitable for trace analysis.
+//
+// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
+// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
+// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
+// only (for assertions). This test ensures that (a) all callers properly mask
+// the namespace bits out before dereferencing a pointer (or else a core dump
+// occurs), and (b) all callers send "raw" (unmasked) addresses to
+// j__udy*Free*() calls.
+//
+// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
+
+#if (! (defined(JUDY1) || defined(JUDYL)))
+#error: One of -DJUDY1 or -DJUDYL must be specified.
+#endif
+
+#ifdef JUDY1
+#include "Judy1.h"
+#else
+#include "JudyL.h"
+#endif
+
+#include "JudyPrivate1L.h"
+
+// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
+// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
+// ignored), to trigger a fake malloc error when the number is exceeded. Note,
+// this code is always executed, not #ifdefd, because its virtually free.
+//
+// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
+// MAXINT, not zero, by default.
+
+Word_t j__uMaxWords = ~0UL;
+
+// This macro hides the faking of a malloc failure:
+//
+// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
+// complexity of first adding WordsNow, meaning the trigger point is not
+// exactly where you might assume, but it shouldnt matter.
+
+#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
+ (((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
+
+// Clear words starting at address:
+//
+// Note: Only use this for objects that care; in other cases, it doesnt
+// matter if the objects memory is pre-zeroed.
+
+#define ZEROWORDS(Addr,Words) \
+ { \
+ Word_t Words__ = (Words); \
+ PWord_t Addr__ = (PWord_t) (Addr); \
+ while (Words__--) *Addr__++ = 0UL; \
+ }
+
+#ifdef TRACEMI
+
+// TRACING SUPPORT:
+//
+// Note: For TRACEMI, use a format for address printing compatible with other
+// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
+// part on 64-bit systems.
+//
+// TBD: The trace macros need fixing for alternate address types.
+//
+// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
+// engine used.
+
+#include <stdio.h>
+
+static Word_t j__udyMemSequence = 0L; // event sequence number.
+
+#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
+#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
+#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
+#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
+
+#else
+
+#ifdef TRACEMI2
+
+#include <stdio.h>
+
+#define b_pw cJU_BYTESPERWORD
+
+#define TRACE_ALLOC5(a,b,c,d,e) \
+ (void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
+#define TRACE_FREE5( a,b,c,d,e) \
+ (void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
+#define TRACE_ALLOC6(a,b,c,d,e,f) \
+ (void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
+#define TRACE_FREE6( a,b,c,d,e,f) \
+ (void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
+
+static Word_t j__udyMemSequence = 0L; // event sequence number.
+
+#else
+
+#define TRACE_ALLOC5(a,b,c,d,e) // null.
+#define TRACE_FREE5( a,b,c,d,e) // null.
+#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
+#define TRACE_FREE6( a,b,c,d,e,f) // null.
+
+#endif // ! TRACEMI2
+#endif // ! TRACEMI
+
+
+// MALLOC NAMESPACE SUPPORT:
+
+#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
+#define MALLOCBITS 1
+#endif
+
+#ifdef MALLOCBITS
+#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
+#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
+
+#define MALLOCBITS_SET( Type,Addr) \
+ ((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
+#define MALLOCBITS_TEST(Type,Addr) \
+ assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
+ ((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
+#else
+#define MALLOCBITS_SET( Type,Addr) // null.
+#define MALLOCBITS_TEST(Type,Addr) // null.
+#endif
+
+
+// SAVE ERROR INFORMATION IN A Pjpm:
+//
+// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
+// errors. (TBD, non-zero invalid values are no longer returned from
+// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
+
+#define J__UDYSETALLOCERROR(Addr) \
+ { \
+ JU_ERRID(Pjpm) = __LINE__; \
+ if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
+ else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
+ return(0); \
+ }
+
+
+// ****************************************************************************
+// ALLOCATION FUNCTIONS:
+//
+// To help the compiler catch coding errors, each function returns a specific
+// object type.
+//
+// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
+// sizeof(Word_t) to indicate the type of memory allocation failure. Other
+// allocation functions convert this failure to a JU_ERRNO.
+
+
+// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
+// that is, without malloc namespace or root pointer type bits:
+
+FUNCTION Pjpm_t j__udyAllocJPM(void)
+{
+ Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
+ Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
+
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
+
+ if ((Word_t) Pjpm > sizeof(Word_t))
+ {
+ ZEROWORDS(Pjpm, Words);
+ Pjpm->jpm_TotalMemWords = Words;
+ }
+
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
+ Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
+ // MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
+ return(Pjpm);
+
+} // j__udyAllocJPM()
+
+
+FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
+ Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
+ Pjpm->jpm_TotalMemWords, Words);
+
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
+
+ if ((Word_t) PjblRaw > sizeof(Word_t))
+ {
+ ZEROWORDS(P_JBL(PjblRaw), Words);
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjblRaw); }
+
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjbl_t, PjblRaw);
+ return(PjblRaw);
+
+} // j__udyAllocJBL()
+
+
+FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
+ Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
+ Pjpm->jpm_TotalMemWords, Words);
+
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
+
+ if ((Word_t) PjbbRaw > sizeof(Word_t))
+ {
+ ZEROWORDS(P_JBB(PjbbRaw), Words);
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjbbRaw); }
+
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjbb_t, PjbbRaw);
+ return(PjbbRaw);
+
+} // j__udyAllocJBB()
+
+
+FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
+ Pjp_t PjpRaw;
+
+ PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjpRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjpRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
+ j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjp_t, PjpRaw);
+ return(PjpRaw);
+
+} // j__udyAllocJBBJP()
+
+
+FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
+ Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
+ Pjpm->jpm_TotalMemWords, Words);
+
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
+
+ if ((Word_t) PjbuRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjbuRaw); }
+
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjbu_t, PjbuRaw);
+ return(PjbuRaw);
+
+} // j__udyAllocJBU()
+
+
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
+
+FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL1()
+
+#endif // (JUDYL || (! JU_64BIT))
+
+
+FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL2()
+
+
+FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL3()
+
+
+#ifdef JU_64BIT
+
+FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL4()
+
+
+FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL5()
+
+
+FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL6()
+
+
+FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
+ Pjll_t PjllRaw;
+
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjllRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjllRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
+ return(PjllRaw);
+
+} // j__udyAllocJLL7()
+
+#endif // JU_64BIT
+
+
+// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
+// other j__udyAlloc*() functions, they are returned non-raw, that is, without
+// malloc namespace or root pointer type bits (the latter are added later by
+// the caller):
+
+FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
+{
+ Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
+ Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
+ j__udyMemSequence++, Pop1, Words, Pop1);
+ // MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
+ return(Pjlw);
+
+} // j__udyAllocJLW()
+
+
+FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
+ Pjlb_t PjlbRaw;
+
+ PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
+
+ if ((Word_t) PjlbRaw > sizeof(Word_t))
+ {
+ ZEROWORDS(P_JLB(PjlbRaw), Words);
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjlbRaw); }
+
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjlb_t, PjlbRaw);
+ return(PjlbRaw);
+
+} // j__udyAllocJLB1()
+
+
+#ifdef JUDYL
+
+FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
+ Pjv_t PjvRaw;
+
+ PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
+
+ if ((Word_t) PjvRaw > sizeof(Word_t))
+ {
+ Pjpm->jpm_TotalMemWords += Words;
+ }
+ else { J__UDYSETALLOCERROR(PjvRaw); }
+
+ TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
+ MALLOCBITS_SET(Pjv_t, PjvRaw);
+ return(PjvRaw);
+
+} // j__udyLAllocJV()
+
+#endif // JUDYL
+
+
+// ****************************************************************************
+// FREE FUNCTIONS:
+//
+// To help the compiler catch coding errors, each function takes a specific
+// object type to free.
+
+
+// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
+// bits present, that is, they must be stripped by the caller using P_JPM():
+
+FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
+{
+ Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
+
+ // MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
+ JudyFree((Pvoid_t) PjpmFree, Words);
+
+ if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
+
+// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
+// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
+// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
+// really will be 0, not cJU_LEAFW_MAXPOP1.
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
+ j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
+
+
+} // j__udyFreeJPM()
+
+
+FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
+
+ MALLOCBITS_TEST(Pjbl_t, Pjbl);
+ JudyFreeVirtual((Pvoid_t) Pjbl, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJBL()
+
+
+FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
+
+ MALLOCBITS_TEST(Pjbb_t, Pjbb);
+ JudyFreeVirtual((Pvoid_t) Pjbb, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJBB()
+
+
+FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
+
+ MALLOCBITS_TEST(Pjp_t, Pjp);
+ JudyFree((Pvoid_t) Pjp, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
+ j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJBBJP()
+
+
+FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
+
+ MALLOCBITS_TEST(Pjbu_t, Pjbu);
+ JudyFreeVirtual((Pvoid_t) Pjbu, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJBU()
+
+
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
+
+FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL1()
+
+#endif // (JUDYL || (! JU_64BIT))
+
+
+FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL2()
+
+
+FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL3()
+
+
+#ifdef JU_64BIT
+
+FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL4()
+
+
+FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL5()
+
+
+FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL6()
+
+
+FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjll_t, Pjll);
+ JudyFree((Pvoid_t) Pjll, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLL7()
+
+#endif // JU_64BIT
+
+
+// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
+// bits present, that is, they are stripped by P_JLW():
+
+FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
+
+ // MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
+ JudyFree((Pvoid_t) Pjlw, Words);
+
+ if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
+ j__udyMemSequence++, Pop1, Words, Pop1 - 1);
+
+
+} // j__udyFreeJLW()
+
+
+FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
+{
+ Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
+
+ MALLOCBITS_TEST(Pjlb_t, Pjlb);
+ JudyFree((Pvoid_t) Pjlb, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyFreeJLB1()
+
+
+#ifdef JUDYL
+
+FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
+{
+ Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
+
+ MALLOCBITS_TEST(Pjv_t, Pjv);
+ JudyFree((Pvoid_t) Pjv, Words);
+
+ Pjpm->jpm_TotalMemWords -= Words;
+
+ TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
+
+
+} // j__udyLFreeJV()
+
+#endif // JUDYL