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

Side by Side Diff: pkg/kernel/lib/binary/ast_to_binary.dart

Issue 2896493002: Add LimitedBinaryPrinter, tests and switch incremental generator to it. (Closed)
Patch Set: Move LimitedBinaryPrinter to kernel, remove comments. Created 3 years, 7 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.ast_to_binary; 4 library kernel.ast_to_binary;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../import_table.dart'; 7 import '../import_table.dart';
8 import 'tag.dart'; 8 import 'tag.dart';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:typed_data'; 10 import 'dart:typed_data';
11 import 'dart:collection'; 11 import 'dart:collection';
12 12
13 /// Writes to a binary file. 13 /// Writes to a binary file.
14 /// 14 ///
15 /// A [BinaryPrinter] can be used to write one file and must then be 15 /// A [BinaryPrinter] can be used to write one file and must then be
16 /// discarded. 16 /// discarded.
17 class BinaryPrinter extends Visitor { 17 class BinaryPrinter extends Visitor {
18 VariableIndexer _variableIndexer; 18 VariableIndexer _variableIndexer;
19 LabelIndexer _labelIndexer; 19 LabelIndexer _labelIndexer;
20 SwitchCaseIndexer _switchCaseIndexer; 20 SwitchCaseIndexer _switchCaseIndexer;
21 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer(); 21 final TypeParameterIndexer _typeParameterIndexer = new TypeParameterIndexer();
22 final StringIndexer _stringIndexer = new StringIndexer(); 22 final StringIndexer stringIndexer;
23 final StringIndexer _sourceUriIndexer = new StringIndexer(); 23 final StringIndexer _sourceUriIndexer = new StringIndexer();
24 Map<LibraryDependency, int> _libraryDependencyIndex = 24 Map<LibraryDependency, int> _libraryDependencyIndex =
25 <LibraryDependency, int>{}; 25 <LibraryDependency, int>{};
26 26
27 final BufferedSink _sink; 27 final BufferedSink _sink;
28 28
29 /// Create a printer that writes to the given [sink]. 29 /// Create a printer that writes to the given [sink].
30 /// 30 ///
31 /// The BinaryPrinter will use its own buffer, so the [sink] does not need 31 /// The BinaryPrinter will use its own buffer, so the [sink] does not need
32 /// one. 32 /// one.
33 /// 33 ///
34 /// If multiple binaries are to be written based on the same IR, a shared 34 /// If multiple binaries are to be written based on the same IR, a shared
35 /// [globalIndexer] may be passed in to avoid rebuilding the same indices 35 /// [globalIndexer] may be passed in to avoid rebuilding the same indices
36 /// in every printer. 36 /// in every printer.
37 BinaryPrinter(Sink<List<int>> sink) : _sink = new BufferedSink(sink); 37 BinaryPrinter(Sink<List<int>> sink, {StringIndexer stringIndexer})
38 : _sink = new BufferedSink(sink),
39 stringIndexer = stringIndexer ?? new StringIndexer();
38 40
39 void _flush() { 41 void _flush() {
40 _sink.flushAndDestroy(); 42 _sink.flushAndDestroy();
41 } 43 }
42 44
43 void writeByte(int byte) { 45 void writeByte(int byte) {
44 _sink.addByte(byte); 46 _sink.addByte(byte);
45 } 47 }
46 48
47 void writeBytes(List<int> bytes) { 49 void writeBytes(List<int> bytes) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 endOffset += entry.utf8Bytes.length; 85 endOffset += entry.utf8Bytes.length;
84 writeUInt30(endOffset); 86 writeUInt30(endOffset);
85 } 87 }
86 // Write the UTF-8 encoded strings. 88 // Write the UTF-8 encoded strings.
87 for (var entry in indexer.entries) { 89 for (var entry in indexer.entries) {
88 writeBytes(entry.utf8Bytes); 90 writeBytes(entry.utf8Bytes);
89 } 91 }
90 } 92 }
91 93
92 void writeStringReference(String string) { 94 void writeStringReference(String string) {
93 writeUInt30(_stringIndexer[string]); 95 writeUInt30(stringIndexer[string]);
94 } 96 }
95 97
96 void writeStringReferenceList(List<String> strings) { 98 void writeStringReferenceList(List<String> strings) {
97 writeList(strings, writeStringReference); 99 writeList(strings, writeStringReference);
98 } 100 }
99 101
100 void writeUriReference(String string) { 102 void writeUriReference(String string) {
101 int index = _sourceUriIndexer[string]; 103 int index = _sourceUriIndexer[string];
102 if (index == null) { 104 if (index == null) {
103 // Assume file was loaded without linking. Bail out to empty string. 105 // Assume file was loaded without linking. Bail out to empty string.
(...skipping 26 matching lines...) Expand all
130 132
131 void writeLinkTable(Program program) { 133 void writeLinkTable(Program program) {
132 List<CanonicalName> list = <CanonicalName>[]; 134 List<CanonicalName> list = <CanonicalName>[];
133 void visitCanonicalName(CanonicalName node) { 135 void visitCanonicalName(CanonicalName node) {
134 node.index = list.length; 136 node.index = list.length;
135 list.add(node); 137 list.add(node);
136 node.children.forEach(visitCanonicalName); 138 node.children.forEach(visitCanonicalName);
137 } 139 }
138 140
139 for (var library in program.libraries) { 141 for (var library in program.libraries) {
142 if (!shouldWriteLibraryCanonicalNames(library)) continue;
140 visitCanonicalName(library.canonicalName); 143 visitCanonicalName(library.canonicalName);
141 } 144 }
145 addCanonicalNamesForLinkTable(list);
142 writeList(list, writeCanonicalNameEntry); 146 writeList(list, writeCanonicalNameEntry);
143 } 147 }
144 148
149 /// Return `true` if all canonical names of the [library] should be written
150 /// into the link table. If some libraries of the program are skipped,
151 /// then [addCanonicalNamesForLinkTable] should append all the additional
152 /// names referenced by the libraries that are written by [writeLibraries].
153 bool shouldWriteLibraryCanonicalNames(Library library) => true;
154
155 /// Append additional names for entities that are referenced by the
156 /// libraries that are written by [writeLibraries], but declared outside
157 /// of these libraries.
158 void addCanonicalNamesForLinkTable(List<CanonicalName> list) {}
159
145 void writeCanonicalNameEntry(CanonicalName node) { 160 void writeCanonicalNameEntry(CanonicalName node) {
146 var parent = node.parent; 161 var parent = node.parent;
147 if (parent.isRoot) { 162 if (parent.isRoot) {
148 writeByte(0); 163 writeByte(0);
149 } else { 164 } else {
150 writeUInt30(parent.index + 1); 165 writeUInt30(parent.index + 1);
151 } 166 }
152 writeStringReference(node.name); 167 writeStringReference(node.name);
153 } 168 }
154 169
155 void writeProgramFile(Program program) { 170 void writeProgramFile(Program program) {
156 program.computeCanonicalNames(); 171 program.computeCanonicalNames();
157 writeMagicWord(Tag.ProgramFile); 172 writeMagicWord(Tag.ProgramFile);
158 _stringIndexer.scanProgram(program); 173 buildStringIndex(program);
159 writeStringTable(_stringIndexer); 174 writeStringTable(stringIndexer);
160 writeUriToSource(program); 175 writeUriToSource(program);
161 writeLinkTable(program); 176 writeLinkTable(program);
162 writeList(program.libraries, writeNode); 177 writeLibraries(program);
163 writeMemberReference(program.mainMethod, allowNull: true); 178 writeMemberReference(program.mainMethod, allowNull: true);
164 _flush(); 179 _flush();
165 } 180 }
166 181
182 /// Fill the [stringIndexer] with all strings we are going to reference.
183 void buildStringIndex(Program program) {
184 stringIndexer.scanProgram(program);
185 }
186
187 /// Write all of some of the libraries of the [program].
188 void writeLibraries(Program program) {
189 writeList(program.libraries, writeNode);
190 }
191
167 void writeUriToSource(Program program) { 192 void writeUriToSource(Program program) {
168 program.uriToSource.keys.forEach((uri) { 193 program.uriToSource.keys.forEach((uri) {
169 _sourceUriIndexer.put(uri); 194 _sourceUriIndexer.put(uri);
170 }); 195 });
171 writeStringTable(_sourceUriIndexer); 196 writeStringTable(_sourceUriIndexer);
172 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) { 197 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) {
173 String uri = _sourceUriIndexer.entries[i].value; 198 String uri = _sourceUriIndexer.entries[i].value;
174 Source source = 199 Source source =
175 program.uriToSource[uri] ?? new Source(<int>[], const <int>[]); 200 program.uriToSource[uri] ?? new Source(<int>[], const <int>[]);
176 writeUtf8Bytes(source.source); 201 writeUtf8Bytes(source.source);
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 final LibraryFilter predicate; 1107 final LibraryFilter predicate;
1083 1108
1084 LibraryFilteringBinaryPrinter( 1109 LibraryFilteringBinaryPrinter(
1085 Sink<List<int>> sink, bool predicate(Library library)) 1110 Sink<List<int>> sink, bool predicate(Library library))
1086 : predicate = predicate, 1111 : predicate = predicate,
1087 super(sink); 1112 super(sink);
1088 1113
1089 void writeProgramFile(Program program) { 1114 void writeProgramFile(Program program) {
1090 program.computeCanonicalNames(); 1115 program.computeCanonicalNames();
1091 writeMagicWord(Tag.ProgramFile); 1116 writeMagicWord(Tag.ProgramFile);
1092 _stringIndexer.scanProgram(program); 1117 stringIndexer.scanProgram(program);
1093 writeStringTable(_stringIndexer); 1118 writeStringTable(stringIndexer);
1094 writeUriToSource(program); 1119 writeUriToSource(program);
1095 writeLinkTable(program); 1120 writeLinkTable(program);
1096 writeList(program.libraries.where(predicate).toList(), writeNode); 1121 writeList(program.libraries.where(predicate).toList(), writeNode);
1097 writeMemberReference(program.mainMethod, allowNull: true); 1122 writeMemberReference(program.mainMethod, allowNull: true);
1098 _flush(); 1123 _flush();
1099 } 1124 }
1100 } 1125 }
1101 1126
1102 class VariableIndexer { 1127 class VariableIndexer {
1103 final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{}; 1128 final Map<VariableDeclaration, int> index = <VariableDeclaration, int>{};
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 class StringIndexer extends RecursiveVisitor<Null> { 1215 class StringIndexer extends RecursiveVisitor<Null> {
1191 final List<StringTableEntry> entries = <StringTableEntry>[]; 1216 final List<StringTableEntry> entries = <StringTableEntry>[];
1192 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>(); 1217 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
1193 1218
1194 StringIndexer() { 1219 StringIndexer() {
1195 put(''); 1220 put('');
1196 } 1221 }
1197 1222
1198 int get numberOfStrings => index.length; 1223 int get numberOfStrings => index.length;
1199 1224
1200 void scanProgram(Node node) { 1225 /// Scan all the [program] libraries and [finish] indexing.
1201 node.accept(this); 1226 void scanProgram(Program program) {
1227 program.accept(this);
1228 finish();
1229 }
1230
1231 /// Scan the given library, but don't [finish] indexing yet.
1232 void scanLibrary(Library library) {
1233 library.accept(this);
1234 }
1235
1236 /// Finish building of the index - sort and assign indices for entries.
1237 void finish() {
1202 entries.sort(); 1238 entries.sort();
1203 for (int i = 0; i < entries.length; ++i) { 1239 for (int i = 0; i < entries.length; ++i) {
1204 index[entries[i].value] = i; 1240 index[entries[i].value] = i;
1205 } 1241 }
1206 } 1242 }
1207 1243
1208 void visitCanonicalName(CanonicalName name) { 1244 void visitCanonicalName(CanonicalName name) {
1209 put(name.name); 1245 put(name.name);
1210 name.children.forEach(visitCanonicalName); 1246 name.children.forEach(visitCanonicalName);
1211 } 1247 }
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 _sink.add(_buffer.sublist(0, length)); 1441 _sink.add(_buffer.sublist(0, length));
1406 _buffer = new Uint8List(SIZE); 1442 _buffer = new Uint8List(SIZE);
1407 flushedLength += length; 1443 flushedLength += length;
1408 length = 0; 1444 length = 0;
1409 } 1445 }
1410 1446
1411 void flushAndDestroy() { 1447 void flushAndDestroy() {
1412 _sink.add(_buffer.sublist(0, length)); 1448 _sink.add(_buffer.sublist(0, length));
1413 } 1449 }
1414 } 1450 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698