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

Side by Side Diff: runtime/bin/vmservice/observatory/lib/dominator_tree.dart

Issue 837723004: Build Observatory as part of runtime (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library dominator_tree;
6
7 // Flowgraph dominators in O(m log n) time. Implements the algorithm from
8 // [Lengauer & Tarjan 1979]
9 // T. Lengauer and R.E. Tarjan,
10 // "A fast algorithm for finding dominators in a flowgraph",
11 // ACM Transactions on Programming Language and Systems, 1(1):121-141, 1979.
12
13 // Internal vertex information used inside 'Dominator'.
14 // Field names mostly follow naming in [Lengauer & Tarjan 1979].
15 class _Vertex {
16 final Object id;
17 _Vertex dom;
18 _Vertex parent;
19 _Vertex ancestor;
20 _Vertex label;
21 int semi;
22 final List<_Vertex> pred = new List<_Vertex>();
23 final List<_Vertex> bucket = new List<_Vertex>();
24 // TODO(koda): Avoid duplication by having an interface for 'id' with
25 // access to outgoing edges, and/or clearing 'succ' after constructing
26 // inverse graph in 'pred'.
27 final List<_Vertex> succ = new List<_Vertex>();
28 _Vertex(this.id) { label = this; }
29 }
30
31 // Utility to compute immediate dominators. Usage:
32 // 1. Build the flowgraph using 'addEdges'.
33 // 2. Call 'computeDominatorTree' once.
34 // 3. Use 'dominator' to access result.
35 // The instance can only be used once.
36 class Dominator {
37 final Map<Object, _Vertex> _idToVertex = new Map<Object, _Vertex>();
38 final List<_Vertex> _vertex = new List<_Vertex>();
39
40 void addEdges(Object u, Iterable<Object> vs) {
41 _asVertex(u).succ.addAll(vs.map(_asVertex));
42 }
43
44 // Returns the immediate dominator of 'v', or null if 'v' is the root.
45 Object dominator(Object v) {
46 _Vertex dom = _asVertex(v).dom;
47 return dom == null ? null : dom.id;
48 }
49
50 _Vertex _asVertex(Object u) {
51 return _idToVertex.putIfAbsent(u, () => new _Vertex(u));
52 }
53
54 void _dfs(_Vertex v) {
55 v.semi = _vertex.length;
56 _vertex.add(v);
57 for (_Vertex w in v.succ) {
58 if (w.semi == null) {
59 w.parent = v;
60 _dfs(w);
61 }
62 w.pred.add(v);
63 }
64 }
65
66 void _compress(_Vertex v) {
67 if (v.ancestor.ancestor != null) {
68 _compress(v.ancestor);
69 if (v.ancestor.label.semi < v.label.semi) {
70 v.label = v.ancestor.label;
71 }
72 v.ancestor = v.ancestor.ancestor;
73 }
74 }
75
76 _Vertex _eval(_Vertex v) {
77 if (v.ancestor == null) {
78 return v;
79 } else {
80 _compress(v);
81 return v.label;
82 }
83 }
84
85 void _link(_Vertex v, _Vertex w) {
86 w.ancestor = v;
87 }
88
89 void computeDominatorTree(Object root) {
90 _Vertex r = _asVertex(root);
91 int n = _idToVertex.length;
92 _dfs(r);
93 if (_vertex.length != n) {
94 throw new StateError("Not a flowgraph: "
95 "only ${_vertex.length} of $n vertices reachable");
96 }
97 for (int i = n - 1; i >= 1; --i) {
98 _Vertex w = _vertex[i];
99 for (_Vertex v in w.pred) {
100 _Vertex u = _eval(v);
101 if (u.semi < w.semi) {
102 w.semi = u.semi;
103 }
104 }
105 _vertex[w.semi].bucket.add(w);
106 _link(w.parent, w);
107 for (_Vertex v in w.parent.bucket) {
108 _Vertex u = _eval(v);
109 v.dom = u.semi < v.semi ? u : w.parent;
110 }
111 w.parent.bucket.clear();
112 }
113 for (int i = 1; i < n; ++i) {
114 _Vertex w = _vertex[i];
115 if (w.dom != _vertex[w.semi]) {
116 w.dom = w.dom.dom;
117 }
118 }
119 r.dom = null;
120 }
121 }
OLDNEW
« no previous file with comments | « runtime/bin/vmservice/observatory/lib/app.dart ('k') | runtime/bin/vmservice/observatory/lib/elements.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698