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

Unified Diff: lib/binary/ast_to_binary.dart

Issue 2507723002: Remove unnecessary indexing passes from serialization. (Closed)
Patch Set: Add copyright 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 | « no previous file | test/serialize_bench.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/binary/ast_to_binary.dart
diff --git a/lib/binary/ast_to_binary.dart b/lib/binary/ast_to_binary.dart
index 4e05ca45adedc678cf0fbd898219caf7502e6655..0c628f83cbdda5dae32ce05307ba7e12a27d4bfb 100644
--- a/lib/binary/ast_to_binary.dart
+++ b/lib/binary/ast_to_binary.dart
@@ -17,7 +17,6 @@ import 'dart:collection';
class BinaryPrinter extends Visitor {
ImportTable _importTable;
- // TODO: We can do the indexing on-the-fly, but for now just keep it simple.
VariableIndexer _variableIndexer;
LabelIndexer _labelIndexer;
SwitchCaseIndexer _switchCaseIndexer;
@@ -274,7 +273,6 @@ class BinaryPrinter extends Visitor {
void writeAnnotation(Expression annotation) {
_variableIndexer ??= new VariableIndexer();
- _variableIndexer.build(annotation);
writeNode(annotation);
}
@@ -293,45 +291,49 @@ class BinaryPrinter extends Visitor {
writeStringReference(node.name ?? '');
writeUriReference(node.fileUri ?? '');
writeAnnotationList(node.annotations);
- _typeParameterIndexer.push(node.typeParameters);
+ _typeParameterIndexer.enter(node.typeParameters);
writeNodeList(node.typeParameters);
writeNode(node.supertype);
writeNode(node.mixedInType);
writeNodeList(node.implementedTypes);
writeNodeList(node.constructors);
- _typeParameterIndexer.pop(node.typeParameters);
+ _typeParameterIndexer.exit(node.typeParameters);
} else {
writeByte(Tag.NormalClass);
writeByte(flags);
writeStringReference(node.name ?? '');
writeUriReference(node.fileUri ?? '');
writeAnnotationList(node.annotations);
- _typeParameterIndexer.push(node.typeParameters);
+ _typeParameterIndexer.enter(node.typeParameters);
writeNodeList(node.typeParameters);
writeOptionalNode(node.supertype);
writeNodeList(node.implementedTypes);
writeNodeList(node.fields);
writeNodeList(node.constructors);
writeNodeList(node.procedures);
- _typeParameterIndexer.pop(node.typeParameters);
+ _typeParameterIndexer.exit(node.typeParameters);
}
}
static final Name _emptyName = new Name('');
visitConstructor(Constructor node) {
- _variableIndexer = new VariableIndexer()..build(node);
+ _variableIndexer = new VariableIndexer();
writeByte(Tag.Constructor);
writeByte(node.flags);
writeName(node.name ?? _emptyName);
writeAnnotationList(node.annotations);
assert(node.function.typeParameters.isEmpty);
writeNode(node.function);
+ // Parameters are in scope in the initializers.
+ _variableIndexer.restoreScope(node.function.positionalParameters.length +
+ node.function.namedParameters.length);
writeNodeList(node.initializers);
+ _variableIndexer = null;
}
visitProcedure(Procedure node) {
- _variableIndexer = new VariableIndexer()..build(node);
+ _variableIndexer = new VariableIndexer();
writeByte(Tag.Procedure);
writeByte(node.kind.index);
writeByte(node.flags);
@@ -339,10 +341,11 @@ class BinaryPrinter extends Visitor {
writeUriReference(node.fileUri ?? '');
writeAnnotationList(node.annotations);
writeOptionalNode(node.function);
+ _variableIndexer = null;
}
visitField(Field node) {
- _variableIndexer = new VariableIndexer()..build(node);
+ _variableIndexer = new VariableIndexer();
writeByte(Tag.Field);
writeOffset(node);
writeByte(node.flags);
@@ -352,6 +355,7 @@ class BinaryPrinter extends Visitor {
writeNode(node.type);
writeOptionalInferredValue(node.inferredValue);
writeOptionalNode(node.initializer);
+ _variableIndexer = null;
}
visitInvalidInitializer(InvalidInitializer node) {
@@ -383,12 +387,13 @@ class BinaryPrinter extends Visitor {
visitFunctionNode(FunctionNode node) {
assert(_variableIndexer != null);
+ _variableIndexer.pushScope();
var oldLabels = _labelIndexer;
- _labelIndexer = new LabelIndexer()..build(node);
+ _labelIndexer = new LabelIndexer();
var oldCases = _switchCaseIndexer;
- _switchCaseIndexer = new SwitchCaseIndexer()..build(node);
+ _switchCaseIndexer = new SwitchCaseIndexer();
// Note: FunctionNode has no tag.
- _typeParameterIndexer.push(node.typeParameters);
+ _typeParameterIndexer.enter(node.typeParameters);
writeByte(node.asyncMarker.index);
writeNodeList(node.typeParameters);
writeUInt30(node.requiredParameterCount);
@@ -399,7 +404,8 @@ class BinaryPrinter extends Visitor {
writeOptionalNode(node.body);
_labelIndexer = oldLabels;
_switchCaseIndexer = oldCases;
- _typeParameterIndexer.pop(node.typeParameters);
+ _typeParameterIndexer.exit(node.typeParameters);
+ _variableIndexer.popScope();
}
visitInvalidExpression(InvalidExpression node) {
@@ -683,6 +689,7 @@ class BinaryPrinter extends Visitor {
writeByte(Tag.Let);
writeVariableDeclaration(node.variable);
writeNode(node.body);
+ --_variableIndexer.stackHeight;
}
writeStatementOrEmpty(Statement node) {
@@ -703,8 +710,10 @@ class BinaryPrinter extends Visitor {
}
visitBlock(Block node) {
+ _variableIndexer.pushScope();
writeByte(Tag.Block);
writeNodeList(node.statements);
+ _variableIndexer.popScope();
}
visitEmptyStatement(EmptyStatement node) {
@@ -718,8 +727,10 @@ class BinaryPrinter extends Visitor {
}
visitLabeledStatement(LabeledStatement node) {
+ _labelIndexer.enter(node);
writeByte(Tag.LabeledStatement);
writeNode(node.body);
+ _labelIndexer.exit();
}
visitBreakStatement(BreakStatement node) {
@@ -740,24 +751,30 @@ class BinaryPrinter extends Visitor {
}
visitForStatement(ForStatement node) {
+ _variableIndexer.pushScope();
writeByte(Tag.ForStatement);
writeVariableDeclarationList(node.variables);
writeOptionalNode(node.condition);
writeNodeList(node.updates);
writeNode(node.body);
+ _variableIndexer.popScope();
}
visitForInStatement(ForInStatement node) {
+ _variableIndexer.pushScope();
writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement);
writeVariableDeclaration(node.variable);
writeNode(node.iterable);
writeNode(node.body);
+ _variableIndexer.popScope();
}
visitSwitchStatement(SwitchStatement node) {
+ _switchCaseIndexer.enter(node);
writeByte(Tag.SwitchStatement);
writeNode(node.expression);
writeNodeList(node.cases);
+ _switchCaseIndexer.exit(node);
}
visitSwitchCase(SwitchCase node) {
@@ -792,10 +809,12 @@ class BinaryPrinter extends Visitor {
visitCatch(Catch node) {
// Note: there is no tag on Catch.
+ _variableIndexer.pushScope();
writeNode(node.guard);
writeOptionalVariableDeclaration(node.exception);
writeOptionalVariableDeclaration(node.stackTrace);
writeNode(node.body);
+ _variableIndexer.popScope();
}
visitTryFinally(TryFinally node) {
@@ -821,6 +840,9 @@ class BinaryPrinter extends Visitor {
writeNode(node.type);
writeOptionalInferredValue(node.inferredValue);
writeOptionalNode(node.initializer);
+ // Declare the variable after its initializer. It is not in scope in its
+ // own initializer.
+ _variableIndexer.declare(node);
}
void writeVariableDeclarationList(List<VariableDeclaration> nodes) {
@@ -889,7 +911,7 @@ class BinaryPrinter extends Visitor {
writeNode(node.returnType);
} else {
writeByte(Tag.FunctionType);
- _typeParameterIndexer.push(node.typeParameters);
+ _typeParameterIndexer.enter(node.typeParameters);
writeNodeList(node.typeParameters);
writeUInt30(node.requiredParameterCount);
writeNodeList(node.positionalParameters);
@@ -898,7 +920,7 @@ class BinaryPrinter extends Visitor {
writeNode(node.namedParameters[name]);
});
writeNode(node.returnType);
- _typeParameterIndexer.pop(node.typeParameters);
+ _typeParameterIndexer.exit(node.typeParameters);
}
}
@@ -917,132 +939,76 @@ class BinaryPrinter extends Visitor {
}
}
-class VariableIndexer extends RecursiveVisitor {
+class VariableIndexer {
final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{};
+ final List<int> scopes = <int>[];
int stackHeight = 0;
- void build(TreeNode node) => node.accept(this);
-
- visitConstructor(Constructor node) {
- node.function.accept(this);
- // Keep parameters in scope when traversing initializers.
- stackHeight = node.function.positionalParameters.length +
- node.function.namedParameters.length;
- for (var init in node.initializers) {
- init.accept(this);
- }
- stackHeight = 0;
+ void declare(VariableDeclaration node) {
+ index[node] = stackHeight++;
}
- visitFunctionNode(FunctionNode node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
+ void pushScope() {
+ scopes.add(stackHeight);
}
- visitBlock(Block node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
+ void popScope() {
+ stackHeight = scopes.removeLast();
}
- visitLet(Let node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
+ void restoreScope(int numberOfVariables) {
+ stackHeight += numberOfVariables;
}
- visitForInStatement(ForInStatement node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
- }
-
- visitForStatement(ForStatement node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
- }
-
- visitCatch(Catch node) {
- int frame = stackHeight;
- node.visitChildren(this);
- stackHeight = frame;
+ int operator [](VariableDeclaration node) {
+ return index[node];
}
-
- visitVariableDeclaration(VariableDeclaration node) {
- node.visitChildren(this);
- assert(!index.containsKey(node));
- index[node] = stackHeight;
- ++stackHeight;
- }
-
- int operator [](VariableDeclaration node) => index[node];
}
-class LabelIndexer extends RecursiveVisitor {
+class LabelIndexer {
final Map<LabeledStatement, int> index = <LabeledStatement, int>{};
int stackHeight = 0;
- void build(FunctionNode node) => node.visitChildren(this);
-
- visitFunctionNode(FunctionNode node) {
- // Inhibit traversal into nested functions.
- // The client must create a separate label indexer for the
- // nested function.
+ void enter(LabeledStatement node) {
+ index[node] = stackHeight++;
}
- visitLabeledStatement(LabeledStatement node) {
- index[node] = stackHeight;
- ++stackHeight;
- node.visitChildren(this);
+ void exit() {
--stackHeight;
}
int operator [](LabeledStatement node) => index[node];
}
-class SwitchCaseIndexer extends RecursiveVisitor {
+class SwitchCaseIndexer {
final Map<SwitchCase, int> index = <SwitchCase, int>{};
int stackHeight = 0;
- void build(FunctionNode node) => node.visitChildren(this);
-
- visitFunctionNode(FunctionNode node) {
- // Inhibit traversal into nested functions.
- // The client must create a separate case indexer for the
- // nested function.
- }
-
- visitSwitchStatement(SwitchStatement node) {
- int oldHeight = stackHeight;
+ void enter(SwitchStatement node) {
for (var caseNode in node.cases) {
- index[caseNode] = stackHeight;
- ++stackHeight;
+ index[caseNode] = stackHeight++;
}
- node.visitChildren(this);
- stackHeight = oldHeight;
+ }
+
+ void exit(SwitchStatement node) {
+ stackHeight -= node.cases.length;
}
int operator [](SwitchCase node) => index[node];
}
-/// The type parameter indexer works differently from the other indexers because
-/// type parameters can be bound inside DartTypes, which can be shared by the
-/// in-memory representation (but not the binary form) and the index depends on
-/// the use site.
class TypeParameterIndexer {
final Map<TypeParameter, int> index = <TypeParameter, int>{};
int stackHeight = 0;
- void push(List<TypeParameter> typeParameters) {
+ void enter(List<TypeParameter> typeParameters) {
for (var parameter in typeParameters) {
index[parameter] = stackHeight;
++stackHeight;
}
}
- void pop(List<TypeParameter> typeParameters) {
+ void exit(List<TypeParameter> typeParameters) {
stackHeight -= typeParameters.length;
}
« no previous file with comments | « no previous file | test/serialize_bench.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698