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

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

Issue 2999763002: Clear analyzer warning on Observatory (Closed)
Patch Set: Created 3 years, 4 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
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
deleted file mode 100644
index 76e1a2680f6bdbbaad8e09abe52ad3703e5bfea0..0000000000000000000000000000000000000000
--- a/runtime/observatory/lib/src/cpu_profile/cpu_profile.dart
+++ /dev/null
@@ -1,1090 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of cpu_profiler;
-
-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>();
-
- // Either a ProfileCode or a ProfileFunction.
- Object get profileData;
- String get name;
-
- CallTreeNode(this.children, this.count, this.inclusiveNativeAllocations,
- this.exclusiveNativeAllocations);
-}
-
-class CodeCallTreeNode extends CallTreeNode<CodeCallTreeNode>
- implements M.CodeCallTreeNode {
- final ProfileCode profileCode;
-
- Object get profileData => profileCode;
-
- String get name => profileCode.code.name;
-
- final Set<String> attributes = new Set<String>();
- CodeCallTreeNode(this.profileCode, int count, int inclusiveNativeAllocations,
- int exclusiveNativeAllocations)
- : super(new List<CodeCallTreeNode>(), count, inclusiveNativeAllocations,
- exclusiveNativeAllocations) {
- attributes.addAll(profileCode.attributes);
- }
-}
-
-class CallTree<NodeT extends CallTreeNode> {
- final bool inclusive;
- final NodeT root;
-
- CallTree(this.inclusive, this.root);
-}
-
-class CodeCallTree extends CallTree<CodeCallTreeNode>
- implements M.CodeCallTree {
- CodeCallTree(bool inclusive, CodeCallTreeNode root) : super(inclusive, 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();
- 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;
- }
-
- _setCodePercentage(CodeCallTreeNode parent, CodeCallTreeNode node) {
- assert(node != null);
- var parentPercentage = 1.0;
- var parentCount = node.count;
- if (parent != null) {
- parentPercentage = parent._percentage;
- parentCount = parent.count;
- }
- if (inclusive) {
- node._percentage = parentPercentage * (node.count / parentCount);
- } else {
- node._percentage = (node.count / parentCount);
- }
- for (var child in node.children) {
- _setCodePercentage(node, child);
- }
- }
-
- _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);
- }
- node.children.sort((a, b) {
- return b.inclusiveNativeAllocations - a.inclusiveNativeAllocations;
- });
- }
-
- _recordCallerAndCalleesInner(
- CodeCallTreeNode caller, CodeCallTreeNode callee) {
- if (caller != null) {
- caller.profileCode._recordCallee(callee.profileCode, callee.count);
- callee.profileCode._recordCaller(caller.profileCode, caller.count);
- }
-
- for (var child in callee.children) {
- _recordCallerAndCalleesInner(callee, child);
- }
- }
-
- _recordCallerAndCallees() {
- for (var child in root.children) {
- _recordCallerAndCalleesInner(null, child);
- }
- }
-}
-
-class FunctionCallTreeNodeCode {
- final ProfileCode code;
- final int ticks;
- FunctionCallTreeNodeCode(this.code, this.ticks);
-}
-
-class FunctionCallTreeNode extends CallTreeNode {
- final ProfileFunction profileFunction;
- final codes = new List<FunctionCallTreeNodeCode>();
- int _totalCodeTicks = 0;
- int get totalCodesTicks => _totalCodeTicks;
-
- String get name => M.getFunctionFullName(profileFunction.function);
- Object get profileData => profileFunction;
-
- FunctionCallTreeNode(this.profileFunction, int count,
- inclusiveNativeAllocations, exclusiveNativeAllocations)
- : super(new List<FunctionCallTreeNode>(), count,
- inclusiveNativeAllocations, exclusiveNativeAllocations) {
- profileFunction._addKindBasedAttributes(attributes);
- }
-
- // Does this function have an optimized version of itself?
- bool hasOptimizedCode() {
- for (var nodeCode in codes) {
- var profileCode = nodeCode.code;
- if (!profileCode.code.isDartCode) {
- continue;
- }
- if (profileCode.code.function != profileFunction.function) {
- continue;
- }
- if (profileCode.code.isOptimized) {
- return true;
- }
- }
- return false;
- }
-
- // Does this function have an unoptimized version of itself?
- bool hasUnoptimizedCode() {
- for (var nodeCode in codes) {
- var profileCode = nodeCode.code;
- if (!profileCode.code.isDartCode) {
- continue;
- }
- if (profileCode.code.kind == M.CodeKind.stub) {
- continue;
- }
- if (!profileCode.code.isOptimized) {
- return true;
- }
- }
- return false;
- }
-
- // Has this function been inlined in another function?
- bool isInlined() {
- for (var nodeCode in codes) {
- var profileCode = nodeCode.code;
- if (!profileCode.code.isDartCode) {
- continue;
- }
- if (profileCode.code.kind == M.CodeKind.stub) {
- continue;
- }
- // If the code's function isn't this function.
- if (profileCode.code.function != profileFunction.function) {
- return true;
- }
- }
- return false;
- }
-
- setCodeAttributes() {}
-}
-
-/// Predicate filter function. Returns true if path from root to [node] and all
-/// of [node]'s children should be added to the filtered tree.
-typedef bool CallTreeNodeFilter(CallTreeNode node);
-
-/// Build a filter version of a FunctionCallTree.
-abstract class _FilteredCallTreeBuilder {
- /// The filter.
- final CallTreeNodeFilter filter;
-
- /// The unfiltered tree.
- final CallTree _unfilteredTree;
-
- /// The filtered tree (construct by [build]).
- final CallTree filtered;
- final List _currentPath = [];
-
- /// Construct a filtered tree builder using [filter] and [tree].
- _FilteredCallTreeBuilder(this.filter, CallTree tree, this.filtered)
- : _unfilteredTree = tree;
-
- /// Build the filtered tree.
- build() {
- assert(filtered != null);
- assert(filter != null);
- assert(_unfilteredTree != null);
- _descend(_unfilteredTree.root);
- }
-
- CallTreeNode _findInChildren(CallTreeNode current, CallTreeNode needle) {
- for (var child in current.children) {
- if (child.profileData == needle.profileData) {
- return child;
- }
- }
- return null;
- }
-
- CallTreeNode _copyNode(CallTreeNode node);
-
- /// Add all nodes in [_currentPath].
- FunctionCallTreeNode _addCurrentPath() {
- FunctionCallTreeNode current = filtered.root;
- // Tree root is always the first element of the current path.
- assert(_unfilteredTree.root == _currentPath[0]);
- // Assert that unfiltered tree's root and filtered tree's root are different.
- assert(_unfilteredTree.root != current);
- for (var i = 1; i < _currentPath.length; i++) {
- // toAdd is from the unfiltered tree.
- var toAdd = _currentPath[i];
- // See if we already have a node for toAdd in the filtered tree.
- var child = _findInChildren(current, toAdd);
- if (child == null) {
- // New node.
- child = _copyNode(toAdd);
- current.children.add(child);
- }
- current = child;
- assert(current.count == toAdd.count);
- }
- return current;
- }
-
- /// Starting at [current] append [next] and all of [next]'s sub-trees
- _appendTree(CallTreeNode current, CallTreeNode next) {
- if (next == null) {
- return;
- }
- var child = _findInChildren(current, next);
- if (child == null) {
- child = _copyNode(next);
- current.children.add(child);
- }
- current = child;
- for (var nextChild in next.children) {
- _appendTree(current, nextChild);
- }
- }
-
- /// Add path from root to [child], [child], and all of [child]'s sub-trees
- /// to filtered tree.
- _addTree(CallTreeNode child) {
- var current = _addCurrentPath();
- _appendTree(current, child);
- }
-
- /// Descend further into the tree. [current] is from the unfiltered tree.
- _descend(CallTreeNode current) {
- if (current == null) {
- return;
- }
- _currentPath.add(current);
-
- if (filter(current)) {
- // Filter matched.
- if (current.children.length == 0) {
- // Have no children. Add this path.
- _addTree(null);
- } else {
- // Add all child trees.
- for (var child in current.children) {
- _addTree(child);
- }
- }
- } else {
- // Did not match, descend to each child.
- for (var child in current.children) {
- _descend(child);
- }
- }
-
- var last = _currentPath.removeLast();
- assert(current == last);
- }
-}
-
-class _FilteredFunctionCallTreeBuilder extends _FilteredCallTreeBuilder {
- _FilteredFunctionCallTreeBuilder(
- CallTreeNodeFilter filter, FunctionCallTree tree)
- : super(
- filter,
- tree,
- new FunctionCallTree(
- tree.inclusive,
- new FunctionCallTreeNode(
- tree.root.profileData,
- tree.root.count,
- tree.root.inclusiveNativeAllocations,
- tree.root.exclusiveNativeAllocations)));
-
- _copyNode(FunctionCallTreeNode node) {
- return new FunctionCallTreeNode(node.profileData, node.count,
- node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
- }
-}
-
-class _FilteredCodeCallTreeBuilder extends _FilteredCallTreeBuilder {
- _FilteredCodeCallTreeBuilder(CallTreeNodeFilter filter, CodeCallTree tree)
- : super(
- filter,
- tree,
- 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,
- node.inclusiveNativeAllocations, node.exclusiveNativeAllocations);
- }
-}
-
-class FunctionCallTree extends CallTree implements M.FunctionCallTree {
- FunctionCallTree(bool inclusive, FunctionCallTreeNode root)
- : super(inclusive, 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();
- 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;
- }
-
- void _setFunctionPercentage(
- FunctionCallTreeNode parent, FunctionCallTreeNode node) {
- assert(node != null);
- var parentPercentage = 1.0;
- var parentCount = node.count;
- if (parent != null) {
- parentPercentage = parent._percentage;
- parentCount = parent.count;
- }
- if (inclusive) {
- node._percentage = parentPercentage * (node.count / parentCount);
- } else {
- node._percentage = (node.count / parentCount);
- }
- for (var child in node.children) {
- _setFunctionPercentage(node, child);
- }
- }
-
- 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);
- }
- node.children.sort((a, b) {
- return b.inclusiveNativeAllocations - a.inclusiveNativeAllocations;
- });
- }
-
- _markFunctionCallsInner(
- FunctionCallTreeNode caller, FunctionCallTreeNode callee) {
- if (caller != null) {
- caller.profileFunction
- ._recordCallee(callee.profileFunction, callee.count);
- callee.profileFunction
- ._recordCaller(caller.profileFunction, caller.count);
- }
- for (var child in callee.children) {
- _markFunctionCallsInner(callee, child);
- }
- }
-
- _markFunctionCalls() {
- for (var child in root.children) {
- _markFunctionCallsInner(null, child);
- }
- }
-}
-
-class CodeTick {
- final int exclusiveTicks;
- final int inclusiveTicks;
- CodeTick(this.exclusiveTicks, this.inclusiveTicks);
-}
-
-class InlineIntervalTick {
- final int startAddress;
- int _inclusiveTicks = 0;
- int get inclusiveTicks => _inclusiveTicks;
- int _exclusiveTicks = 0;
- int get exclusiveTicks => _exclusiveTicks;
- InlineIntervalTick(this.startAddress);
-}
-
-class ProfileCode implements M.ProfileCode {
- final CpuProfile profile;
- 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>();
- final intervalTicks = new Map<int, InlineIntervalTick>();
- String formattedInclusiveTicks = '';
- String formattedExclusiveTicks = '';
- String formattedExclusivePercent = '';
- String formattedCpuTime = '';
- String formattedOnStackTime = '';
- final Set<String> attributes = new Set<String>();
- final Map<ProfileCode, int> callers = new Map<ProfileCode, int>();
- final Map<ProfileCode, int> callees = new Map<ProfileCode, int>();
-
- void _processTicks(List<dynamic> profileTicks) {
- assert(profileTicks != null);
- assert((profileTicks.length % 3) == 0);
- for (var i = 0; i < profileTicks.length; i += 3) {
- // TODO(observatory): Address is not necessarily representable as a JS
- // integer.
- var address = int.parse(profileTicks[i] as String, radix: 16);
- var exclusive = profileTicks[i + 1] as int;
- var inclusive = profileTicks[i + 2] as int;
- var tick = new CodeTick(exclusive, inclusive);
- addressTicks[address] = tick;
-
- var interval = code.findInterval(address);
- if (interval != null) {
- var intervalTick = intervalTicks[interval.start];
- if (intervalTick == null) {
- // Insert into map.
- intervalTick = new InlineIntervalTick(interval.start);
- intervalTicks[interval.start] = intervalTick;
- }
- intervalTick._inclusiveTicks += inclusive;
- intervalTick._exclusiveTicks += exclusive;
- }
- }
- }
-
- ProfileCode.fromMap(this.profile, this.code, Map data) {
- assert(profile != null);
- assert(code != null);
-
- code.profile = this;
-
- if (code.kind == M.CodeKind.stub) {
- attributes.add('stub');
- } else if (code.kind == M.CodeKind.dart) {
- if (code.isNative) {
- attributes.add('ffi'); // Not to be confused with a C function.
- } else {
- attributes.add('dart');
- }
- if (code.hasIntrinsic) {
- attributes.add('intrinsic');
- }
- if (code.isOptimized) {
- attributes.add('optimized');
- } else {
- attributes.add('unoptimized');
- }
- } else if (code.kind == M.CodeKind.tag) {
- attributes.add('tag');
- } else if (code.kind == M.CodeKind.native) {
- attributes.add('native');
- }
- inclusiveTicks = data['inclusiveTicks'];
- exclusiveTicks = data['exclusiveTicks'];
-
- normalizedExclusiveTicks = exclusiveTicks / profile.sampleCount;
-
- normalizedInclusiveTicks = inclusiveTicks / profile.sampleCount;
-
- var ticks = data['ticks'];
- if (ticks != null) {
- _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);
-
- formattedCpuTime = Utils.formatTimeMilliseconds(
- profile.approximateMillisecondsForCount(exclusiveTicks));
-
- formattedOnStackTime = Utils.formatTimeMilliseconds(
- profile.approximateMillisecondsForCount(inclusiveTicks));
-
- formattedInclusiveTicks =
- '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} '
- '($inclusiveTicks)';
-
- formattedExclusiveTicks =
- '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} '
- '($exclusiveTicks)';
- }
-
- _recordCaller(ProfileCode caller, int count) {
- var r = callers[caller];
- if (r == null) {
- r = 0;
- }
- callers[caller] = r + count;
- }
-
- _recordCallee(ProfileCode callee, int count) {
- var r = callees[callee];
- if (r == null) {
- r = 0;
- }
- callees[callee] = r + count;
- }
-}
-
-class ProfileFunction implements M.ProfileFunction {
- final CpuProfile profile;
- final ServiceFunction function;
- // List of compiled code objects containing this function.
- final List<ProfileCode> profileCodes = new List<ProfileCode>();
- final Map<ProfileFunction, int> callers = new Map<ProfileFunction, int>();
- final Map<ProfileFunction, int> callees = new Map<ProfileFunction, int>();
-
- // Absolute ticks:
- int exclusiveTicks = 0;
- int inclusiveTicks = 0;
-
- // Global percentages:
- double normalizedExclusiveTicks = 0.0;
- double normalizedInclusiveTicks = 0.0;
-
- // Native allocations:
- int exclusiveNativeAllocations = 0;
- int inclusiveNativeAllocations = 0;
-
- String formattedInclusiveTicks = '';
- String formattedExclusiveTicks = '';
- String formattedExclusivePercent = '';
- String formattedCpuTime = '';
- String formattedOnStackTime = '';
- final Set<String> attributes = new Set<String>();
-
- int _sortCodes(ProfileCode a, ProfileCode b) {
- if (a.code.isOptimized == b.code.isOptimized) {
- return b.code.profile.exclusiveTicks - a.code.profile.exclusiveTicks;
- }
- if (a.code.isOptimized) {
- return -1;
- }
- return 1;
- }
-
- // Does this function have an optimized version of itself?
- bool hasOptimizedCode() {
- for (var profileCode in profileCodes) {
- if (profileCode.code.function != function) {
- continue;
- }
- if (profileCode.code.isOptimized) {
- return true;
- }
- }
- return false;
- }
-
- // Does this function have an unoptimized version of itself?
- bool hasUnoptimizedCode() {
- for (var profileCode in profileCodes) {
- if (profileCode.code.kind == M.CodeKind.stub) {
- continue;
- }
- if (!profileCode.code.isDartCode) {
- continue;
- }
- if (!profileCode.code.isOptimized) {
- return true;
- }
- }
- return false;
- }
-
- // Has this function been inlined in another function?
- bool isInlined() {
- for (var profileCode in profileCodes) {
- if (profileCode.code.kind == M.CodeKind.stub) {
- continue;
- }
- if (!profileCode.code.isDartCode) {
- continue;
- }
- // If the code's function isn't this function.
- if (profileCode.code.function != function) {
- return true;
- }
- }
- return false;
- }
-
- void _addKindBasedAttributes(Set<String> attribs) {
- if (function.kind == M.FunctionKind.tag) {
- attribs.add('tag');
- } else if (function.kind == M.FunctionKind.stub) {
- attribs.add('stub');
- } else if (function.kind == M.FunctionKind.native) {
- attribs.add('native');
- } else if (M.isSyntheticFunction(function.kind)) {
- attribs.add('synthetic');
- } else if (function.isNative) {
- attribs.add('ffi'); // Not to be confused with a C function.
- } else {
- attribs.add('dart');
- }
- if (function.hasIntrinsic == true) {
- attribs.add('intrinsic');
- }
- }
-
- ProfileFunction.fromMap(this.profile, this.function, Map data) {
- function.profile = this;
- for (var codeIndex in data['codes']) {
- var profileCode = profile.codes[codeIndex];
- profileCodes.add(profileCode);
- }
- profileCodes.sort(_sortCodes);
-
- _addKindBasedAttributes(attributes);
- exclusiveTicks = data['exclusiveTicks'];
- inclusiveTicks = data['inclusiveTicks'];
-
- 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);
-
- formattedCpuTime = Utils.formatTimeMilliseconds(
- profile.approximateMillisecondsForCount(exclusiveTicks));
-
- formattedOnStackTime = Utils.formatTimeMilliseconds(
- profile.approximateMillisecondsForCount(inclusiveTicks));
-
- formattedInclusiveTicks =
- '${Utils.formatPercent(inclusiveTicks, profile.sampleCount)} '
- '($inclusiveTicks)';
-
- formattedExclusiveTicks =
- '${Utils.formatPercent(exclusiveTicks, profile.sampleCount)} '
- '($exclusiveTicks)';
- }
-
- _recordCaller(ProfileFunction caller, int count) {
- var r = callers[caller];
- if (r == null) {
- r = 0;
- }
- callers[caller] = r + count;
- }
-
- _recordCallee(ProfileFunction callee, int count) {
- var r = callees[callee];
- if (r == null) {
- r = 0;
- }
- callees[callee] = r + count;
- }
-}
-
-// TODO(johnmccutchan): Rename to SampleProfile
-class CpuProfile extends M.SampleProfile {
- Isolate isolate;
-
- int sampleCount = 0;
- int samplePeriod = 0;
- double sampleRate = 0.0;
-
- int stackDepth = 0;
-
- double timeSpan = 0.0;
-
- final Map<String, List> tries = <String, List>{};
- final List<ProfileCode> codes = new List<ProfileCode>();
- bool _builtCodeCalls = false;
- final List<ProfileFunction> functions = new List<ProfileFunction>();
- bool _builtFunctionCalls = false;
-
- CodeCallTree loadCodeTree(M.ProfileTreeDirection direction) {
- switch (direction) {
- case M.ProfileTreeDirection.inclusive:
- return _loadCodeTree(true, tries['inclusiveCodeTrie']);
- case M.ProfileTreeDirection.exclusive:
- return _loadCodeTree(false, tries['exclusiveCodeTrie']);
- }
- throw new Exception('Unknown ProfileTreeDirection');
- }
-
- FunctionCallTree loadFunctionTree(M.ProfileTreeDirection direction) {
- switch (direction) {
- case M.ProfileTreeDirection.inclusive:
- return _loadFunctionTree(true, tries['inclusiveFunctionTrie']);
- case M.ProfileTreeDirection.exclusive:
- return _loadFunctionTree(false, tries['exclusiveFunctionTrie']);
- }
- throw new Exception('Unknown ProfileTreeDirection');
- }
-
- buildCodeCallerAndCallees() {
- if (_builtCodeCalls) {
- return;
- }
- _builtCodeCalls = true;
- var tree = loadCodeTree(M.ProfileTreeDirection.inclusive);
- tree._recordCallerAndCallees();
- }
-
- buildFunctionCallerAndCallees() {
- if (_builtFunctionCalls) {
- return;
- }
- _builtFunctionCalls = true;
- var tree = loadFunctionTree(M.ProfileTreeDirection.inclusive);
- tree._markFunctionCalls();
- }
-
- clear() {
- sampleCount = 0;
- samplePeriod = 0;
- sampleRate = 0.0;
- stackDepth = 0;
- timeSpan = 0.0;
- codes.clear();
- functions.clear();
- tries.clear();
- _builtCodeCalls = false;
- _builtFunctionCalls = false;
- }
-
- Future load(ServiceObjectOwner owner, ServiceMap profile) async {
- await loadProgress(owner, profile).last;
- }
-
- static Future sleep([Duration duration = const Duration(microseconds: 0)]) {
- final Completer completer = new Completer();
- new Timer(duration, () => completer.complete());
- return completer.future;
- }
-
- Stream<double> loadProgress(ServiceObjectOwner owner, ServiceMap profile) {
- var progress = new StreamController<double>.broadcast();
-
- (() async {
- final Stopwatch watch = new Stopwatch();
- watch.start();
- int count = 0;
- var needToUpdate = () {
- count++;
- if (((count % 256) == 0) && (watch.elapsedMilliseconds > 16)) {
- watch.reset();
- return true;
- }
- return false;
- };
- var signal = (double p) {
- progress.add(p);
- return sleep();
- };
- try {
- clear();
- progress.add(0.0);
- if (profile == null) {
- return;
- }
-
- if ((owner != null) && (owner is Isolate)) {
- isolate = owner;
- isolate.resetCachedProfileData();
- }
-
- sampleCount = profile['sampleCount'];
- samplePeriod = profile['samplePeriod'];
- sampleRate = (Duration.MICROSECONDS_PER_SECOND / samplePeriod);
- stackDepth = profile['stackDepth'];
- timeSpan = profile['timeSpan'];
-
- num length = profile['codes'].length + profile['functions'].length;
-
- // Process code table.
- for (var codeRegion in profile['codes']) {
- if (needToUpdate()) {
- await signal(count * 100.0 / length);
- }
- Code code = codeRegion['code'];
- assert(code != null);
- codes.add(new ProfileCode.fromMap(this, code, codeRegion));
- }
- // Process function table.
- for (var profileFunction in profile['functions']) {
- if (needToUpdate()) {
- await signal(count * 100 / length);
- }
- ServiceFunction function = profileFunction['function'];
- assert(function != null);
- functions.add(
- new ProfileFunction.fromMap(this, function, profileFunction));
- }
-
- tries['exclusiveCodeTrie'] =
- new Uint32List.fromList(profile['exclusiveCodeTrie']);
- tries['inclusiveCodeTrie'] =
- new Uint32List.fromList(profile['inclusiveCodeTrie']);
- tries['exclusiveFunctionTrie'] =
- new Uint32List.fromList(profile['exclusiveFunctionTrie']);
- tries['inclusiveFunctionTrie'] =
- new Uint32List.fromList(profile['inclusiveFunctionTrie']);
- } finally {
- progress.close();
- }
- }());
- return progress.stream;
- }
-
- // Data shared across calls to _read*TrieNode.
- int _dataCursor = 0;
-
- // The code trie is serialized as a list of integers. Each node
- // is recreated by consuming some portion of the list. The format is as
- // follows:
- // [0] index into codeTable of code object.
- // [1] tick count (number of times this stack frame occured).
- // [2] child node count
- // Reading the trie is done by recursively reading the tree depth-first
- // pre-order.
- CodeCallTree _loadCodeTree(bool inclusive, List<int> data) {
- if (data == null) {
- return null;
- }
- if (data.length < 3) {
- // Not enough for root node.
- return null;
- }
- // Read the tree, returns the root node.
- var root = _readCodeTrie(data);
- return new CodeCallTree(inclusive, root);
- }
-
- CodeCallTreeNode _readCodeTrieNode(List<int> data) {
- // Lookup code object.
- var codeIndex = data[_dataCursor++];
- var code = codes[codeIndex];
- // Node tick counter.
- 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, inclusiveNativeAllocations, exclusiveNativeAllocations);
- node.children.length = children;
- return node;
- }
-
- CodeCallTreeNode _readCodeTrie(List<int> data) {
- final nodeStack = new List<CodeCallTreeNode>();
- final childIndexStack = new List<int>();
-
- _dataCursor = 0;
- // Read root.
- var root = _readCodeTrieNode(data);
-
- // Push root onto stack.
- if (root.children.length > 0) {
- nodeStack.add(root);
- childIndexStack.add(0);
- }
-
- while (nodeStack.length > 0) {
- var lastIndex = nodeStack.length - 1;
- // Pop parent from stack.
- var parent = nodeStack[lastIndex];
- var childIndex = childIndexStack[lastIndex];
-
- // Read child node.
- assert(childIndex < parent.children.length);
- var node = _readCodeTrieNode(data);
- parent.children[childIndex++] = node;
-
- // If parent still has children, update child index.
- if (childIndex < parent.children.length) {
- childIndexStack[lastIndex] = childIndex;
- } else {
- // Finished processing parent node.
- nodeStack.removeLast();
- childIndexStack.removeLast();
- }
-
- // If node has children, push onto stack.
- if (node.children.length > 0) {
- nodeStack.add(node);
- childIndexStack.add(0);
- }
- }
-
- return root;
- }
-
- FunctionCallTree _loadFunctionTree(bool inclusive, List<int> data) {
- if (data == null) {
- return null;
- }
- if (data.length < 3) {
- // Not enough integers for 1 node.
- return null;
- }
- // Read the tree, returns the root node.
- var root = _readFunctionTrie(data);
- return new FunctionCallTree(inclusive, root);
- }
-
- FunctionCallTreeNode _readFunctionTrieNode(List<int> data) {
- // Read index into function table.
- var index = data[_dataCursor++];
- // Lookup function object.
- 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,
- inclusiveNativeAllocations, exclusiveNativeAllocations);
- // Number of code index / count pairs.
- var codeCount = data[_dataCursor++];
- node.codes.length = codeCount;
- var totalCodeTicks = 0;
- for (var i = 0; i < codeCount; i++) {
- var codeIndex = data[_dataCursor++];
- var code = codes[codeIndex];
- assert(code != null);
- var codeTicks = data[_dataCursor++];
- totalCodeTicks += codeTicks;
- var nodeCode = new FunctionCallTreeNodeCode(code, codeTicks);
- node.codes[i] = nodeCode;
- }
- node.setCodeAttributes();
- node._totalCodeTicks = totalCodeTicks;
- // Number of children.
- var childCount = data[_dataCursor++];
- node.children.length = childCount;
- return node;
- }
-
- FunctionCallTreeNode _readFunctionTrie(List<int> data) {
- final nodeStack = new List<FunctionCallTreeNode>();
- final childIndexStack = new List<int>();
-
- _dataCursor = 0;
-
- // Read root.
- var root = _readFunctionTrieNode(data);
-
- // Push root onto stack.
- if (root.children.length > 0) {
- nodeStack.add(root);
- childIndexStack.add(0);
- }
-
- while (nodeStack.length > 0) {
- var lastIndex = nodeStack.length - 1;
- // Pop parent from stack.
- var parent = nodeStack[lastIndex];
- var childIndex = childIndexStack[lastIndex];
-
- // Read child node.
- assert(childIndex < parent.children.length);
- var node = _readFunctionTrieNode(data);
- parent.children[childIndex++] = node;
-
- // If parent still has children, update child index.
- if (childIndex < parent.children.length) {
- childIndexStack[lastIndex] = childIndex;
- } else {
- // Finished processing parent node.
- nodeStack.removeLast();
- childIndexStack.removeLast();
- }
-
- // If node has children, push onto stack.
- if (node.children.length > 0) {
- nodeStack.add(node);
- childIndexStack.add(0);
- }
- }
-
- return root;
- }
-
- int approximateMillisecondsForCount(count) {
- return (count * samplePeriod) ~/ Duration.MICROSECONDS_PER_MILLISECOND;
- }
-
- double approximateSecondsForCount(count) {
- return (count * samplePeriod) / Duration.MICROSECONDS_PER_SECOND;
- }
-}
« no previous file with comments | « runtime/observatory/lib/service.dart ('k') | runtime/observatory/lib/src/elements/class_allocation_profile.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698