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

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

Issue 1375213003: dart2js cps: Maintain parent pointers instead of recomputing them. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase 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 RecursiveVisitor { 27 class CheckCpsIntegrity extends TrampolineRecursiveVisitor {
28 28
29 FunctionDefinition topLevelNode; 29 FunctionDefinition topLevelNode;
30 String previousPass;
30 31
31 Set<Definition> seenDefinitions = new Set<Definition>(); 32 Set<Definition> seenDefinitions = new Set<Definition>();
32 Map<Definition, Set<Reference>> seenReferences = 33 Map<Definition, Set<Reference>> seenReferences =
33 <Definition, Set<Reference>>{}; 34 <Definition, Set<Reference>>{};
34 35
35 Set<Definition> inScope = new Set<Definition>(); 36 Set<Definition> inScope = new Set<Definition>();
36 Set<Continuation> insideContinuations = new Set<Continuation>(); 37 Set<Continuation> insideContinuations = new Set<Continuation>();
37 38
38 void markAsSeen(Definition def) { 39 void markAsSeen(Definition def) {
39 if (!seenDefinitions.add(def)) { 40 if (!seenDefinitions.add(def)) {
40 error('Redeclared $def', def); 41 error('Redeclared $def', def);
41 } 42 }
42 seenReferences[def] = new Set<Reference>(); 43 seenReferences[def] = new Set<Reference>();
43 } 44 }
44 45
45 void enterScope(Iterable<Definition> definitions) { 46 void enterScope(Iterable<Definition> definitions) {
46 inScope.addAll(definitions); 47 inScope.addAll(definitions);
47 pushAction(() => inScope.removeAll(definitions)); 48 pushAction(() => inScope.removeAll(definitions));
48 } 49 }
49 50
50 void enterContinuation(Continuation cont) { 51 void enterContinuation(Continuation cont) {
51 insideContinuations.add(cont); 52 insideContinuations.add(cont);
52 pushAction(() => insideContinuations.remove(cont)); 53 pushAction(() => insideContinuations.remove(cont));
53 } 54 }
54 55
55 void check(FunctionDefinition node) { 56 void check(FunctionDefinition node, String previousPass) {
56 topLevelNode = node; 57 topLevelNode = node;
58 this.previousPass = previousPass;
59 ParentChecker.checkParents(node, this);
57 visit(node); 60 visit(node);
58 // Check for broken reference chains. We check this last, so out-of-scope 61 // Check for broken reference chains. We check this last, so out-of-scope
59 // references are not classified as a broken reference chain. 62 // references are not classified as a broken reference chain.
60 seenDefinitions.forEach(checkReferenceChain); 63 seenDefinitions.forEach(checkReferenceChain);
61 } 64 }
62 65
63 @override 66 @override
64 Expression traverseLetCont(LetCont node) { 67 Expression traverseLetCont(LetCont node) {
65 node.continuations.forEach(markAsSeen); 68 node.continuations.forEach(markAsSeen);
66 node.continuations.forEach(push); 69 node.continuations.forEach(push);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 error('Reference chain for $def contains orphaned references', def); 177 error('Reference chain for $def contains orphaned references', def);
175 } 178 }
176 } 179 }
177 180
178 error(String message, node) { 181 error(String message, node) {
179 String sexpr; 182 String sexpr;
180 if (ENABLE_DUMP) { 183 if (ENABLE_DUMP) {
181 try { 184 try {
182 Decorator decorator = (n, String s) => n == node ? '**$s**' : s; 185 Decorator decorator = (n, String s) => n == node ? '**$s**' : s;
183 sexpr = new SExpressionStringifier(decorator).visit(topLevelNode); 186 sexpr = new SExpressionStringifier(decorator).visit(topLevelNode);
187 sexpr = 'SExpr dump (offending node marked with **):\n\n$sexpr';
184 } catch (e) { 188 } catch (e) {
185 sexpr = '(Exception thrown by SExpressionStringifier: $e)'; 189 sexpr = '(Exception thrown by SExpressionStringifier: $e)';
186 } 190 }
187 } else { 191 } else {
188 sexpr = '(Set DUMP_IR flag to enable)'; 192 sexpr = '(Set DUMP_IR flag to enable SExpr dump)';
189 } 193 }
190 throw 'CPS integrity violation in ${topLevelNode.element}:\n' 194 throw 'CPS integrity violation\n'
195 'After $previousPass on ${topLevelNode.element}\n'
191 '$message\n\n' 196 '$message\n\n'
192 'SExpr dump (offending node marked with **):\n\n'
193 '$sexpr\n'; 197 '$sexpr\n';
194 } 198 }
199 }
195 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 }
196 } 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