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

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

Issue 2790093002: Hacky streaming of VariableGet (Closed)
Patch Set: Created 3 years, 8 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';
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 386 }
387 387
388 visitRedirectingInitializer(RedirectingInitializer node) { 388 visitRedirectingInitializer(RedirectingInitializer node) {
389 writeByte(Tag.RedirectingInitializer); 389 writeByte(Tag.RedirectingInitializer);
390 writeReference(node.targetReference); 390 writeReference(node.targetReference);
391 writeNode(node.arguments); 391 writeNode(node.arguments);
392 } 392 }
393 393
394 visitLocalInitializer(LocalInitializer node) { 394 visitLocalInitializer(LocalInitializer node) {
395 writeByte(Tag.LocalInitializer); 395 writeByte(Tag.LocalInitializer);
396 writeVariableDeclaration(node.variable); 396 writeVariableDeclaration(node.variable, false);
397 } 397 }
398 398
399 visitFunctionNode(FunctionNode node) { 399 visitFunctionNode(FunctionNode node) {
400 assert(_variableIndexer != null); 400 assert(_variableIndexer != null);
401 _variableIndexer.pushScope(); 401 _variableIndexer.pushScope();
402 var oldLabels = _labelIndexer; 402 var oldLabels = _labelIndexer;
403 _labelIndexer = new LabelIndexer(); 403 _labelIndexer = new LabelIndexer();
404 var oldCases = _switchCaseIndexer; 404 var oldCases = _switchCaseIndexer;
405 _switchCaseIndexer = new SwitchCaseIndexer(); 405 _switchCaseIndexer = new SwitchCaseIndexer();
406 // Note: FunctionNode has no tag. 406 // Note: FunctionNode has no tag.
(...skipping 19 matching lines...) Expand all
426 } 426 }
427 427
428 visitVariableGet(VariableGet node) { 428 visitVariableGet(VariableGet node) {
429 assert(_variableIndexer != null); 429 assert(_variableIndexer != null);
430 int index = _variableIndexer[node.variable]; 430 int index = _variableIndexer[node.variable];
431 assert(index != null); 431 assert(index != null);
432 if (index & Tag.SpecializedPayloadMask == index && 432 if (index & Tag.SpecializedPayloadMask == index &&
433 node.promotedType == null) { 433 node.promotedType == null) {
434 writeByte(Tag.SpecializedVariableGet + index); 434 writeByte(Tag.SpecializedVariableGet + index);
435 writeOffset(node.fileOffset); 435 writeOffset(node.fileOffset);
436 writeUInt30(node.variable.tempOffset);
436 } else { 437 } else {
437 writeByte(Tag.VariableGet); 438 writeByte(Tag.VariableGet);
438 writeOffset(node.fileOffset); 439 writeOffset(node.fileOffset);
440 writeUInt30(node.variable.tempOffset);
439 writeUInt30(_variableIndexer[node.variable]); 441 writeUInt30(_variableIndexer[node.variable]);
440 writeOptionalNode(node.promotedType); 442 writeOptionalNode(node.promotedType);
441 } 443 }
442 } 444 }
443 445
444 visitVariableSet(VariableSet node) { 446 visitVariableSet(VariableSet node) {
445 assert(_variableIndexer != null); 447 assert(_variableIndexer != null);
446 int index = _variableIndexer[node.variable]; 448 int index = _variableIndexer[node.variable];
447 if (index & Tag.SpecializedPayloadMask == index) { 449 if (index & Tag.SpecializedPayloadMask == index) {
448 writeByte(Tag.SpecializedVariableSet + index); 450 writeByte(Tag.SpecializedVariableSet + index);
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 writeNode(node.operand); 708 writeNode(node.operand);
707 } 709 }
708 710
709 visitFunctionExpression(FunctionExpression node) { 711 visitFunctionExpression(FunctionExpression node) {
710 writeByte(Tag.FunctionExpression); 712 writeByte(Tag.FunctionExpression);
711 writeNode(node.function); 713 writeNode(node.function);
712 } 714 }
713 715
714 visitLet(Let node) { 716 visitLet(Let node) {
715 writeByte(Tag.Let); 717 writeByte(Tag.Let);
716 writeVariableDeclaration(node.variable); 718 writeVariableDeclaration(node.variable, false);
717 writeNode(node.body); 719 writeNode(node.body);
718 --_variableIndexer.stackHeight; 720 --_variableIndexer.stackHeight;
719 } 721 }
720 722
721 visitLoadLibrary(LoadLibrary node) { 723 visitLoadLibrary(LoadLibrary node) {
722 writeByte(Tag.LoadLibrary); 724 writeByte(Tag.LoadLibrary);
723 writeDeferredImportReference(node.import); 725 writeDeferredImportReference(node.import);
724 } 726 }
725 727
726 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) { 728 visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 writeOptionalNode(node.condition); 819 writeOptionalNode(node.condition);
818 writeNodeList(node.updates); 820 writeNodeList(node.updates);
819 writeNode(node.body); 821 writeNode(node.body);
820 _variableIndexer.popScope(); 822 _variableIndexer.popScope();
821 } 823 }
822 824
823 visitForInStatement(ForInStatement node) { 825 visitForInStatement(ForInStatement node) {
824 _variableIndexer.pushScope(); 826 _variableIndexer.pushScope();
825 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement); 827 writeByte(node.isAsync ? Tag.AsyncForInStatement : Tag.ForInStatement);
826 writeOffset(node.fileOffset); 828 writeOffset(node.fileOffset);
827 writeVariableDeclaration(node.variable); 829 writeVariableDeclaration(node.variable, false);
828 writeNode(node.iterable); 830 writeNode(node.iterable);
829 writeNode(node.body); 831 writeNode(node.body);
830 _variableIndexer.popScope(); 832 _variableIndexer.popScope();
831 } 833 }
832 834
833 visitSwitchStatement(SwitchStatement node) { 835 visitSwitchStatement(SwitchStatement node) {
834 _switchCaseIndexer.enter(node); 836 _switchCaseIndexer.enter(node);
835 writeByte(Tag.SwitchStatement); 837 writeByte(Tag.SwitchStatement);
836 writeNode(node.expression); 838 writeNode(node.expression);
837 writeNodeList(node.cases); 839 writeNodeList(node.cases);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 890
889 visitYieldStatement(YieldStatement node) { 891 visitYieldStatement(YieldStatement node) {
890 writeByte(Tag.YieldStatement); 892 writeByte(Tag.YieldStatement);
891 writeOffset(node.fileOffset); 893 writeOffset(node.fileOffset);
892 writeByte(node.flags); 894 writeByte(node.flags);
893 writeNode(node.expression); 895 writeNode(node.expression);
894 } 896 }
895 897
896 visitVariableDeclaration(VariableDeclaration node) { 898 visitVariableDeclaration(VariableDeclaration node) {
897 writeByte(Tag.VariableDeclaration); 899 writeByte(Tag.VariableDeclaration);
898 writeVariableDeclaration(node); 900 writeVariableDeclaration(node, true);
899 } 901 }
900 902
901 void writeVariableDeclaration(VariableDeclaration node) { 903 void writeVariableDeclaration(VariableDeclaration node,
904 [bool hasTag = false]) {
905 int length = _sink.flushedLength + _sink.length - (hasTag ? 1 : 0);
Kevin Millikin (Google) 2017/04/05 08:59:57 It seems better to move writing of the tag here so
906 node.tempOffset = length;
902 writeOffset(node.fileOffset); 907 writeOffset(node.fileOffset);
903 writeOffset(node.fileEqualsOffset); 908 writeOffset(node.fileEqualsOffset);
904 writeByte(node.flags); 909 writeByte(node.flags);
905 writeStringReference(node.name ?? ''); 910 writeStringReference(node.name ?? '');
906 writeNode(node.type); 911 writeNode(node.type);
907 writeOptionalNode(node.initializer); 912 writeOptionalNode(node.initializer);
908 // Declare the variable after its initializer. It is not in scope in its 913 // Declare the variable after its initializer. It is not in scope in its
909 // own initializer. 914 // own initializer.
910 _variableIndexer.declare(node); 915 _variableIndexer.declare(node);
911 } 916 }
912 917
913 void writeVariableDeclarationList(List<VariableDeclaration> nodes) { 918 void writeVariableDeclarationList(List<VariableDeclaration> nodes) {
914 writeList(nodes, writeVariableDeclaration); 919 writeList(nodes, writeVariableDeclaration);
915 } 920 }
916 921
917 void writeOptionalVariableDeclaration(VariableDeclaration node) { 922 void writeOptionalVariableDeclaration(VariableDeclaration node) {
918 if (node == null) { 923 if (node == null) {
919 writeByte(Tag.Nothing); 924 writeByte(Tag.Nothing);
920 } else { 925 } else {
921 writeByte(Tag.Something); 926 writeByte(Tag.Something);
922 writeVariableDeclaration(node); 927 writeVariableDeclaration(node, false);
923 } 928 }
924 } 929 }
925 930
926 visitFunctionDeclaration(FunctionDeclaration node) { 931 visitFunctionDeclaration(FunctionDeclaration node) {
927 writeByte(Tag.FunctionDeclaration); 932 writeByte(Tag.FunctionDeclaration);
928 writeOffset(node.fileOffset); 933 writeOffset(node.fileOffset);
929 writeVariableDeclaration(node.variable); 934 writeVariableDeclaration(node.variable, false);
930 writeNode(node.function); 935 writeNode(node.function);
931 } 936 }
932 937
933 visitBottomType(BottomType node) { 938 visitBottomType(BottomType node) {
934 writeByte(Tag.BottomType); 939 writeByte(Tag.BottomType);
935 } 940 }
936 941
937 visitInvalidType(InvalidType node) { 942 visitInvalidType(InvalidType node) {
938 writeByte(Tag.InvalidType); 943 writeByte(Tag.InvalidType);
939 } 944 }
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 } 1250 }
1246 } 1251 }
1247 1252
1248 /// Puts a buffer in front of a [Sink<List<int>>]. 1253 /// Puts a buffer in front of a [Sink<List<int>>].
1249 class BufferedSink { 1254 class BufferedSink {
1250 static const int SIZE = 100000; 1255 static const int SIZE = 100000;
1251 static const int SMALL = 10000; 1256 static const int SMALL = 10000;
1252 final Sink<List<int>> _sink; 1257 final Sink<List<int>> _sink;
1253 Uint8List _buffer = new Uint8List(SIZE); 1258 Uint8List _buffer = new Uint8List(SIZE);
1254 int length = 0; 1259 int length = 0;
1260 int flushedLength = 0;
1255 1261
1256 BufferedSink(this._sink); 1262 BufferedSink(this._sink);
1257 1263
1258 void addByte(int byte) { 1264 void addByte(int byte) {
1259 _buffer[length++] = byte; 1265 _buffer[length++] = byte;
1260 if (length == SIZE) { 1266 if (length == SIZE) {
1261 _sink.add(_buffer); 1267 _sink.add(_buffer);
1262 _buffer = new Uint8List(SIZE); 1268 _buffer = new Uint8List(SIZE);
1263 length = 0; 1269 length = 0;
1270 flushedLength += SIZE;
1264 } 1271 }
1265 } 1272 }
1266 1273
1267 void addBytes(List<int> bytes) { 1274 void addBytes(List<int> bytes) {
1268 // Avoid copying a large buffer into the another large buffer. Also, if 1275 // Avoid copying a large buffer into the another large buffer. Also, if
1269 // the bytes buffer is too large to fit in our own buffer, just emit both. 1276 // the bytes buffer is too large to fit in our own buffer, just emit both.
1270 if (length + bytes.length < SIZE && 1277 if (length + bytes.length < SIZE &&
1271 (bytes.length < SMALL || length < SMALL)) { 1278 (bytes.length < SMALL || length < SMALL)) {
1272 if (length == 0) { 1279 if (length == 0) {
1273 _sink.add(bytes); 1280 _sink.add(bytes);
1281 flushedLength += bytes.length;
1274 } else { 1282 } else {
1275 _buffer.setRange(length, length + bytes.length, bytes); 1283 _buffer.setRange(length, length + bytes.length, bytes);
1276 length += bytes.length; 1284 length += bytes.length;
1277 } 1285 }
1278 } else if (bytes.length < SMALL) { 1286 } else if (bytes.length < SMALL) {
1279 // Flush as much as we can in the current buffer. 1287 // Flush as much as we can in the current buffer.
1280 _buffer.setRange(length, SIZE, bytes); 1288 _buffer.setRange(length, SIZE, bytes);
1281 _sink.add(_buffer); 1289 _sink.add(_buffer);
1282 // Copy over the remainder into a new buffer. It is guaranteed to fit 1290 // Copy over the remainder into a new buffer. It is guaranteed to fit
1283 // because the input byte array is small. 1291 // because the input byte array is small.
1284 int alreadyEmitted = SIZE - length; 1292 int alreadyEmitted = SIZE - length;
1285 int remainder = bytes.length - alreadyEmitted; 1293 int remainder = bytes.length - alreadyEmitted;
1286 _buffer = new Uint8List(SIZE); 1294 _buffer = new Uint8List(SIZE);
1287 _buffer.setRange(0, remainder, bytes, alreadyEmitted); 1295 _buffer.setRange(0, remainder, bytes, alreadyEmitted);
1288 length = remainder; 1296 length = remainder;
1297 flushedLength += SIZE;
1289 } else { 1298 } else {
1290 _sink.add(_buffer.sublist(0, length)); 1299 _sink.add(_buffer.sublist(0, length));
1291 _sink.add(bytes); 1300 _sink.add(bytes);
1292 _buffer = new Uint8List(SIZE); 1301 _buffer = new Uint8List(SIZE);
1302 flushedLength += length;
1303 flushedLength += bytes.length;
1293 length = 0; 1304 length = 0;
1294 } 1305 }
1295 } 1306 }
1296 1307
1297 void flush() { 1308 void flush() {
1298 _sink.add(_buffer.sublist(0, length)); 1309 _sink.add(_buffer.sublist(0, length));
1299 _buffer = new Uint8List(SIZE); 1310 _buffer = new Uint8List(SIZE);
1311 flushedLength += length;
1300 length = 0; 1312 length = 0;
1301 } 1313 }
1302 1314
1303 void flushAndDestroy() { 1315 void flushAndDestroy() {
1304 _sink.add(_buffer.sublist(0, length)); 1316 _sink.add(_buffer.sublist(0, length));
1305 } 1317 }
1306 } 1318 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698