Skip to main content

Module allocator

Module allocator 

Source
Expand description

C ABI allocator compatibility — xmlMemSetup, xmlMemGet, xmlMalloc, xmlFree, etc. (§58).

This module implements the complete memory hook system exposed by libxml2:

  • Global allocator function pointers (malloc, realloc, free, strdup)
  • xmlMemSetup() / xmlMemGet() — set/get allocator hooks
  • xmlGcMemSetup() / xmlGcMemGet() — GC-aware allocator hooks (wrappers)
  • xmlMalloc() / xmlMallocAtomic() / xmlRealloc() / xmlFree() / xmlMemStrdup()
  • xmlMemUsed() / xmlMemBlocks() — allocation tracking
  • xmlMemDisplay() / xmlMemShow() — debugging output

§Phase 1 status

Complete — all allocator APIs are implemented; state lives in the five exported function-pointer variables exactly as upstream (globals.c), giving xmlMemSetup and direct xmlMalloc = custom assignment one shared override mechanism (R-000176).

§Safety

Allocator hooks are unsafe because they operate on raw pointers and are called from C code. Every public function documents its safety contract.

§Upstream contract

The parity target is libxml2 2.15.3 (SRC-LIBXML2-2.15.0-XMLMEMORY-C: oracle/historical/src/libxml2-2.15.0/xmlmemory.c) plus the allocator globals of globals.c. The 5 allocator entry points (xmlMalloc, xmlMallocAtomic, xmlRealloc, xmlFree, xmlMemStrdup) are exported as DATA function-pointer globals matching the upstream XMLPUBVAR declarations (R-000162).

§Conceptual behavior

This module implements the complete libxml2 memory-hook system: swappable allocator hooks via xmlMemSetup/xmlMemGet (and the GC aliases), a per-block metadata registry mirroring upstream xmlmemory.cs debug block table, and the tracking/debug entry points built on it (xmlMemUsed, xmlMemBlocks, xmlMemSize, xmlMemDisplay*, xmlMemShow, xmlMemoryDump).

§Ownership & safety invariants

Every pointer returned by an xml* allocator must be freed with xmlFree (OWNERSHIP_ATLAS section 1). The block registry records ptr -> (size, file, line) so xmlMemSize and the dumps are exact, and xmlMemUsed/xmlMemBlocks track live totals. xmlMemSetup custom allocators bypass the registry (counters only), matching upstreams debug-allocator-only contract. xmlFree on a foreign/unknown pointer is a registry-removal no-op instead of upstreams corruption — a documented safe divergence (OWNERSHIP_ATLAS section 8).

§Historical quirks & epochs

R-000131 (11.1-J): the legacy allocator surface was simplified before the per-block registry existed — xmlMemSize returned 0 and the *Loc variants ignored file/line. Since the 11.1-J fix the registry is the source of truth; xmlMemShows upstream most-recent ordering is still not reproduced (documented divergence). R-000133 (11.1-H): the legacy names (xmlMemMalloc/xmlMemFree/xmlMemRealloc/xmlMemoryStrdup) were declared-but-unexported and had to be implemented for the honest-header rule.

§Deliberate oddities

xmlMemSetup/direct variable assignment bypass the accounting registry (deliberate: upstream’s block table exists only in the debug allocator). The default allocator routes through Rust’s global allocator but the five exported variables (xmlMalloc, xmlMallocAtomic, xmlRealloc, xmlFree, xmlMemStrdup) default to the *Default accounting bodies, so downstream xmlMemSetup swaps behave identically to upstream. The exported variables are the single source of truth (R-000176, 11.1-Z.2): xmlMemSetup assigns them and every internal allocation reads them through the *Impl indirection, exactly like upstream internal xmlMalloc(...) calls.

§Proving courts

ABI-DATA, ALLOCATOR, GLOBAL-STATE and THREADING court families; the allocator probes (tools/abi/*_probe.py + courts/suites/data-abi/*) compile the same C probe against the oracle DSO and the candidate and require byte-identical output; the DSO-LOADER court resolves every exported symbol from the built DSO.

§Tempting simplifications that would break parity

A tempting simplification is to drop the per-block registry and return 0 from xmlMemSize — that is exactly the pre-R-000131 state and would break the ALLOCATOR probes, xmlMemUsed exactness, and every downstream allocator-debugging consumer. Another tempting shortcut is exporting the allocator entry points as plain functions — upstream exports them as data function pointers, so the allocator-override mechanism (xmlMalloc = custom) could not link (R-000162 lesson).

Statics§

xmlFree
xmlFreeFunc xmlFree — the free hook.
xmlMalloc
xmlMallocFunc xmlMalloc — the malloc hook (default: xmlMallocDefault).
xmlMallocAtomic
xmlMallocFunc xmlMallocAtomic — the atomic-malloc hook.
xmlMemStrdup
xmlStrdupFunc xmlMemStrdup — the strdup hook.
xmlRealloc
xmlReallocFunc xmlRealloc — the realloc hook.

Functions§

xmlCleanupMemory
Clean up the memory layer.
xmlFreeImpl
Free through the exported xmlFree variable.
xmlGcMemGet
Get GC-aware memory allocator functions (upstream xmlmemory.h).
xmlGcMemSetup
Set GC-aware memory allocator functions (upstream xmlmemory.h).
xmlInitMemory
Initialize the memory layer with debugging support.
xmlMallocAtomicImpl
Allocate through the exported xmlMallocAtomic variable.
xmlMallocAtomicLoc
Allocate zeroed memory, recording the allocation site (upstream xmlmemory.h).
xmlMallocAtomicZero
Allocate zero-initialized memory (atomic variant).
xmlMallocImpl
Allocate memory through the exported xmlMalloc variable.
xmlMallocLoc
Allocate memory, recording the allocation site (upstream xmlmemory.h).
xmlMallocZero
Allocate zero-initialized memory.
xmlMemBlocks
Return the current number of allocated blocks (approximate).
xmlMemDisplay
Display memory allocation information to a file.
xmlMemDisplayLast
Display a limited amount of memory debug information (upstream xmlmemory.h).
xmlMemFree
Free memory (legacy name; same contract as xmlFree).
xmlMemGet
Get the current memory allocator functions (upstream xmlmemory.h).
xmlMemMalloc
Allocate memory (legacy name; same contract as xmlMalloc).
xmlMemRealloc
Reallocate memory (legacy name; same contract as xmlRealloc).
xmlMemSetup
Set custom memory allocator functions (upstream xmlmemory.h).
xmlMemShow
Show memory allocation information.
xmlMemSize
Return the size of an allocated block (upstream xmlmemory.h).
xmlMemStrdupImpl
Duplicate a C string through the exported xmlMemStrdup variable.
xmlMemStrdupLoc
Duplicate a string, recording the allocation site (upstream xmlmemory.h).
xmlMemUsed
Return the total amount of memory currently allocated (approximate).
xmlMemoryDump
Dump memory allocation statistics (upstream xmlmemory.h).
xmlMemoryStrdup
Duplicate a string (legacy name; same contract as xmlMemStrdup).
xmlReallocImpl
Reallocate through the exported xmlRealloc variable.
xmlReallocLoc
Reallocate memory, recording the allocation site (upstream xmlmemory.h).
xmlReallocZero
Reallocate and zero-initialize the new portion.