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

Unified Diff: runtime/bin/vmservice/observatory/lib/dominator_tree.dart

Issue 777693002: Compute retained size for every object, using dominator trees. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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/bin/vmservice/observatory/lib/dominator_tree.dart
===================================================================
--- runtime/bin/vmservice/observatory/lib/dominator_tree.dart (revision 0)
+++ runtime/bin/vmservice/observatory/lib/dominator_tree.dart (working copy)
@@ -0,0 +1,121 @@
+// Copyright (c) 2014, 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.
+
+library dominator_tree;
+
+// Flowgraph dominators in O(m log n) time. Implements the algorithm from
+// [Lengauer & Tarjan 1979]
+// T. Lengauer and R.E. Tarjan,
+// "A fast algorithm for finding dominators in a flowgraph",
+// ACM Transactions on Programming Language and Systems, 1(1):121-141, 1979.
+
+// Internal vertex information used inside 'Dominator'.
+// Field names mostly follow naming in [Lengauer & Tarjan 1979].
+class _Vertex {
+ final Object id;
+ _Vertex dom;
+ _Vertex parent;
+ _Vertex ancestor;
+ _Vertex label;
+ int semi;
+ final List<_Vertex> pred = new List<_Vertex>();
+ final List<_Vertex> bucket = new List<_Vertex>();
+ // TODO(koda): Avoid duplication by having an interface for 'id' with
+ // access to outgoing edges, and/or clearing 'succ' after constructing
+ // inverse graph in 'pred'.
+ final List<_Vertex> succ = new List<_Vertex>();
+ _Vertex(this.id) { label = this; }
+}
+
+// Utility to compute immediate dominators. Usage:
+// 1. Build the flowgraph using 'addEdges'.
+// 2. Call 'computeDominatorTree' once.
+// 3. Use 'dominator' to access result.
+// The instance can only be used once.
+class Dominator {
+ final Map<Object, _Vertex> _idToVertex = new Map<Object, _Vertex>();
+ final List<_Vertex> _vertex = new List<_Vertex>();
+
+ void addEdges(Object u, Iterable<Object> vs) {
+ _asVertex(u).succ.addAll(vs.map(_asVertex));
+ }
+
+ // Returns the immediate dominator of 'v', or null if 'v' is the root.
+ Object dominator(Object v) {
+ _Vertex dom = _asVertex(v).dom;
+ return dom == null ? null : dom.id;
+ }
+
+ _Vertex _asVertex(Object u) {
+ return _idToVertex.putIfAbsent(u, () => new _Vertex(u));
+ }
+
+ void _dfs(_Vertex v) {
+ v.semi = _vertex.length;
+ _vertex.add(v);
+ for (_Vertex w in v.succ) {
+ if (w.semi == null) {
+ w.parent = v;
+ _dfs(w);
+ }
+ w.pred.add(v);
+ }
+ }
+
+ void _compress(_Vertex v) {
+ if (v.ancestor.ancestor != null) {
+ _compress(v.ancestor);
+ if (v.ancestor.label.semi < v.label.semi) {
+ v.label = v.ancestor.label;
+ }
+ v.ancestor = v.ancestor.ancestor;
+ }
+ }
+
+ _Vertex _eval(_Vertex v) {
+ if (v.ancestor == null) {
+ return v;
+ } else {
+ _compress(v);
+ return v.label;
+ }
+ }
+
+ void _link(_Vertex v, _Vertex w) {
+ w.ancestor = v;
+ }
+
+ void computeDominatorTree(Object root) {
+ _Vertex r = _asVertex(root);
+ int n = _idToVertex.length;
+ _dfs(r);
+ if (_vertex.length != n) {
+ throw new StateError("Not a flowgraph: "
+ "only ${_vertex.length} of $n vertices reachable");
+ }
+ for (int i = n - 1; i >= 1; --i) {
+ _Vertex w = _vertex[i];
+ for (_Vertex v in w.pred) {
+ _Vertex u = _eval(v);
+ if (u.semi < w.semi) {
+ w.semi = u.semi;
+ }
+ }
+ _vertex[w.semi].bucket.add(w);
+ _link(w.parent, w);
+ for (_Vertex v in w.parent.bucket) {
+ _Vertex u = _eval(v);
+ v.dom = u.semi < v.semi ? u : w.parent;
+ }
+ w.parent.bucket.clear();
+ }
+ for (int i = 1; i < n; ++i) {
+ _Vertex w = _vertex[i];
+ if (w.dom != _vertex[w.semi]) {
+ w.dom = w.dom.dom;
+ }
+ }
+ r.dom = null;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698