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

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

Issue 1251083002: dart2js cps: Avoid deep recursion using trampolines and basic blocks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Rebase Created 5 years, 5 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 | « no previous file | 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
index 0d7c066ce0b6a7dec44d17c2310d8ab34d15cff4..88faa4d5713549ae7a928e3771f306e1dacc4cf9 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
@@ -32,19 +32,9 @@ class CheckCpsIntegrity extends RecursiveVisitor {
Map<Definition, Set<Reference>> seenReferences =
<Definition, Set<Reference>>{};
- Map<Definition, Node> bindings = <Definition, Node>{};
+ Set<Definition> inScope = new Set<Definition>();
Set<Continuation> insideContinuations = new Set<Continuation>();
- doInScope(Iterable<Definition> defs, Node binding, action()) {
- for (Definition def in defs) {
- bindings[def] = binding;
- }
- action();
- for (Definition def in defs) {
- bindings.remove(def);
- }
- }
-
void markAsSeen(Definition def) {
if (!seenDefinitions.add(def)) {
error('Redeclared $def', def);
@@ -52,70 +42,92 @@ class CheckCpsIntegrity extends RecursiveVisitor {
seenReferences[def] = new Set<Reference>();
}
- @override
- visitLetCont(LetCont node) {
- // Analyze each continuation separately without the others in scope.
- for (Continuation continuation in node.continuations) {
- // We always consider a continuation to be in scope of itself.
- // The isRecursive flag is checked explicitly to give more useful
- // error messages.
- doInScope([continuation], node, () => visit(continuation));
- }
- // Analyze the body with all continuations in scope.
- doInScope(node.continuations, node, () => visit(node.body));
+ void enterScope(Iterable<Definition> definitions) {
+ inScope.addAll(definitions);
+ pushAction(() => inScope.removeAll(definitions));
+ }
+
+ void enterContinuation(Continuation cont) {
+ insideContinuations.add(cont);
+ pushAction(() => insideContinuations.remove(cont));
+ }
+
+ void check(FunctionDefinition node) {
+ topLevelNode = node;
+ visit(node);
+ // Check for broken reference chains. We check this last, so out-of-scope
+ // references are not classified as a broken reference chain.
+ seenDefinitions.forEach(checkReferenceChain);
}
@override
- visitContinuation(Continuation node) {
- markAsSeen(node);
- if (node.isReturnContinuation) {
- error('Non-return continuation missing body', node);
- }
- node.parameters.forEach(markAsSeen);
- insideContinuations.add(node);
- doInScope(node.parameters, node, () => visit(node.body));
- insideContinuations.remove(node);
+ Expression traverseLetCont(LetCont node) {
+ node.continuations.forEach(markAsSeen);
+ node.continuations.forEach(push);
+
+ // Put all continuations in scope when visiting the body.
+ enterScope(node.continuations);
+
+ return node.body;
}
@override
- visitLetPrim(LetPrim node) {
+ Expression traverseLetPrim(LetPrim node) {
markAsSeen(node.primitive);
+
+ // Process references in the primitive.
visit(node.primitive);
- doInScope([node.primitive], node, () => visit(node.body));
+
+ // Put the primitive in scope when visiting the body.
+ enterScope([node.primitive]);
+
+ return node.body;
}
@override
- visitLetMutable(LetMutable node) {
+ Expression traverseLetMutable(LetMutable node) {
markAsSeen(node.variable);
processReference(node.value);
- doInScope([node.variable], node, () => visit(node.body));
+
+ // 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(markAsSeen);
+ 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.thisParameter != null) {
markAsSeen(node.thisParameter);
+ enterScope([node.thisParameter]);
}
node.parameters.forEach(markAsSeen);
+ enterScope(node.parameters);
markAsSeen(node.returnContinuation);
+ enterScope([node.returnContinuation]);
if (!node.returnContinuation.isReturnContinuation) {
error('Return continuation with a body', node);
}
- doInOptionalScope(node.thisParameter, node,
- () => doInScope(node.parameters, node,
- () => doInScope([node.returnContinuation], node,
- () => visit(node.body))));
- }
-
- doInOptionalScope(Parameter parameter, Node node, action) {
- return (parameter == null)
- ? action()
- : doInScope([parameter], node, action);
+ visit(node.body);
}
@override
processReference(Reference reference) {
- if (!bindings.containsKey(reference.definition)) {
+ if (!inScope.contains(reference.definition)) {
error('Referenced out of scope: ${reference.definition}', reference);
}
if (!seenReferences[reference.definition].add(reference)) {
@@ -181,13 +193,4 @@ class CheckCpsIntegrity extends RecursiveVisitor {
'$sexpr\n';
}
- void check(FunctionDefinition node) {
- topLevelNode = node;
- visit(node);
-
- // Check this last, so out-of-scope references are not classified as
- // a broken reference chain.
- seenDefinitions.forEach(checkReferenceChain);
- }
-
}
« no previous file with comments | « no previous file | 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