61f0f5bc43
This change replaces kernel AST declarations of fields and functions with bytecode declarations. Size of dilp files is reduced by 11-12%. Startup latency: Time to the first full frame: 1.945s -> 1.687s FinalizeClass: 554ms -> 277ms FinishClassLoading: 296ms -> 156ms There are following regressions in bytecode mode, which will be fixed in future: * dart:mirrors are not supported yet (implementation of mirrors relies on reading kernel AST in certain cases). As the result, lib_2/mirrors/* tests fail. * native extensions are not supported yet (annotations on libraries and classes in AST are cleaned up as they could reference members which are now removed from AST). As the result, standalone_2/entrypoints_verification_test test fails. * language_2/spread_collections/const_error_test/* tests fail due to https://github.com/dart-lang/sdk/issues/36286. Change-Id: I5130f401fd7b84038b136136e7ccc1a6e51b6cea Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97561 Commit-Queue: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
94 lines
2.3 KiB
Dart
94 lines
2.3 KiB
Dart
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
library vm.bytecode.source_positions;
|
|
|
|
import 'bytecode_serialization.dart' show BufferedWriter, BufferedReader;
|
|
|
|
/// Maintains mapping between bytecode instructions and source positions.
|
|
class SourcePositions {
|
|
final Map<int, int> mapping = <int, int>{}; // PC -> fileOffset
|
|
int _lastPc = 0;
|
|
int _lastOffset = 0;
|
|
|
|
SourcePositions();
|
|
|
|
void add(int pc, int fileOffset) {
|
|
assert(pc > _lastPc);
|
|
assert(fileOffset >= 0);
|
|
if (fileOffset != _lastOffset) {
|
|
mapping[pc] = fileOffset;
|
|
_lastPc = pc;
|
|
_lastOffset = fileOffset;
|
|
}
|
|
}
|
|
|
|
void write(BufferedWriter writer) {
|
|
writer.writePackedUInt30(mapping.length);
|
|
final encodePC = new PackedUInt30DeltaEncoder();
|
|
final encodeOffset = new SLEB128DeltaEncoder();
|
|
mapping.forEach((int pc, int fileOffset) {
|
|
encodePC.write(writer, pc);
|
|
encodeOffset.write(writer, fileOffset);
|
|
});
|
|
}
|
|
|
|
SourcePositions.read(BufferedReader reader) {
|
|
final int length = reader.readPackedUInt30();
|
|
final decodePC = new PackedUInt30DeltaDecoder();
|
|
final decodeOffset = new SLEB128DeltaDecoder();
|
|
for (int i = 0; i < length; ++i) {
|
|
int pc = decodePC.read(reader);
|
|
int fileOffset = decodeOffset.read(reader);
|
|
add(pc, fileOffset);
|
|
}
|
|
}
|
|
|
|
@override
|
|
String toString() => mapping.toString();
|
|
|
|
Map<int, String> getBytecodeAnnotations() {
|
|
return mapping.map((int pc, int fileOffset) =>
|
|
new MapEntry(pc, 'source position $fileOffset'));
|
|
}
|
|
}
|
|
|
|
class PackedUInt30DeltaEncoder {
|
|
int _last = 0;
|
|
|
|
void write(BufferedWriter write, int value) {
|
|
write.writePackedUInt30(value - _last);
|
|
_last = value;
|
|
}
|
|
}
|
|
|
|
class PackedUInt30DeltaDecoder {
|
|
int _last = 0;
|
|
|
|
int read(BufferedReader reader) {
|
|
int value = reader.readPackedUInt30() + _last;
|
|
_last = value;
|
|
return value;
|
|
}
|
|
}
|
|
|
|
class SLEB128DeltaEncoder {
|
|
int _last = 0;
|
|
|
|
void write(BufferedWriter writer, int value) {
|
|
writer.writeSLEB128(value - _last);
|
|
_last = value;
|
|
}
|
|
}
|
|
|
|
class SLEB128DeltaDecoder {
|
|
int _last = 0;
|
|
|
|
int read(BufferedReader reader) {
|
|
int value = reader.readSLEB128() + _last;
|
|
_last = value;
|
|
return value;
|
|
}
|
|
}
|