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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart

Issue 981523002: Integrity checker for CPS and Tree IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 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 library tree_ir.integrity;
2
3 import 'tree_ir_nodes.dart';
4
5 /// Performs integrity checks on the tree_ir.
6 ///
7 /// Should only be run for debugging purposes, not in production.
8 ///
9 /// - Reference counts on variables and labels must match be actual
10 /// number of references.
11 /// - Labels must be in scope when referenced.
12 /// - Breaks must target a [LabeledStatement].
13 /// - Continues must target a [Loop].
14 ///
15 class CheckTreeIntegrity extends RecursiveVisitor {
16 ExecutableDefinition topLevelNode;
17
18 Map<Variable, int> varReads = <Variable, int>{};
19 Map<Variable, int> varWrites = <Variable, int>{};
20 Map<Label, int> labelUses = <Label, int>{};
21 Map<Label, JumpTarget> label2declaration = <Label, JumpTarget>{};
22
23 void write(Variable variable) {
24 varWrites.putIfAbsent(variable, () => 0);
25 varWrites[variable]++;
26 }
27
28 void read(Variable variable) {
29 varReads.putIfAbsent(variable, () => 0);
30 varReads[variable]++;
31 }
32
33 visitVariableUse(VariableUse node) {
34 read(node.variable);
35 }
36
37 visitAssign(Assign node) {
38 write(node.variable);
39 visitExpression(node.definition);
40 visitStatement(node.next);
41 }
42
43 visitTry(Try node) {
44 node.catchParameters.forEach(write);
45 visitStatement(node.tryBody);
46 visitStatement(node.catchBody);
47 }
48
49 visitFunctionDefinition(FunctionDefinition node) {
50 node.parameters.forEach(write);
51 if (node.body != null) visitStatement(node.body);
52 }
53
54 visitFunctionDeclaration(FunctionDeclaration node) {
55 write(node.variable);
56 visitFunctionDefinition(node.definition);
57 visitStatement(node.next);
58 }
59
60 visitJumpTargetBody(JumpTarget target) {
61 Label label = target.label;
62 if (label2declaration.containsKey(label)) {
63 error('Duplicate declaration of label $label');
64 }
65 label2declaration[label] = target;
66 labelUses[label] = 0;
67 visitStatement(target.body);
68 label2declaration.remove(target);
69
70 if (labelUses[label] != label.useCount) {
71 error('Label $label has ${labelUses[label]} uses '
72 'but its reference count is ${label.useCount}');
73 }
74 }
75
76 visitLabeledStatement(LabeledStatement node) {
77 visitJumpTargetBody(node);
78 visitStatement(node.next);
79 }
80
81 visitWhileTrue(WhileTrue node) {
82 visitJumpTargetBody(node);
83 }
84
85 visitWhileCondition(WhileCondition node) {
86 visitExpression(node.condition);
87 visitJumpTargetBody(node);
88 visitStatement(node.next);
89 }
90
91 visitBreak(Break node) {
92 if (!label2declaration.containsKey(node.target)) {
93 error('Break to label that is not in scope');
94 }
95 if (label2declaration[node.target] is! LabeledStatement) {
96 error('Break to non-labeled statement ${label2declaration[node.target]}');
97 }
98 labelUses[node.target]++;
99 }
100
101 visitContinue(Continue node) {
102 if (!label2declaration.containsKey(node.target)) {
103 error('Continue to label that is not in scope');
104 }
105 if (label2declaration[node.target] is! Loop) {
106 error('Continue to non-loop statement ${label2declaration[node.target]}');
107 }
108 labelUses[node.target]++;
109 }
110
111 dynamic error(String message) {
112 throw 'Tree IR integrity violation in ${topLevelNode.element}:\n$message';
113 }
114
115 void check(ExecutableDefinition node) {
116 topLevelNode = node;
117 visitExecutableDefinition(node);
118
119 // Verify reference counters for all variables.
120 List<Variable> seenVariables = new List<Variable>();
121 seenVariables.addAll(varReads.keys);
122 seenVariables.addAll(varWrites.keys);
123 for (Variable variable in seenVariables) {
124 int reads = varReads.putIfAbsent(variable, () => 0);
125 int writes = varWrites.putIfAbsent(variable, () => 0);
126 if (reads != variable.readCount || writes != variable.writeCount) {
127 error('Invalid reference count for ${variable.element}:\n'
128 '- Variable has $reads reads and $writes writes\n'
129 '- Reference count is ${variable.readCount} reads and '
130 '${variable.writeCount} writes');
131 }
132 }
133 }
134
135 }
136
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698