Array createPhpEdge(HeapGraphContextPtr hgptr, int index) { auto ptr = hgptr->hg.ptrs[index]; auto cptr = hgptr->cptrs[index]; auto ptr_arr = make_map_array( s_index, Variant(index), s_kind, Variant(getEdgeKindName(ptr.kind)), s_from, Variant(ptr.from), s_to, Variant(ptr.to), s_seat, (ptr.seat == nullptr ? init_null() : Variant(ptr.seat)), s_name, Variant(cptr.edgename) ); return ptr_arr; }
Array createPhpEdge(HeapGraphContextPtr hgptr, int index) { auto ptr = hgptr->hg.ptrs[index]; auto cptr = hgptr->cptrs[index]; auto ptr_arr = make_map_array( s_index, Variant(index), s_kind, Variant(getEdgeKindName(ptr.ptr_kind)), s_from, Variant(ptr.from), s_to, Variant(ptr.to), s_seat, Variant(root_kind_names[(unsigned)ptr.root_kind]), s_name, Variant(cptr.edgename) ); return ptr_arr; }
std::string getNodesConnectionName( const HeapGraph& g, int ptr, int from, int to ) { // For non Ambiguous pointers, try to drill down and resolve the edge name if (from != -1 && to != -1 && g.ptrs[ptr].kind != HeapGraph::Ambiguous) { auto h = g.nodes[from].h; auto th = g.nodes[to].h; const void* target_ptr = &th->obj_; ObjectData* obj; std::string conn_name; switch (h->kind()) { // Known generalized cases that don't really need pointer kind case HeaderKind::Struct: // Not implemented yet case HeaderKind::Mixed: return "ArrayKeyValue"; // Obvious cases that do not need pointer type case HeaderKind::AwaitAllWH: case HeaderKind::WaitHandle: case HeaderKind::ResumableObj: case HeaderKind::Pair: case HeaderKind::ResumableFrame: case HeaderKind::Set: case HeaderKind::ImmSet: case HeaderKind::Vector: case HeaderKind::ImmVector: case HeaderKind::Packed: return ""; // Explicit cases that have explicit pointer name case HeaderKind::Ref: return ""; case HeaderKind::Map: case HeaderKind::ImmMap: case HeaderKind::Object: obj = const_cast<ObjectData*>(&h->obj_); //auto obj_tv = make_tv<KindOfObject>(obj); conn_name = getObjectConnectionName(obj, target_ptr); if (!conn_name.empty()) { return conn_name; } // Fallback to pointer kind break; // Unknown drilldown cases that need pointer type case HeaderKind::Empty: case HeaderKind::Apc: case HeaderKind::Globals: case HeaderKind::Proxy: case HeaderKind::String: case HeaderKind::Resource: case HeaderKind::BigMalloc: case HeaderKind::SmallMalloc: case HeaderKind::NativeData: case HeaderKind::Free: case HeaderKind::BigObj: case HeaderKind::Hole: // Fallback to pointer kind break; } } else if (from == -1 && to != -1) { auto seat = g.ptrs[ptr].seat; std::string conn_name; if (seat != nullptr) { conn_name = std::string(seat); } if (!conn_name.empty()) { return conn_name; } } return getEdgeKindName(g.ptrs[ptr].kind); }