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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart

Issue 2246623002: Delete CPS IR (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
deleted file mode 100644
index 6363c88292b52487d30a3d02b1c49b060d1d635e..0000000000000000000000000000000000000000
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
+++ /dev/null
@@ -1,276 +0,0 @@
-library dart2js.cps_ir_integrity;
-
-import '../tracer.dart' as tracer;
-import 'cps_ir_nodes.dart';
-import 'cps_ir_nodes_sexpr.dart';
-
-/// Dump S-expressions on error if the tracer is enabled.
-///
-/// Technically this has nothing to do with the tracer, but if you want one
-/// enabled, you typically want the other as well, so we use the same flag.
-const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null;
-
-enum ScopeType { InScope, InDefinition, NotInScope }
-
-/// Performs integrity checks on the CPS IR.
-///
-/// To be run for debugging purposes, not for use in production.
-///
-/// The following integrity checks are performed:
-///
-/// - References are in scope of their definitions.
-/// - Recursive Continuations and InvokeContinuations are marked as recursive.
-/// - InvokeContinuations have the same arity as their target.
-/// - Reference chains are valid doubly-linked lists.
-/// - Reference chains contain exactly the references that are in the IR.
-/// - Each definition object occurs only once in the IR (no redeclaring).
-/// - Each reference object occurs only once in the IR (no sharing).
-///
-class CheckCpsIntegrity extends TrampolineRecursiveVisitor {
- FunctionDefinition topLevelNode;
- final Map<Definition, ScopeType> inScope = <Definition, ScopeType>{};
- final List<Definition> definitions = [];
- String previousPass;
-
- void handleDeclaration(Definition def) {
- definitions.add(def);
- // Check the reference chain for cycles broken links.
- Reference anchor = null;
- int i = 0;
- for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
- if (ref.definition != def) {
- error(
- 'Reference to ${ref.definition} found in '
- 'reference chain for $def',
- def);
- }
- if (ref == anchor) {
- error('Cyclic reference chain for $def', def);
- }
- if (i & ++i == 0) {
- // Move the anchor every 2^Nth step.
- anchor = ref;
- }
- }
- }
-
- void enterScope(Iterable<Definition> definitions) {
- for (Definition def in definitions) {
- inScope[def] = ScopeType.InScope;
- }
- pushAction(() {
- for (Definition def in definitions) {
- inScope[def] = ScopeType.NotInScope;
- }
- });
- }
-
- void enterContinuation(Continuation cont) {
- inScope[cont] = ScopeType.InDefinition;
- pushAction(() {
- inScope[cont] = ScopeType.NotInScope;
- });
- }
-
- void check(FunctionDefinition node, String previousPass) {
- // [check] will be called multiple times per instance to avoid reallocating
- // the large [inScope] map. Reset the other fields.
- this.topLevelNode = node;
- this.previousPass = previousPass;
- this.definitions.clear();
- ParentChecker.checkParents(node, this);
- visit(node);
- // Check for broken reference chains. We check this last, so out-of-scope
- // references are not classified as a broken reference chain.
- definitions.forEach(checkReferenceChain);
- }
-
- @override
- Expression traverseLetCont(LetCont node) {
- node.continuations.forEach(handleDeclaration);
- node.continuations.forEach(push);
-
- // Put all continuations in scope when visiting the body.
- enterScope(node.continuations);
-
- return node.body;
- }
-
- @override
- Expression traverseLetPrim(LetPrim node) {
- handleDeclaration(node.primitive);
-
- // Process references in the primitive.
- visit(node.primitive);
-
- // Put the primitive in scope when visiting the body.
- enterScope([node.primitive]);
-
- return node.body;
- }
-
- @override
- Expression traverseLetMutable(LetMutable node) {
- handleDeclaration(node.variable);
- processReference(node.valueRef);
-
- // Put the primitive in scope when visiting the body.
- enterScope([node.variable]);
-
- return node.body;
- }
-
- @override
- Expression traverseContinuation(Continuation cont) {
- if (cont.isReturnContinuation) {
- error('Non-return continuation missing body', cont);
- }
- cont.parameters.forEach(handleDeclaration);
- enterScope(cont.parameters);
- // Put every continuation in scope at its own body. The isRecursive
- // flag is checked explicitly using [insideContinuations].
- enterScope([cont]);
- enterContinuation(cont);
- return cont.body;
- }
-
- @override
- visitFunctionDefinition(FunctionDefinition node) {
- if (node.interceptorParameter != null) {
- handleDeclaration(node.interceptorParameter);
- enterScope([node.interceptorParameter]);
- }
- if (node.receiverParameter != null) {
- handleDeclaration(node.receiverParameter);
- enterScope([node.receiverParameter]);
- }
- node.parameters.forEach(handleDeclaration);
- enterScope(node.parameters);
- handleDeclaration(node.returnContinuation);
- enterScope([node.returnContinuation]);
- if (!node.returnContinuation.isReturnContinuation) {
- error('Return continuation with a body', node);
- }
- visit(node.body);
- }
-
- @override
- processReference(Reference ref) {
- Definition def = ref.definition;
- if (inScope[def] == ScopeType.NotInScope) {
- error('Referenced out of scope: $def', ref);
- }
- if (ref.previous == ref) {
- error('Shared Reference object to $def', ref);
- }
- if (ref.previous == null && def.firstRef != ref ||
- ref.previous != null && ref.previous.next != ref) {
- error('Broken .previous link in reference to $def', def);
- }
- ref.previous = ref; // Mark reference as "seen". We will repair it later.
- }
-
- @override
- processInvokeContinuation(InvokeContinuation node) {
- Continuation target = node.continuation;
- if (node.isRecursive && inScope[target] == ScopeType.InScope) {
- error('Non-recursive InvokeContinuation marked as recursive', node);
- }
- if (!node.isRecursive && inScope[target] == ScopeType.InDefinition) {
- error('Recursive InvokeContinuation marked as non-recursive', node);
- }
- if (node.isRecursive && !target.isRecursive) {
- error('Recursive Continuation was not marked as recursive', node);
- }
- if (node.argumentRefs.length != target.parameters.length) {
- error('Arity mismatch in InvokeContinuation', node);
- }
- }
-
- @override
- processInvokeMethod(InvokeMethod node) {
- if (node.callingConvention == CallingConvention.Intercepted) {
- if (node.interceptorRef == null) {
- error('No interceptor on intercepted call', node);
- }
- } else {
- if (node.interceptorRef != null) {
- error('Interceptor on call with ${node.callingConvention}', node);
- }
- }
- }
-
- void checkReferenceChain(Definition def) {
- Reference previous = null;
- for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
- if (ref.previous != ref) {
- // Reference was not seen during IR traversal, so it is orphaned.
- error('Orphaned reference in reference chain for $def', def);
- }
- // Repair the .previous link that was used for marking.
- ref.previous = previous;
- previous = ref;
- }
- }
-
- error(String message, node) {
- String sexpr;
- if (ENABLE_DUMP) {
- try {
- Decorator decorator = (n, String s) => n == node ? '**$s**' : s;
- sexpr = new SExpressionStringifier(decorator).visit(topLevelNode);
- sexpr = 'SExpr dump (offending node marked with **):\n\n$sexpr';
- } catch (e) {
- sexpr = '(Exception thrown by SExpressionStringifier: $e)';
- }
- } else {
- sexpr = '(Set DUMP_IR flag to enable SExpr dump)';
- }
- throw 'CPS integrity violation\n'
- 'After \'$previousPass\' on ${topLevelNode.element}\n'
- '$message\n\n'
- '$sexpr\n';
- }
-}
-
-/// Traverses the CPS term and checks that node.parent is correctly set
-/// for each visited node.
-class ParentChecker extends DeepRecursiveVisitor {
- static void checkParents(Node node, CheckCpsIntegrity main) {
- ParentChecker visitor = new ParentChecker._make(main);
- visitor._worklist.add(node);
- visitor.trampoline();
- }
-
- ParentChecker._make(this.main);
-
- Node _parent;
- final List<Node> _worklist = <Node>[];
- final CheckCpsIntegrity main;
-
- void trampoline() {
- while (_worklist.isNotEmpty) {
- _parent = _worklist.removeLast();
- _parent.accept(this);
- }
- }
-
- error(String message, node) => main.error(message, node);
-
- @override
- visit(Node node) {
- _worklist.add(node);
- if (node.parent != _parent) {
- error('Parent pointer on $node is ${node.parent} but should be $_parent',
- node);
- }
- }
-
- @override
- processReference(Reference node) {
- if (node.parent != _parent) {
- error('Parent pointer on $node is ${node.parent} but should be $_parent',
- node);
- }
- }
-}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.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