Background context: go/memory-infra
Summary:
Introduce a new api
MemoryAllocatorDump::CopyPropertyFrom(const char* property_name, const MemoryAllocatorDump& other)
Discussion from emails:
ssid:
The net dump provider has url_requests and a pool of sessions. url_requests can share sessions in any way.
So, lets take a case:
url_request1 -> session1, session2
url_request2 -> session1, session3
Now, while dumping each session has a complex set of operations to calculate size. So each session dumps its usage into an independent object: "net/session1" -> size.
"net/sessions/1" -> 10MB
"net/sessions/2" -> 10MB
"net/sessions/3" -> 10MB
Now I think it is better if we attribute the memory into the url_request (shared ones will just split by 2).
What I think effective size and size should look like is:
net/ 30MB <whatevr>
-> sessions 0 30MB
-> session1 0 -> 10MB
-> session2 0 -> 10MB
-> session3 0 -> 10MB
-> url_request1/ 15MB 10MB
-> session1 5MB 10MB
-> session2 10MB 10MB
-> url_request2/ 15MB 10MB
-> session1 5MB 10MB
-> session3 10MB 10MB
This all looks good. But the issue is this complex calculation that needs to be done for each session that cannot be repeated multiple times. So, we only add the size to the dump "net/sessions/session1". We do not add size to the dump "net/url_request1/session1".
Though we add the correct ownership edges to the dumps, we cannot assume the size of "net/url_request1/session1" from the size of the owning dump (source) without specifying. But in reality we know that the size of these two dumps is the same.
So this is what is seen in the actual UI:
net/ 30MB <whatevr>
-> sessions 30MB 30MB
-> session1 10MB -> 10MB
-> session2 10MB -> 10MB
-> session3 10MB -> 10MB
-> url_request1/
-> session1
-> session2
-> url_request2/
-> session1
-> session3
The arrows show ownership, but the memory is just shown under sessions.
So what I am looking for here is a way to tell that these are exactly same dumps:
MemoryAllocatorDump::AddOwnershipEdgeAndInheritSize(source, target) {
target.size = source.size;
AddOwnershipEdge(source, target);
}
Primiano:
Specifically, by looking at the various examples it looks that size inheritance works only the other way round, i.e. if A has size=5 and A owns -> B, then B has an inferred size of 5.
But what we want here is the other way round, we want to say: A owns B, which has size=5, but we don't know the size of A. This one doesn't propagate.
Having said this, I think there are two ways we could get around this:
A. Solve this is in the UI: Adding a special constant so you can say mad.AddScalar(kNameSize, kUnitsBytes, kInheritAll), which will likely cause chrome to generate a dump of with size=-1 and add the logic to the UI that understand that -1 is special.
B. Solve this in chrome: Add an API of the form:
MemoryAllocatorDump::CopyPropertyFrom(const char* property_name, const MemoryAllocatorDump& other)
A is ideal and conceptually cleaner, however require touch a very hard part of the UI code (the graph calculation) and I have no idea how much that would take in terms of eng hours.
B is a bit more hacky (but okay as long as we keep the value internally and don't expose the raw value but only a copy method) but can be done in a very simple CL.
So if we do B this would look like:
OnURLRequestDump(pmd) {
string session_dump_name = ...;
auto* session_mad = pmd.GetAllocatorDump(session_dump_name);
if (session_mad == nullptr) {
// Do the expensive session calculation (only once)
CreateExpensiveSessionMAD(session_dump_name);
session_mad = pmd.GetAllocatorDump(session_dump_name)
}
auto urlreq_sess_mad = pmd.CreateAllocatorDump("net/url_req1/session2");
urlreq_sess_mad.CopyPropertyFrom(kNameSize, session_mad);
pmd.AddAllocatorEdge(urlreq_sess_mad, session_mad);
}