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

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

Issue 2204563003: Converted Observatory cpu-profile element (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Removed tmp files Created 4 years, 5 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/elements/cpu_profile/virtual_tree.dart
diff --git a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
new file mode 100644
index 0000000000000000000000000000000000000000..83a1f5a90a7bb16d6228257bb62282f26ef895ec
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
@@ -0,0 +1,204 @@
+// Copyright (c) 2013, 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.
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:math' as Math;
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/stack_trace_tree_config.dart'
+ show ProfileTreeMode, ProfileTreeDirection;
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/containers/virtual_tree.dart';
+import 'package:observatory/src/elements/function_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/utils.dart';
+
+class CpuProfileVirtualTreeElement extends HtmlElement implements Renderable {
+ static const tag =
+ const Tag<CpuProfileVirtualTreeElement>('cpu-profile-virtual-tree');
+
+ RenderingScheduler<CpuProfileVirtualTreeElement> _r;
+
+ Stream<RenderedEvent<CpuProfileVirtualTreeElement>> get onRendered =>
+ _r.onRendered;
+
+ ProfileTreeDirection _direction;
+ ProfileTreeMode _mode;
+ M.Isolate _isolate;
+ M.SampleProfile _profile;
+ M.CallTreeNodeFilter _filter;
+
+ ProfileTreeDirection get direction => _direction;
+ ProfileTreeMode get mode => _mode;
+ M.Isolate get isolate => _isolate;
+ M.SampleProfile get profile => _profile;
+ M.CallTreeNodeFilter get filter => _filter;
+
+ set direction(ProfileTreeDirection value) =>
+ _direction = _r.checkAndReact(_direction, value);
+ set mode(ProfileTreeMode value) => _mode = _r.checkAndReact(_mode, value);
+ set filter(M.CallTreeNodeFilter value) =>
+ _filter = _r.checkAndReact(_filter, value);
+
+ factory CpuProfileVirtualTreeElement(M.IsolateRef isolate,
+ M.SampleProfile profile, {ProfileTreeMode mode: ProfileTreeMode.Function,
+ ProfileTreeDirection direction: ProfileTreeDirection.Exclusive,
+ RenderingQueue queue}) {
+ assert(isolate != null);
+ assert(profile != null);
+ assert(mode != null);
+ assert(direction != null);
+ CpuProfileVirtualTreeElement e = document.createElement(tag.name);
+ e._r = new RenderingScheduler(e, queue: queue);
+ e._isolate = isolate;
+ e._profile = profile;
+ e._mode = mode;
+ e._direction = direction;
+ return e;
+ }
+
+
+ CpuProfileVirtualTreeElement.created() : super.created();
+
+ @override
+ attached() {
+ super.attached();
+ _r.enable();
+ }
+
+ @override
+ detached() {
+ super.detached(); _r.disable(notify: true);
+ children = [];
+ }
+
+ void render() {
+ children = const [];
+ bool exclusive = direction == ProfileTreeDirection.Exclusive;
+ switch (mode) {
+ case ProfileTreeMode.Code:
+ _buildCodeTree(exclusive);
+ break;
+ case ProfileTreeMode.Function:
+ _buildFunctionTree(exclusive);
+ break;
+ default:
+ throw new Exception('Unknown ProfileTreeMode');
+ }
+ }
+
+ static const kHotThreshold = 0.05; // 5%.
+ static const kMediumThreshold = 0.02; // 2%.
+
+ void _buildFunctionTree(bool exclusive) {
+ var tree = _profile.loadFunctionTree(exclusive ? 'exclusive' : 'inclusive');
+ if (tree == null) {
+ return;
+ }
+ if (filter != null) {
+ tree = tree.filtered(filter);
+ }
+ var t;
+ children = [
+ t = new VirtualTreeElement((toggle) {
Cutch 2016/08/02 15:52:20 could this closure be turned into a named method?
cbernaschina 2016/08/02 17:40:24 Done.
+ return new DivElement()
+ ..classes = const ['tmp-collection-item']
+ ..children = [
+ new SpanElement()..classes = const ['inclusive']
+ ..title = 'global % on stack',
+ new SpanElement()..classes = const ['exclusive']
+ ..title = 'global % executing',
+ new SpanElement()..classes = const ['lines'],
+ new SpanElement()..classes = const ['expander']
+ ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+ new SpanElement()..classes = const ['percentage']
+ ..title = 'tree node %',
+ new SpanElement()..classes = const ['name']
+ ];
+ }, (HtmlElement element, M.FunctionCallTreeNode item, int depth) {
+ element.children[0].text = Utils.formatPercentNormalized(
+ item.profileFunction.normalizedInclusiveTicks);
+ element.children[1].text = Utils.formatPercentNormalized(
+ item.profileFunction.normalizedExclusiveTicks);
+ _updateLines(element.children[2].children, depth);
+ if (item.children.isNotEmpty) {
+ element.children[3].text = t.isExpanded(item) ? '▼' : '►';
+ } else {
+ element.children[3].text = '';
+ }
+ element.children[4].text = Utils.formatPercentNormalized(
+ item.percentage);
+ element.children[5] = new FunctionRefElement(_isolate,
+ item.profileFunction.function, queue: _r.queue)
+ ..classes = const ['name'];
+ }, (M.FunctionCallTreeNode node) => node.children,
+ items: tree.root.children, queue: _r.queue)
+ ];
+ if (tree.root.children.length == 1) {
+ t.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
+ }
+ }
+
+
+
+ void _buildCodeTree(bool exclusive) {
+ var tree = _profile.loadCodeTree(exclusive ? 'exclusive' : 'inclusive');
+ if (tree == null) {
+ return;
+ }
+ if (filter != null) {
+ tree = tree.filtered(filter);
+ }
+ var t;
+ children = [
+ t = new VirtualTreeElement((toggle) {
Cutch 2016/08/02 15:52:20 could this closure be turned into a named method?
cbernaschina 2016/08/02 17:40:24 Done.
+ return new DivElement()
+ ..classes = const ['tmp-collection-item']
+ ..children = [
+ new SpanElement()..classes = const ['inclusive']
+ ..title = 'global % on stack',
+ new SpanElement()..classes = const ['exclusive']
+ ..title = 'global % executing',
+ new SpanElement()..classes = const ['lines'],
+ new SpanElement()..classes = const ['expander']
+ ..onClick.listen((_) => toggle(autoToggleSingleChildNodes: true)),
+ new SpanElement()..classes = const ['percentage']
+ ..title = 'tree node %',
+ new AnchorElement()..classes = const ['name']
+ ];
+ }, (HtmlElement element, M.CodeCallTreeNode item, int depth) {
+ element.children[0].text = Utils.formatPercentNormalized(
+ item.profileCode.normalizedInclusiveTicks);
+ element.children[1].text = Utils.formatPercentNormalized(
+ item.profileCode.normalizedExclusiveTicks);
+ _updateLines(element.children[2].children, depth);
+ if (item.children.isNotEmpty) {
+ element.children[3].text = t.isExpanded(item) ? '▼' : '►';
+ } else {
+ element.children[3].text = '';
+ }
+ element.children[4].text = Utils.formatPercentNormalized(
+ item.percentage);
+ element.children[5] = new CodeRefElement(_isolate,
+ item.profileCode.code, queue: _r.queue)
+ ..classes = const ['name'];
+ }, (M.CodeCallTreeNode node) => node.children,
+ items: tree.root.children, queue: _r.queue)
+ ];
+ if (tree.root.children.length == 1) {
+ t.expand(tree.root.children.first, autoExpandSingleChildNodes: true);
+ }
+ }
+
+ static _updateLines(List<Element> lines, int n) {
+ n = Math.max(0, n);
+ while (lines.length > n) {
+ lines.removeLast();
+ }
+ while (lines.length < n) {
+ lines.add(new SpanElement());
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698