// parse the heap to find valid objects and initialize metadata, then // add edges for every known root pointer and every known obj->obj ptr. HeapGraph makeHeapGraph(bool include_free) { HeapGraph g; PtrMap blocks; // parse the heap once to create a PtrMap for pointer filtering. Create // one node for every parsed block, including NativeData and AsyncFuncFrame // blocks. Only include free blocks if requested. MM().forEachHeader([&](Header* h) { if (h->kind() != HeaderKind::Free || include_free) { blocks.insert(h); // adds interval [h, h+h->size[ } }); blocks.prepare(); // initialize nodes by iterating over PtrMap's regions g.nodes.reserve(blocks.size()); blocks.iterate([&](const Header* h, size_t size) { g.nodes.push_back(HeapGraph::Node{h, -1, -1}); }); // find roots PtrFilter<RootMarker> rmark(g, blocks); scanRoots(rmark); // find heap->heap pointers for (size_t i = 0, n = g.nodes.size(); i < n; i++) { auto h = g.nodes[i].h; PtrFilter<ObjMarker> omark(g, blocks, h); scanHeader(h, omark); } g.nodes.shrink_to_fit(); g.ptrs.shrink_to_fit(); g.roots.shrink_to_fit(); return g; }
NEVER_INLINE void Marker::trace() { scanRoots(*this); while (!work_.empty()) { auto h = work_.back(); work_.pop_back(); scanHeader(h, *this); } }