Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Unified Diff: runtime/observatory/lib/src/cpu_profile/cpu_profile.dart

Issue 2771293003: Resubmission of native memory allocation info surfacing in Observatory. Fixed crashing tests and st… (Closed)
Patch Set: Added page to Observatory to display native memory allocation information. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/observatory/lib/src/app/page.dart ('k') | runtime/observatory/lib/src/elements/class_ref.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
diff --git a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
index 1c6d9801228b0a47cb4b21762f6c3e80252521f2..521fc192d323d6dac0914164bc65818e5058659d 100644
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ b/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
@@ -8,6 +8,8 @@ abstract class CallTreeNode<NodeT extends M.CallTreeNode>
implements M.CallTreeNode {
final List<NodeT> children;
final int count;
+ final int inclusiveNativeAllocations;
+ final int exclusiveNativeAllocations;
double get percentage => _percentage;
double _percentage = 0.0;
final Set<String> attributes = new Set<String>();
@@ -16,7 +18,8 @@ abstract class CallTreeNode<NodeT extends M.CallTreeNode>
Object get profileData;
String get name;
- CallTreeNode(this.children, this.count);
+ CallTreeNode(this.children, this.count, this.inclusiveNativeAllocations,
+ this.exclusiveNativeAllocations);
}
class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode>
@@ -28,8 +31,10 @@ class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode>
String get name => profileCode.code.name;
final Set<String> attributes = new Set<String>();
- CodeCallTreeNode(this.profileCode, int count)
- : super(new List<CodeCallTreeNode>(), count) {
+ CodeCallTreeNode(this.profileCode, int count, int inclusiveNativeAllocations,
+ int exclusiveNativeAllocations)
+ : super(new List<CodeCallTreeNode>(), count, inclusiveNativeAllocations,
+ exclusiveNativeAllocations) {
attributes.addAll(profileCode.attributes);
}
}
@@ -44,13 +49,23 @@ class CallTree<NodeT extends CallTreeNode> {
class CodeCallTree extends CallTree<CodeCallTreeNode>
implements M.CodeCallTree {
CodeCallTree(bool inclusive, CodeCallTreeNode root) : super(inclusive, root) {
- _setCodePercentage(null, root);
+ if ((root.inclusiveNativeAllocations != null) &&
+ (root.inclusiveNativeAllocations != 0)) {
+ _setCodeMemoryPercentage(null, root);
+ } else {
+ _setCodePercentage(null, root);
+ }
}
CodeCallTree filtered(CallTreeNodeFilter filter) {
var treeFilter = new _FilteredCodeCallTreeBuilder(filter, this);
treeFilter.build();
- _setCodePercentage(null, treeFilter.filtered.root);
+ if ((treeFilter.filtered.root.inclusiveNativeAllocations != null) &&
+ (treeFilter.filtered.root.inclusiveNativeAllocations != 0)) {
+ _setCodeMemoryPercentage(null, treeFilter.filtered.root);
+ } else {
+ _setCodePercentage(null, treeFilter.filtered.root);
+ }
return treeFilter.filtered;
}
@@ -72,6 +87,25 @@ class CodeCallTree extends CallTree<CodeCallTreeNode>
}
}
+ _setCodeMemoryPercentage(CodeCallTreeNode parent, CodeCallTreeNode node) {
+ assert(node != null);
+ var parentPercentage = 1.0;
+ var parentMemory = node.inclusiveNativeAllocations;
+ if (parent != null) {
+ parentPercentage = parent._percentage;
+ parentMemory = parent.inclusiveNativeAllocations;
+ }
+ if (inclusive) {
+ node._percentage =
+ parentPercentage * (node.inclusiveNativeAllocations / parentMemory);
+ } else {
+ node._percentage = (node.inclusiveNativeAllocations / parentMemory);
+ }
+ for (var child in node.children) {
+ _setCodeMemoryPercentage(node, child);
+ }
+ }
+
_recordCallerAndCalleesInner(
CodeCallTreeNode caller, CodeCallTreeNode callee) {
if (caller != null) {
@@ -106,8 +140,10 @@ class FunctionCallTreeNode extends CallTreeNode {
String get name => M.getFunctionFullName(profileFunction.function);
Object get profileData => profileFunction;
- FunctionCallTreeNode(this.profileFunction, int count)
- : super(new List<FunctionCallTreeNode>(), count) {
+ FunctionCallTreeNode(this.profileFunction, int count,
+ inclusiveNativeAllocations, exclusiveNativeAllocations)
+ : super(new List<FunctionCallTreeNode>(), count,
+ inclusiveNativeAllocations, exclusiveNativeAllocations) {
profileFunction._addKindBasedAttributes(attributes);
}
@@ -290,10 +326,14 @@ class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder {
new FunctionCallTree(
tree.inclusive,
new FunctionCallTreeNode(
- tree.root.profileData, tree.root.count)));
+ tree.root.profileData,
+ tree.root.count,
+ tree.root.inclusiveNativeAllocations,
+ tree.root.exclusiveNativeAllocations)));
_copyNode(FunctionCallTreeNode node) {
- return new FunctionCallTreeNode(node.profileData, node.count);
+ return new FunctionCallTreeNode(node.profileData, node.count,
+ node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
}
}
@@ -302,24 +342,40 @@ class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder {
: super(
filter,
tree,
- new CodeCallTree(tree.inclusive,
- new CodeCallTreeNode(tree.root.profileData, tree.root.count)));
+ new CodeCallTree(
+ tree.inclusive,
+ new CodeCallTreeNode(
+ tree.root.profileData,
+ tree.root.count,
+ tree.root.inclusiveNativeAllocations,
+ tree.root.exclusiveNativeAllocations)));
_copyNode(CodeCallTreeNode node) {
- return new CodeCallTreeNode(node.profileData, node.count);
+ return new CodeCallTreeNode(node.profileData, node.count,
+ node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
}
}
class FunctionCallTree extends CallTree implements M.FunctionCallTree {
FunctionCallTree(bool inclusive, FunctionCallTreeNode root)
: super(inclusive, root) {
- _setFunctionPercentage(null, root);
+ if ((root.inclusiveNativeAllocations != null) &&
+ (root.inclusiveNativeAllocations != 0)) {
+ _setFunctionMemoryPercentage(null, root);
+ } else {
+ _setFunctionPercentage(null, root);
+ }
}
FunctionCallTree filtered(CallTreeNodeFilter filter) {
var treeFilter = new _FilteredFunctionCallTreeBuilder(filter, this);
treeFilter.build();
- _setFunctionPercentage(null, treeFilter.filtered.root);
+ if ((treeFilter.filtered.root.inclusiveNativeAllocations != null) &&
+ (treeFilter.filtered.root.inclusiveNativeAllocations != 0)) {
+ _setFunctionMemoryPercentage(null, treeFilter.filtered.root);
+ } else {
+ _setFunctionPercentage(null, treeFilter.filtered.root);
+ }
return treeFilter.filtered;
}
@@ -342,6 +398,26 @@ class FunctionCallTree extends CallTree implements M.FunctionCallTree {
}
}
+ void _setFunctionMemoryPercentage(
+ FunctionCallTreeNode parent, FunctionCallTreeNode node) {
+ assert(node != null);
+ var parentPercentage = 1.0;
+ var parentMemory = node.inclusiveNativeAllocations;
+ if (parent != null) {
+ parentPercentage = parent._percentage;
+ parentMemory = parent.inclusiveNativeAllocations;
+ }
+ if (inclusive) {
+ node._percentage =
+ parentPercentage * (node.inclusiveNativeAllocations / parentMemory);
+ } else {
+ node._percentage = (node.inclusiveNativeAllocations / parentMemory);
+ }
+ for (var child in node.children) {
+ _setFunctionMemoryPercentage(node, child);
+ }
+ }
+
_markFunctionCallsInner(
FunctionCallTreeNode caller, FunctionCallTreeNode callee) {
if (caller != null) {
@@ -382,6 +458,8 @@ class ProfileCode implements M.ProfileCode {
final Code code;
int exclusiveTicks;
int inclusiveTicks;
+ int exclusiveNativeAllocations;
+ int inclusiveNativeAllocations;
double normalizedExclusiveTicks = 0.0;
double normalizedInclusiveTicks = 0.0;
final addressTicks = new Map<int, CodeTick>();
@@ -458,6 +536,14 @@ class ProfileCode implements M.ProfileCode {
_processTicks(ticks);
}
+ if (data.containsKey('exclusiveNativeAllocations') &&
+ data.containsKey('inclusiveNativeAllocations')) {
+ exclusiveNativeAllocations =
+ int.parse(data['exclusiveNativeAllocations']);
+ inclusiveNativeAllocations =
+ int.parse(data['inclusiveNativeAllocations']);
+ }
+
formattedExclusivePercent =
Utils.formatPercent(exclusiveTicks, profile.sampleCount);
@@ -509,6 +595,10 @@ class ProfileFunction implements M.ProfileFunction {
double normalizedExclusiveTicks = 0.0;
double normalizedInclusiveTicks = 0.0;
+ // Native allocations:
+ int exclusiveNativeAllocations = 0;
+ int inclusiveNativeAllocations = 0;
+
String formattedInclusiveTicks = '';
String formattedExclusiveTicks = '';
String formattedExclusivePercent = '';
@@ -606,6 +696,14 @@ class ProfileFunction implements M.ProfileFunction {
normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount;
normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount;
+ if (data.containsKey('exclusiveNativeAllocations') &&
+ data.containsKey('inclusiveNativeAllocations')) {
+ exclusiveNativeAllocations =
+ int.parse(data['exclusiveNativeAllocations']);
+ inclusiveNativeAllocations =
+ int.parse(data['inclusiveNativeAllocations']);
+ }
+
formattedExclusivePercent =
Utils.formatPercent(exclusiveTicks, profile.sampleCount);
@@ -710,8 +808,8 @@ class CpuProfile extends M.SampleProfile {
_builtFunctionCalls = false;
}
- Future load(Isolate isolate, ServiceMap profile) async {
- await loadProgress(isolate, profile).last;
+ Future load(ServiceObjectOwner owner, ServiceMap profile) async {
+ await loadProgress(owner, profile).last;
}
static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
@@ -720,7 +818,7 @@ class CpuProfile extends M.SampleProfile {
return completer.future;
}
- Stream<double> loadProgress(Isolate isolate, ServiceMap profile) {
+ Stream<double> loadProgress(ServiceObjectOwner owner, ServiceMap profile) {
var progress = new StreamController<double>.broadcast();
(() async {
@@ -742,12 +840,14 @@ class CpuProfile extends M.SampleProfile {
try {
clear();
progress.add(0.0);
- if ((isolate == null) || (profile == null)) {
+ if (profile == null) {
return;
}
- this.isolate = isolate;
- isolate.resetCachedProfileData();
+ if ((owner != null) && (owner is Isolate)) {
+ isolate = owner as Isolate;
+ isolate.resetCachedProfileData();
+ }
sampleCount = profile['sampleCount'];
samplePeriod = profile['samplePeriod'];
@@ -824,8 +924,13 @@ class CpuProfile extends M.SampleProfile {
var count = data[_dataCursor++];
// Child node count.
var children = data[_dataCursor++];
+ // Inclusive native allocations.
+ var inclusiveNativeAllocations = data[_dataCursor++];
+ // Exclusive native allocations.
+ var exclusiveNativeAllocations = data[_dataCursor++];
// Create node.
- var node = new CodeCallTreeNode(code, count);
+ var node = new CodeCallTreeNode(
+ code, count, inclusiveNativeAllocations, exclusiveNativeAllocations);
node.children.length = children;
return node;
}
@@ -894,8 +999,13 @@ class CpuProfile extends M.SampleProfile {
var function = functions[index];
// Counter.
var count = data[_dataCursor++];
+ // Inclusive native allocations.
+ var inclusiveNativeAllocations = data[_dataCursor++];
+ // Exclusive native allocations.
+ var exclusiveNativeAllocations = data[_dataCursor++];
// Create node.
- var node = new FunctionCallTreeNode(function, count);
+ var node = new FunctionCallTreeNode(function, count,
+ inclusiveNativeAllocations, exclusiveNativeAllocations);
// Number of code index / count pairs.
var codeCount = data[_dataCursor++];
node.codes.length = codeCount;
« no previous file with comments | « runtime/observatory/lib/src/app/page.dart ('k') | runtime/observatory/lib/src/elements/class_ref.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698