Commit f03b3297 authored by Alexei Filippov's avatar Alexei Filippov Committed by Commit Bot

[heap profiler] Plumb samples through the protocol.

BUG=chromium:889545

Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ic00ffa9968cffaf2e20682e247747b5f7dc0f145
Reviewed-on: https://chromium-review.googlesource.com/c/1285394
Commit-Queue: Alexei Filippov <alph@chromium.org>
Reviewed-by: 's avatarDmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56874}
parent c4311e52
......@@ -1188,6 +1188,11 @@
"description": "Allocations size in bytes for the node excluding children.",
"type": "number"
},
{
"name": "id",
"description": "Node id. Ids are unique across all profiles collected between startSampling and stopSampling.",
"type": "integer"
},
{
"name": "children",
"description": "Child nodes.",
......@@ -1198,14 +1203,43 @@
}
]
},
{
"id": "SamplingHeapProfileSample",
"description": "A single sample from a sampling profile.",
"type": "object",
"properties": [
{
"name": "size",
"description": "Allocation size in bytes attributed to the sample.",
"type": "number"
},
{
"name": "nodeId",
"description": "Id of the corresponding profile tree node.",
"type": "integer"
},
{
"name": "ordinal",
"description": "Time-ordered sample ordinal number. It is unique across all profiles retrieved\nbetween startSampling and stopSampling.",
"type": "number"
}
]
},
{
"id": "SamplingHeapProfile",
"description": "Profile.",
"description": "Sampling profile.",
"type": "object",
"properties": [
{
"name": "head",
"$ref": "SamplingHeapProfileNode"
},
{
"name": "samples",
"type": "array",
"items": {
"$ref": "SamplingHeapProfileSample"
}
}
]
}
......
......@@ -556,13 +556,27 @@ experimental domain HeapProfiler
Runtime.CallFrame callFrame
# Allocations size in bytes for the node excluding children.
number selfSize
# Node id. Ids are unique across all profiles collected between startSampling and stopSampling.
integer id
# Child nodes.
array of SamplingHeapProfileNode children
# Profile.
# A single sample from a sampling profile.
type SamplingHeapProfileSample extends object
properties
# Allocation size in bytes attributed to the sample.
number size
# Id of the corresponding profile tree node.
integer nodeId
# Time-ordered sample ordinal number. It is unique across all profiles retrieved
# between startSampling and stopSampling.
number ordinal
# Sampling profile.
type SamplingHeapProfile extends object
properties
SamplingHeapProfileNode head
array of SamplingHeapProfileSample samples
# Enables console to refer to the node with given id via $x (see Command Line API for more details
# $x functions).
......
......@@ -357,6 +357,7 @@ buildSampingHeapProfileNode(v8::Isolate* isolate,
.setCallFrame(std::move(callFrame))
.setSelfSize(selfSize)
.setChildren(std::move(children))
.setId(node->node_id)
.build();
return result;
}
......@@ -376,15 +377,25 @@ Response V8HeapProfilerAgentImpl::stopSampling(
Response V8HeapProfilerAgentImpl::getSamplingProfile(
std::unique_ptr<protocol::HeapProfiler::SamplingHeapProfile>* profile) {
v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
v8::HandleScope scope(
m_isolate); // v8::AllocationProfile contains Local handles.
// Need a scope as v8::AllocationProfile contains Local handles.
v8::HandleScope scope(m_isolate);
std::unique_ptr<v8::AllocationProfile> v8Profile(
profiler->GetAllocationProfile());
if (!v8Profile)
return Response::Error("V8 sampling heap profiler was not started.");
v8::AllocationProfile::Node* root = v8Profile->GetRootNode();
auto samples = protocol::Array<
protocol::HeapProfiler::SamplingHeapProfileSample>::create();
for (const auto& sample : v8Profile->GetSamples()) {
samples->addItem(protocol::HeapProfiler::SamplingHeapProfileSample::create()
.setSize(sample.size * sample.count)
.setNodeId(sample.node_id)
.setOrdinal(static_cast<double>(sample.sample_id))
.build());
}
*profile = protocol::HeapProfiler::SamplingHeapProfile::create()
.setHead(buildSampingHeapProfileNode(m_isolate, root))
.setSamples(std::move(samples))
.build();
return Response::OK();
}
......
......@@ -4,4 +4,5 @@ Allocated size is zero in the beginning: true
Allocated size is more than 100KB after a chunk is allocated: true
Allocated size increased after one more chunk is allocated: true
Allocated size did not change after stopping: true
Sample found: true
Successfully finished
......@@ -38,6 +38,11 @@
const size4 = nodeSize(profile4.result.profile.head);
InspectorTest.log('Allocated size did not change after stopping:', size4 === size3);
const sample = profile4.result.profile.samples.find(s => s.size > 400000);
const hasSample = hasNode(n => n.id === sample.nodeId && n.callFrame.functionName === 'allocateChunk',
profile4.result.profile.head);
InspectorTest.log('Sample found: ' + hasSample);
InspectorTest.log('Successfully finished');
InspectorTest.completeTest();
......@@ -45,4 +50,8 @@
return node.children.reduce((res, child) => res + nodeSize(child),
node.callFrame.functionName === 'allocateChunk' ? node.selfSize : 0);
}
function hasNode(predicate, node) {
return predicate(node) || node.children.some(hasNode.bind(null, predicate));
}
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment