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

Unified Diff: pkg/kernel/lib/checks.dart

Issue 2529973002: Speed up kernel sanity checks. (Closed)
Patch Set: Revert parent_pointer_test Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/kernel/bin/transform.dart ('k') | pkg/kernel/lib/transformations/flags.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/checks.dart
diff --git a/pkg/kernel/lib/checks.dart b/pkg/kernel/lib/checks.dart
index 3d9a8651d1422f8a4fcac5e0d1e672c2abf2d614..5d77332d64fd873e8c544e54ccd4b020a9267558 100644
--- a/pkg/kernel/lib/checks.dart
+++ b/pkg/kernel/lib/checks.dart
@@ -4,79 +4,90 @@
library kernel.checks;
import 'ast.dart';
+import 'transformations/flags.dart';
void runSanityChecks(Program program) {
- CheckParentPointers.check(program);
- CheckReferences.check(program);
-}
-
-class CheckParentPointers extends Visitor {
- static void check(TreeNode node) {
- node.accept(new CheckParentPointers(node.parent));
- }
-
- TreeNode parent;
-
- CheckParentPointers([this.parent]);
-
- defaultTreeNode(TreeNode node) {
- if (node.parent != parent) {
- throw 'Parent pointer on ${node.runtimeType} '
- 'is ${node.parent.runtimeType} '
- 'but should be ${parent.runtimeType}';
- }
- var oldParent = parent;
- parent = node;
- node.visitChildren(this);
- parent = oldParent;
- }
+ SanityCheck.check(program);
}
/// Checks that references refer to something in scope.
///
/// Currently only checks member, class, and type parameter references.
-class CheckReferences extends RecursiveVisitor {
- final Set<Member> members = new Set<Member>();
+class SanityCheck extends RecursiveVisitor {
final Set<Class> classes = new Set<Class>();
final Set<TypeParameter> typeParameters = new Set<TypeParameter>();
Member currentMember;
Class currentClass;
+ TreeNode currentParent;
TreeNode get context => currentMember ?? currentClass;
static void check(Program program) {
- program.accept(new CheckReferences());
+ program.accept(new SanityCheck());
+ }
+
+ defaultTreeNode(TreeNode node) {
+ visitChildren(node);
+ }
+
+ void visitChildren(TreeNode node) {
+ if (!identical(node.parent, currentParent)) {
+ throw 'Parent pointer on ${node.runtimeType} '
+ 'is ${node.parent.runtimeType} '
+ 'but should be ${currentParent.runtimeType}';
+ }
+ var oldParent = currentParent;
+ currentParent = node;
+ node.visitChildren(this);
+ currentParent = oldParent;
+ }
+
+ void declareMember(Member member) {
+ if (member.transformerFlags & TransformerFlag.seenBySanityCheck != 0) {
+ throw '$member has been declared more than once';
+ }
+ member.transformerFlags |= TransformerFlag.seenBySanityCheck;
+ }
+
+ void undeclareMember(Member member) {
+ member.transformerFlags &= ~TransformerFlag.seenBySanityCheck;
}
visitProgram(Program program) {
for (var library in program.libraries) {
classes.addAll(library.classes);
- members.addAll(library.members);
+ library.members.forEach(declareMember);
+ for (var class_ in library.classes) {
+ class_.members.forEach(declareMember);
+ }
+ }
+ visitChildren(program);
+ for (var library in program.libraries) {
+ library.members.forEach(undeclareMember);
for (var class_ in library.classes) {
- members.addAll(class_.members);
+ class_.members.forEach(undeclareMember);
}
}
- program.visitChildren(this);
}
defaultMember(Member node) {
currentMember = node;
- node.visitChildren(this);
+ visitChildren(node);
currentMember = null;
}
visitClass(Class node) {
currentClass = node;
typeParameters.addAll(node.typeParameters);
- node.visitChildren(this);
+ visitChildren(node);
typeParameters.removeAll(node.typeParameters);
currentClass = null;
}
visitFunctionNode(FunctionNode node) {
typeParameters.addAll(node.typeParameters);
- node.visitChildren(this);
+ visitChildren(node);
typeParameters.removeAll(node.typeParameters);
}
@@ -87,12 +98,19 @@ class CheckReferences extends RecursiveVisitor {
'$context';
}
}
- node.visitChildren(this);
+ typeParameters.addAll(node.typeParameters);
+ for (var typeParameter in node.typeParameters) {
+ typeParameter.bound?.accept(this);
+ }
+ visitList(node.positionalParameters, this);
+ visitList(node.namedParameters, this);
+ node.returnType.accept(this);
+ typeParameters.removeAll(node.typeParameters);
}
@override
defaultMemberReference(Member node) {
- if (!members.contains(node)) {
+ if (node.transformerFlags & TransformerFlag.seenBySanityCheck == 0) {
throw 'Dangling reference to $node found in $context.\n'
'Parent pointer is set to ${node.parent}';
}
@@ -126,23 +144,24 @@ class CheckReferences extends RecursiveVisitor {
}
}
-class SizeCounter extends RecursiveVisitor {
- int size = 0;
- int emptyArguments = 0;
+class CheckParentPointers extends Visitor {
+ static void check(TreeNode node) {
+ node.accept(new CheckParentPointers(node.parent));
+ }
+
+ TreeNode parent;
- void visit(TreeNode node) => node.accept(this);
+ CheckParentPointers([this.parent]);
- visitArguments(Arguments node) {
- super.visitArguments(node);
- if (node.positional.isEmpty &&
- node.positional.isEmpty &&
- node.types.isEmpty) {
- ++emptyArguments;
+ defaultTreeNode(TreeNode node) {
+ if (node.parent != parent) {
+ throw 'Parent pointer on ${node.runtimeType} '
+ 'is ${node.parent.runtimeType} '
+ 'but should be ${parent.runtimeType}';
}
- }
-
- defaultNode(Node node) {
- ++size;
+ var oldParent = parent;
+ parent = node;
node.visitChildren(this);
+ parent = oldParent;
}
}
« no previous file with comments | « pkg/kernel/bin/transform.dart ('k') | pkg/kernel/lib/transformations/flags.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698