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

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

Powered by Google App Engine
This is Rietveld 408576698