Insert that context together with the address and size into an AllocationRegister by calling Insert().

When memory is freed, remove it from the register with Remove().

On memory dump, collect the allocations from the register, call ExportHeapDump(), and add the generated heap dump to the memory dump.

An allocator can skip step 2 and 3 if it is able to store the context itself, and if it is able to enumerate all allocations for step 4.

When heap profiling is enabled (the --enable-heap-profiling flag is passed), the memory dump manager calls OnHeapProfilingEnabled() on every MemoryDumpProvider as early as possible, so allocators can start recording allocations. This should be done even when tracing has not been started, because these allocations might still be around when a heap dump happens during tracing.

Context Tracker

The AllocationContextTracker is a thread-local object. Its main purpose is to keep track of a pseudo stack of trace events. Chrome has been instrumented with lots of TRACE_EVENT macros. These trace events push their name to a thread-local stack when they go into scope, and pop when they go out of scope, if all of the following conditions have been met:

A trace is being recorded.

The category of the event is enabled in the trace config.

Heap profiling is enabled (with the --enable-heap-profiling flag).

This means that allocations that occur before tracing is started will not have backtrace information in their context.

A thread-local instance of the context tracker is initialized lazily when it is first accessed. This might be because a trace event pushed or popped, or because GetContextSnapshot() was called when an allocation occurred.

AllocationContext is what is used to group and break down allocations. Currently AllocationContext has the following fields:

Backtrace: filled by the context tracker, obtained from the thread-local pseudo stack.

Type name: to be filled in at a point where the type of a pointer is known, set to [unknown] by default.

It is possible to modify this context after insertion into the register, for instance to set the type name if it was not known at the time of allocation.

Allocation Register

The AllocationRegister is a hash table specialized for storing (size, AllocationContext) pairs by address. It has been optimized for Chrome's typical number of unfreed allocations, and it is backed by mmap memory directly so there are no reentrancy issues when using it to record malloc allocations.

The allocation register is threading-agnostic. Access must be synchronised properly.

Heap Dump Writer

Dumping every single allocation in the allocation register straight into the trace log is not an option due to the sheer volume (~300k unfreed allocations). The role of the ExportHeapDump() function is to group allocations, striking a balance between trace log size and detail.

See the Heap Dump Format document for more details about the structure of the heap dump in the trace log.

Instrumenting an Allocator

Below is an example of adding heap profiling support to an allocator that has an existing memory dump provider.