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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart

Issue 1386343003: Revert "dart2js cps: Maintain parent pointers instead of recomputing them." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
OLDNEW
1 library dart2js.cps_ir_integrity; 1 library dart2js.cps_ir_integrity;
2 2
3 import 'cps_ir_nodes.dart'; 3 import 'cps_ir_nodes.dart';
4 import 'cps_ir_nodes_sexpr.dart'; 4 import 'cps_ir_nodes_sexpr.dart';
5 import '../tracer.dart' as tracer; 5 import '../tracer.dart' as tracer;
6 6
7 /// Dump S-expressions on error if the tracer is enabled. 7 /// Dump S-expressions on error if the tracer is enabled.
8 /// 8 ///
9 /// Technically this has nothing to do with the tracer, but if you want one 9 /// Technically this has nothing to do with the tracer, but if you want one
10 /// enabled, you typically want the other as well, so we use the same flag. 10 /// enabled, you typically want the other as well, so we use the same flag.
11 const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null; 11 const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null;
12 12
13 /// Performs integrity checks on the CPS IR. 13 /// Performs integrity checks on the CPS IR.
14 /// 14 ///
15 /// To be run for debugging purposes, not for use in production. 15 /// To be run for debugging purposes, not for use in production.
16 /// 16 ///
17 /// The following integrity checks are performed: 17 /// The following integrity checks are performed:
18 /// 18 ///
19 /// - References are in scope of their definitions. 19 /// - References are in scope of their definitions.
20 /// - Recursive Continuations and InvokeContinuations are marked as recursive. 20 /// - Recursive Continuations and InvokeContinuations are marked as recursive.
21 /// - InvokeContinuations have the same arity as their target. 21 /// - InvokeContinuations have the same arity as their target.
22 /// - Reference chains are valid doubly-linked lists. 22 /// - Reference chains are valid doubly-linked lists.
23 /// - Reference chains contain exactly the references that are in the IR. 23 /// - Reference chains contain exactly the references that are in the IR.
24 /// - Each definition object occurs only once in the IR (no redeclaring). 24 /// - Each definition object occurs only once in the IR (no redeclaring).
25 /// - Each reference object occurs only once in the IR (no sharing). 25 /// - Each reference object occurs only once in the IR (no sharing).
26 /// 26 ///
27 class CheckCpsIntegrity extends TrampolineRecursiveVisitor { 27 class CheckCpsIntegrity extends RecursiveVisitor {
28 28
29 FunctionDefinition topLevelNode; 29 FunctionDefinition topLevelNode;
30 String previousPass;
31 30
32 Set<Definition> seenDefinitions = new Set<Definition>(); 31 Set<Definition> seenDefinitions = new Set<Definition>();
33 Map<Definition, Set<Reference>> seenReferences = 32 Map<Definition, Set<Reference>> seenReferences =
34 <Definition, Set<Reference>>{}; 33 <Definition, Set<Reference>>{};
35 34
36 Set<Definition> inScope = new Set<Definition>(); 35 Set<Definition> inScope = new Set<Definition>();
37 Set<Continuation> insideContinuations = new Set<Continuation>(); 36 Set<Continuation> insideContinuations = new Set<Continuation>();
38 37
39 void markAsSeen(Definition def) { 38 void markAsSeen(Definition def) {
40 if (!seenDefinitions.add(def)) { 39 if (!seenDefinitions.add(def)) {
41 error('Redeclared $def', def); 40 error('Redeclared $def', def);
42 } 41 }
43 seenReferences[def] = new Set<Reference>(); 42 seenReferences[def] = new Set<Reference>();
44 } 43 }
45 44
46 void enterScope(Iterable<Definition> definitions) { 45 void enterScope(Iterable<Definition> definitions) {
47 inScope.addAll(definitions); 46 inScope.addAll(definitions);
48 pushAction(() => inScope.removeAll(definitions)); 47 pushAction(() => inScope.removeAll(definitions));
49 } 48 }
50 49
51 void enterContinuation(Continuation cont) { 50 void enterContinuation(Continuation cont) {
52 insideContinuations.add(cont); 51 insideContinuations.add(cont);
53 pushAction(() => insideContinuations.remove(cont)); 52 pushAction(() => insideContinuations.remove(cont));
54 } 53 }
55 54
56 void check(FunctionDefinition node, String previousPass) { 55 void check(FunctionDefinition node) {
57 topLevelNode = node; 56 topLevelNode = node;
58 this.previousPass = previousPass;
59 ParentChecker.checkParents(node, this);
60 visit(node); 57 visit(node);
61 // Check for broken reference chains. We check this last, so out-of-scope 58 // Check for broken reference chains. We check this last, so out-of-scope
62 // references are not classified as a broken reference chain. 59 // references are not classified as a broken reference chain.
63 seenDefinitions.forEach(checkReferenceChain); 60 seenDefinitions.forEach(checkReferenceChain);
64 } 61 }
65 62
66 @override 63 @override
67 Expression traverseLetCont(LetCont node) { 64 Expression traverseLetCont(LetCont node) {
68 node.continuations.forEach(markAsSeen); 65 node.continuations.forEach(markAsSeen);
69 node.continuations.forEach(push); 66 node.continuations.forEach(push);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 error('Reference chain for $def contains orphaned references', def); 174 error('Reference chain for $def contains orphaned references', def);
178 } 175 }
179 } 176 }
180 177
181 error(String message, node) { 178 error(String message, node) {
182 String sexpr; 179 String sexpr;
183 if (ENABLE_DUMP) { 180 if (ENABLE_DUMP) {
184 try { 181 try {
185 Decorator decorator = (n, String s) => n == node ? '**$s**' : s; 182 Decorator decorator = (n, String s) => n == node ? '**$s**' : s;
186 sexpr = new SExpressionStringifier(decorator).visit(topLevelNode); 183 sexpr = new SExpressionStringifier(decorator).visit(topLevelNode);
187 sexpr = 'SExpr dump (offending node marked with **):\n\n$sexpr';
188 } catch (e) { 184 } catch (e) {
189 sexpr = '(Exception thrown by SExpressionStringifier: $e)'; 185 sexpr = '(Exception thrown by SExpressionStringifier: $e)';
190 } 186 }
191 } else { 187 } else {
192 sexpr = '(Set DUMP_IR flag to enable SExpr dump)'; 188 sexpr = '(Set DUMP_IR flag to enable)';
193 } 189 }
194 throw 'CPS integrity violation\n' 190 throw 'CPS integrity violation in ${topLevelNode.element}:\n'
195 'After $previousPass on ${topLevelNode.element}\n'
196 '$message\n\n' 191 '$message\n\n'
192 'SExpr dump (offending node marked with **):\n\n'
197 '$sexpr\n'; 193 '$sexpr\n';
198 } 194 }
195
199 } 196 }
200
201 /// Traverses the CPS term and checks that node.parent is correctly set
202 /// for each visited node.
203 class ParentChecker extends DeepRecursiveVisitor {
204 static void checkParents(Node node, CheckCpsIntegrity main) {
205 ParentChecker visitor = new ParentChecker._make(main);
206 visitor._worklist.add(node);
207 visitor.trampoline();
208 }
209
210 ParentChecker._make(this.main);
211
212 Node _parent;
213 final List<Node> _worklist = <Node>[];
214 final CheckCpsIntegrity main;
215
216 void trampoline() {
217 while (_worklist.isNotEmpty) {
218 _parent = _worklist.removeLast();
219 _parent.accept(this);
220 }
221 }
222
223 error(String message, node) => main.error(message, node);
224
225 @override
226 visit(Node node) {
227 _worklist.add(node);
228 if (node.parent != _parent) {
229 error('Parent pointer on $node is ${node.parent} but should be $_parent',
230 node);
231 }
232 }
233
234 @override
235 processReference(Reference node) {
236 if (node.parent != _parent) {
237 error('Parent pointer on $node is ${node.parent} but should be $_parent',
238 node);
239 }
240 }
241 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_fragment.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698