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

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: 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 StringIndexer _stringIndexer;
ahe 2017/05/22 09:27:05 You can keep this final by adding an optional para
ahe 2017/05/22 09:27:05 Seems like you need this field to be public.
scheglov 2017/05/22 20:36:01 Done.
scheglov 2017/05/22 20:36:01 Done.
23 final StringIndexer _sourceUriIndexer = new StringIndexer(); 23 final StringIndexer _sourceUriIndexer = new StringIndexer();
24 Map<DeferredImport, int> _deferredImportIndexer = <DeferredImport, int>{}; 24 Map<DeferredImport, int> _deferredImportIndexer = <DeferredImport, int>{};
25 25
26 final BufferedSink _sink; 26 final BufferedSink _sink;
27 27
28 /// Create a printer that writes to the given [sink]. 28 /// Create a printer that writes to the given [sink].
29 /// 29 ///
30 /// The BinaryPrinter will use its own buffer, so the [sink] does not need 30 /// The BinaryPrinter will use its own buffer, so the [sink] does not need
31 /// one. 31 /// one.
32 /// 32 ///
33 /// If multiple binaries are to be written based on the same IR, a shared 33 /// If multiple binaries are to be written based on the same IR, a shared
34 /// [globalIndexer] may be passed in to avoid rebuilding the same indices 34 /// [globalIndexer] may be passed in to avoid rebuilding the same indices
35 /// in every printer. 35 /// in every printer.
36 BinaryPrinter(Sink<List<int>> sink) : _sink = new BufferedSink(sink); 36 BinaryPrinter(Sink<List<int>> sink) : _sink = new BufferedSink(sink) {
37 _stringIndexer = createStringIndexer();
38 }
39
40 StringIndexer createStringIndexer() => new StringIndexer();
37 41
38 void _flush() { 42 void _flush() {
39 _sink.flushAndDestroy(); 43 _sink.flushAndDestroy();
40 } 44 }
41 45
42 void writeByte(int byte) { 46 void writeByte(int byte) {
43 _sink.addByte(byte); 47 _sink.addByte(byte);
44 } 48 }
45 49
46 void writeBytes(List<int> bytes) { 50 void writeBytes(List<int> bytes) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 129
126 void writeLinkTable(Program program) { 130 void writeLinkTable(Program program) {
127 List<CanonicalName> list = <CanonicalName>[]; 131 List<CanonicalName> list = <CanonicalName>[];
128 void visitCanonicalName(CanonicalName node) { 132 void visitCanonicalName(CanonicalName node) {
129 node.index = list.length; 133 node.index = list.length;
130 list.add(node); 134 list.add(node);
131 node.children.forEach(visitCanonicalName); 135 node.children.forEach(visitCanonicalName);
132 } 136 }
133 137
134 for (var library in program.libraries) { 138 for (var library in program.libraries) {
139 if (!shouldWriteLibraryCanonicalNames(library)) continue;
135 visitCanonicalName(library.canonicalName); 140 visitCanonicalName(library.canonicalName);
136 } 141 }
142 addCanonicalNamesForLinkTable(list);
137 writeList(list, writeCanonicalNameEntry); 143 writeList(list, writeCanonicalNameEntry);
138 } 144 }
139 145
146 /// Return `true` if all canonical names of the [library] should be written
147 /// into the link table. If some libraries of the program are skipped,
148 /// then [addCanonicalNamesForLinkTable] should append all the additional
149 /// names referenced by the libraries that are written by [writeLibraries].
150 bool shouldWriteLibraryCanonicalNames(Library library) => true;
151
152 /// Append additional names for entities that are referenced by the
153 /// libraries that are written by [writeLibraries], but declared outside
154 /// of these libraries.
155 void addCanonicalNamesForLinkTable(List<CanonicalName> list) {}
156
140 void writeCanonicalNameEntry(CanonicalName node) { 157 void writeCanonicalNameEntry(CanonicalName node) {
141 var parent = node.parent; 158 var parent = node.parent;
142 if (parent.isRoot) { 159 if (parent.isRoot) {
143 writeByte(0); 160 writeByte(0);
144 } else { 161 } else {
145 writeUInt30(parent.index + 1); 162 writeUInt30(parent.index + 1);
146 } 163 }
147 writeStringReference(node.name); 164 writeStringReference(node.name);
148 } 165 }
149 166
150 void writeProgramFile(Program program) { 167 void writeProgramFile(Program program) {
151 program.computeCanonicalNames(); 168 program.computeCanonicalNames();
152 writeMagicWord(Tag.ProgramFile); 169 writeMagicWord(Tag.ProgramFile);
153 _stringIndexer.scanProgram(program); 170 buildStringIndex(program);
154 writeStringTable(_stringIndexer); 171 writeStringTable(_stringIndexer);
155 writeUriToSource(program); 172 writeUriToSource(program);
156 writeLinkTable(program); 173 writeLinkTable(program);
157 writeList(program.libraries, writeNode); 174 writeLibraries(program);
158 writeMemberReference(program.mainMethod, allowNull: true); 175 writeMemberReference(program.mainMethod, allowNull: true);
159 _flush(); 176 _flush();
160 } 177 }
161 178
179 /// Fill the [_stringIndexer] with all strings we are going to reference.
180 void buildStringIndex(Program program) {
181 _stringIndexer.scanProgram(program);
182 }
183
184 /// Write all of some of the libraries of the [program].
185 void writeLibraries(Program program) {
186 writeList(program.libraries, writeNode);
187 }
188
162 void writeUriToSource(Program program) { 189 void writeUriToSource(Program program) {
163 program.uriToSource.keys.forEach((uri) { 190 program.uriToSource.keys.forEach((uri) {
164 _sourceUriIndexer.put(uri); 191 _sourceUriIndexer.put(uri);
165 }); 192 });
166 writeStringTable(_sourceUriIndexer); 193 writeStringTable(_sourceUriIndexer);
167 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) { 194 for (int i = 0; i < _sourceUriIndexer.entries.length; i++) {
168 String uri = _sourceUriIndexer.entries[i].value; 195 String uri = _sourceUriIndexer.entries[i].value;
169 Source source = 196 Source source =
170 program.uriToSource[uri] ?? new Source(<int>[], const <int>[]); 197 program.uriToSource[uri] ?? new Source(<int>[], const <int>[]);
171 writeUtf8Bytes(source.source); 198 writeUtf8Bytes(source.source);
(...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 class StringIndexer extends RecursiveVisitor<Null> { 1203 class StringIndexer extends RecursiveVisitor<Null> {
1177 final List<StringTableEntry> entries = <StringTableEntry>[]; 1204 final List<StringTableEntry> entries = <StringTableEntry>[];
1178 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>(); 1205 final LinkedHashMap<String, int> index = new LinkedHashMap<String, int>();
1179 1206
1180 StringIndexer() { 1207 StringIndexer() {
1181 put(''); 1208 put('');
1182 } 1209 }
1183 1210
1184 int get numberOfStrings => index.length; 1211 int get numberOfStrings => index.length;
1185 1212
1186 void scanProgram(Node node) { 1213 /// Scan all the [program] libraries and [finish] indexing.
1187 node.accept(this); 1214 void scanProgram(Program program) {
1215 program.accept(this);
1216 finish();
1217 }
1218
1219 /// Scan the given library, but don't [finish] indexing yet.
1220 void scanLibrary(Library library) {
1221 library.accept(this);
1222 }
1223
1224 /// Finish building of the index - sort and assign indices for entries.
1225 void finish() {
1188 entries.sort(); 1226 entries.sort();
1189 for (int i = 0; i < entries.length; ++i) { 1227 for (int i = 0; i < entries.length; ++i) {
1190 index[entries[i].value] = i; 1228 index[entries[i].value] = i;
1191 } 1229 }
1192 } 1230 }
1193 1231
1194 void visitCanonicalName(CanonicalName name) { 1232 void visitCanonicalName(CanonicalName name) {
1195 put(name.name); 1233 put(name.name);
1196 name.children.forEach(visitCanonicalName); 1234 name.children.forEach(visitCanonicalName);
1197 } 1235 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 _sink.add(_buffer.sublist(0, length)); 1419 _sink.add(_buffer.sublist(0, length));
1382 _buffer = new Uint8List(SIZE); 1420 _buffer = new Uint8List(SIZE);
1383 flushedLength += length; 1421 flushedLength += length;
1384 length = 0; 1422 length = 0;
1385 } 1423 }
1386 1424
1387 void flushAndDestroy() { 1425 void flushAndDestroy() {
1388 _sink.add(_buffer.sublist(0, length)); 1426 _sink.add(_buffer.sublist(0, length));
1389 } 1427 }
1390 } 1428 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698