Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9406b7b

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Add versioning to bytecode format
Change-Id: I35d86aec17aa0f6894a6380e4bb5ac7ca3092fac Reviewed-on: https://dart-review.googlesource.com/c/80522 Reviewed-by: Zach Anderson <zra@google.com> Reviewed-by: Régis Crelier <regis@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
1 parent a82e025 commit 9406b7b

22 files changed

Lines changed: 246 additions & 183 deletions

pkg/vm/bin/gen_kernel.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
4545
defaultsTo: true)
4646
..addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false)
4747
..addFlag('drop-ast',
48-
help: 'Drop AST for members with bytecode', defaultsTo: false);
48+
help: 'Drop AST for members with bytecode', defaultsTo: false)
49+
..addFlag('use-future-bytecode-format',
50+
help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);
4951

5052
final String _usage = '''
5153
Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
@@ -82,6 +84,7 @@ Future<int> compile(List<String> arguments) async {
8284
final bool tfa = options['tfa'];
8385
final bool genBytecode = options['gen-bytecode'];
8486
final bool dropAST = options['drop-ast'];
87+
final bool useFutureBytecodeFormat = options['use-future-bytecode-format'];
8588
final bool enableAsserts = options['enable-asserts'];
8689
final bool enableConstantEvaluation = options['enable-constant-evaluation'];
8790
final Map<String, String> environmentDefines = {};
@@ -114,6 +117,7 @@ Future<int> compile(List<String> arguments) async {
114117
environmentDefines: environmentDefines,
115118
genBytecode: genBytecode,
116119
dropAST: dropAST,
120+
useFutureBytecodeFormat: useFutureBytecodeFormat,
117121
enableAsserts: enableAsserts,
118122
enableConstantEvaluation: enableConstantEvaluation);
119123

pkg/vm/lib/bytecode/dbc.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
77
library vm.bytecode.dbc;
88

9+
/// Version of stable bytecode format, produced by default.
10+
/// Before bumping stable bytecode version format, make sure that
11+
/// all users have switched to a VM which is able to consume next
12+
/// version of bytecode.
13+
const int stableBytecodeFormatVersion = 1;
14+
15+
/// Version of bleeding edge bytecode format.
16+
/// Produced by bytecode generator when --use-future-bytecode-format
17+
/// option is enabled.
18+
/// Should match kMaxSupportedBytecodeFormatVersion in
19+
/// runtime/vm/constants_kbc.h.
20+
const int futureBytecodeFormatVersion = stableBytecodeFormatVersion + 1;
21+
922
enum Opcode {
1023
kTrap,
1124

pkg/vm/lib/bytecode/gen_bytecode.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const String symbolForTypeCast = ' in type cast';
3939
void generateBytecode(Component component,
4040
{bool dropAST: false,
4141
bool omitSourcePositions: false,
42+
bool useFutureBytecodeFormat: false,
4243
Map<String, String> environmentDefines,
4344
ErrorReporter errorReporter}) {
4445
final coreTypes = new CoreTypes(component);
@@ -50,8 +51,15 @@ void generateBytecode(Component component,
5051
final constantsBackend =
5152
new VmConstantsBackend(environmentDefines, coreTypes);
5253
final errorReporter = new ForwardConstantEvaluationErrors(typeEnvironment);
53-
new BytecodeGenerator(component, coreTypes, hierarchy, typeEnvironment,
54-
constantsBackend, omitSourcePositions, errorReporter)
54+
new BytecodeGenerator(
55+
component,
56+
coreTypes,
57+
hierarchy,
58+
typeEnvironment,
59+
constantsBackend,
60+
omitSourcePositions,
61+
useFutureBytecodeFormat,
62+
errorReporter)
5563
.visitComponent(component);
5664
if (dropAST) {
5765
new DropAST().visitComponent(component);
@@ -65,6 +73,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
6573
final TypeEnvironment typeEnvironment;
6674
final ConstantsBackend constantsBackend;
6775
final bool omitSourcePositions;
76+
final bool useFutureBytecodeFormat;
6877
final ErrorReporter errorReporter;
6978
final BytecodeMetadataRepository metadata = new BytecodeMetadataRepository();
7079
final RecognizedMethods recognizedMethods;
@@ -101,6 +110,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
101110
this.typeEnvironment,
102111
this.constantsBackend,
103112
this.omitSourcePositions,
113+
this.useFutureBytecodeFormat,
104114
this.errorReporter)
105115
: recognizedMethods = new RecognizedMethods(typeEnvironment) {
106116
component.addMetadataRepository(metadata);
@@ -750,8 +760,11 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
750760

751761
void end(Member node) {
752762
if (!hasErrors) {
753-
metadata.mapping[node] = new BytecodeMetadata(
754-
cp, asm.bytecode, asm.exceptionsTable, nullableFields, closures);
763+
final formatVersion = useFutureBytecodeFormat
764+
? futureBytecodeFormatVersion
765+
: stableBytecodeFormatVersion;
766+
metadata.mapping[node] = new BytecodeMetadata(formatVersion, cp,
767+
asm.bytecode, asm.exceptionsTable, nullableFields, closures);
755768
}
756769

757770
typeEnvironment.thisType = null;

pkg/vm/lib/kernel_front_end.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
4949
Map<String, String> environmentDefines,
5050
bool genBytecode: false,
5151
bool dropAST: false,
52+
bool useFutureBytecodeFormat: false,
5253
bool enableAsserts: false,
5354
bool enableConstantEvaluation: true}) async {
5455
// Replace error handler to detect if there are compilation errors.
@@ -91,7 +92,9 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
9192
if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
9293
await runWithFrontEndCompilerContext(source, options, component, () {
9394
generateBytecode(component,
94-
dropAST: dropAST, environmentDefines: environmentDefines);
95+
dropAST: dropAST,
96+
useFutureBytecodeFormat: useFutureBytecodeFormat,
97+
environmentDefines: environmentDefines);
9598
});
9699
}
97100

pkg/vm/lib/metadata/bytecode.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ library vm.metadata.bytecode;
66

77
import 'package:kernel/ast.dart';
88
import '../bytecode/constant_pool.dart' show ConstantPool;
9+
import '../bytecode/dbc.dart'
10+
show stableBytecodeFormatVersion, futureBytecodeFormatVersion;
911
import '../bytecode/disassembler.dart' show BytecodeDisassembler;
1012
import '../bytecode/exceptions.dart' show ExceptionsTable;
1113

@@ -14,6 +16,7 @@ import '../bytecode/exceptions.dart' show ExceptionsTable;
1416
/// In kernel binary, bytecode metadata is encoded as following:
1517
///
1618
/// type BytecodeMetadata {
19+
/// UInt bytecodeFormatVersion
1720
/// UInt flags (HasExceptionsTable, HasNullableFields, HasClosures)
1821
///
1922
/// ConstantPool constantPool
@@ -46,6 +49,7 @@ class BytecodeMetadata {
4649
static const hasNullableFieldsFlag = 1 << 1;
4750
static const hasClosuresFlag = 1 << 2;
4851

52+
final int version;
4953
final ConstantPool constantPool;
5054
final List<int> bytecodes;
5155
final ExceptionsTable exceptionsTable;
@@ -61,13 +65,16 @@ class BytecodeMetadata {
6165
(hasNullableFields ? hasNullableFieldsFlag : 0) |
6266
(hasClosures ? hasClosuresFlag : 0);
6367

64-
BytecodeMetadata(this.constantPool, this.bytecodes, this.exceptionsTable,
65-
this.nullableFields, this.closures);
68+
BytecodeMetadata(this.version, this.constantPool, this.bytecodes,
69+
this.exceptionsTable, this.nullableFields, this.closures);
6670

6771
// TODO(alexmarkov): Consider printing constant pool before bytecode.
6872
@override
6973
String toString() => "\n"
70-
"Bytecode {\n"
74+
"Bytecode"
75+
" (version: "
76+
"${version == stableBytecodeFormatVersion ? 'stable' : version == futureBytecodeFormatVersion ? 'future' : "v$version"}"
77+
") {\n"
7178
"${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable)}}\n"
7279
"$exceptionsTable"
7380
"${nullableFields.isEmpty ? '' : 'Nullable fields: ${nullableFields.map((ref) => ref.asField).toList()}\n'}"
@@ -121,6 +128,7 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
121128

122129
@override
123130
void writeToBinary(BytecodeMetadata metadata, Node node, BinarySink sink) {
131+
sink.writeUInt30(metadata.version);
124132
sink.writeUInt30(metadata.flags);
125133
metadata.constantPool.writeToBinary(node, sink);
126134
sink.writeByteList(metadata.bytecodes);
@@ -140,6 +148,11 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
140148

141149
@override
142150
BytecodeMetadata readFromBinary(Node node, BinarySource source) {
151+
int version = source.readUInt();
152+
if (version != stableBytecodeFormatVersion &&
153+
version != futureBytecodeFormatVersion) {
154+
throw 'Error: unexpected bytecode version $version';
155+
}
143156
int flags = source.readUInt();
144157
final ConstantPool constantPool =
145158
new ConstantPool.readFromBinary(node, source);
@@ -158,7 +171,7 @@ class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
158171
? new List<ClosureBytecode>.generate(source.readUInt(),
159172
(_) => new ClosureBytecode.readFromBinary(source))
160173
: const <ClosureBytecode>[];
161-
return new BytecodeMetadata(
162-
constantPool, bytecodes, exceptionsTable, nullableFields, closures);
174+
return new BytecodeMetadata(version, constantPool, bytecodes,
175+
exceptionsTable, nullableFields, closures);
163176
}
164177
}

pkg/vm/testcases/bytecode/asserts.dart.expect

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import self as self;
33
import "dart:core" as core;
44

55
[@vm.bytecode=
6-
Bytecode {
6+
Bytecode (version: stable) {
77
Entry 0
88
CheckStack
99
JumpIfNoAsserts L1
@@ -28,7 +28,7 @@ ConstantPool {
2828
assert(condition);
2929
}
3030
[@vm.bytecode=
31-
Bytecode {
31+
Bytecode (version: stable) {
3232
Entry 0
3333
CheckStack
3434
JumpIfNoAsserts L1
@@ -58,7 +58,7 @@ ConstantPool {
5858
assert([@vm.call-site-attributes.metadata=receiverType:() → dart.core::bool] condition.call(), [@vm.call-site-attributes.metadata=receiverType:() → dart.core::String] message.call());
5959
}
6060
[@vm.bytecode=
61-
Bytecode {
61+
Bytecode (version: stable) {
6262
Entry 0
6363
CheckStack
6464
PushNull

pkg/vm/testcases/bytecode/async.dart.expect

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "dart:async" as asy;
44
import "dart:core" as core;
55

66
[@vm.bytecode=
7-
Bytecode {
7+
Bytecode (version: stable) {
88
Entry 3
99
CheckStack
1010
Allocate CP#19
@@ -276,7 +276,7 @@ Closure CP#0 {
276276
return :async_completer.{asy::Completer::future};
277277
};
278278
[@vm.bytecode=
279-
Bytecode {
279+
Bytecode (version: stable) {
280280
Entry 7
281281
CheckStack
282282
AllocateContext 4
@@ -463,7 +463,7 @@ L1:
463463
return :async_completer.{asy::Completer::future};
464464
}
465465
[@vm.bytecode=
466-
Bytecode {
466+
Bytecode (version: stable) {
467467
Entry 4
468468
CheckStack
469469
AllocateContext 11
@@ -746,7 +746,7 @@ L1:
746746
return :async_completer.{asy::Completer::future};
747747
}
748748
[@vm.bytecode=
749-
Bytecode {
749+
Bytecode (version: stable) {
750750
Entry 4
751751
CheckStack
752752
AllocateContext 11
@@ -1165,7 +1165,7 @@ L1:
11651165
return :async_completer.{asy::Completer::future};
11661166
}
11671167
[@vm.bytecode=
1168-
Bytecode {
1168+
Bytecode (version: stable) {
11691169
Entry 4
11701170
CheckStack
11711171
AllocateContext 16
@@ -1818,7 +1818,7 @@ L1:
18181818
return :async_completer.{asy::Completer::future};
18191819
}
18201820
[@vm.bytecode=
1821-
Bytecode {
1821+
Bytecode (version: stable) {
18221822
Entry 4
18231823
CheckStack
18241824
AllocateContext 2
@@ -2204,7 +2204,7 @@ Closure CP#0 {
22042204
return nested;
22052205
}
22062206
[@vm.bytecode=
2207-
Bytecode {
2207+
Bytecode (version: stable) {
22082208
Entry 4
22092209
CheckStack
22102210
AllocateContext 9
@@ -2460,7 +2460,7 @@ L1:
24602460
return :async_completer.{asy::Completer::future};
24612461
}
24622462
[@vm.bytecode=
2463-
Bytecode {
2463+
Bytecode (version: stable) {
24642464
Entry 0
24652465
CheckStack
24662466
PushNull

0 commit comments

Comments
 (0)