Skip to content

Commit ffefa12

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm] Initial support for bytecode generation in front-end server
Change-Id: I612dd2cb74534a5368e830a97ca73a469cfce82e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112520 Commit-Queue: Alexander Markov <[email protected]> Reviewed-by: Ryan Macnak <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent daf0de7 commit ffefa12

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

pkg/vm/lib/frontend_server.dart

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import 'package:kernel/kernel.dart'
2525
import 'package:path/path.dart' as path;
2626
import 'package:usage/uuid/uuid.dart';
2727

28+
import 'package:vm/bytecode/gen_bytecode.dart'
29+
show generateBytecode, createFreshComponentWithBytecode;
30+
import 'package:vm/bytecode/options.dart' show BytecodeOptions;
2831
import 'package:vm/incremental_compiler.dart' show IncrementalCompiler;
2932
import 'package:vm/kernel_front_end.dart'
3033
show
@@ -34,6 +37,7 @@ import 'package:vm/kernel_front_end.dart'
3437
convertFileOrUriArgumentToUri,
3538
createFrontEndTarget,
3639
createFrontEndFileSystem,
40+
runWithFrontEndCompilerContext,
3741
setVMEnvironmentDefines,
3842
writeDepfile;
3943

@@ -116,6 +120,16 @@ ArgParser argParser = new ArgParser(allowTrailingOptions: true)
116120
..addFlag('track-widget-creation',
117121
help: 'Run a kernel transformer to track creation locations for widgets.',
118122
defaultsTo: false)
123+
..addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false)
124+
..addMultiOption('bytecode-options',
125+
help: 'Specify options for bytecode generation:',
126+
valueHelp: 'opt1,opt2,...',
127+
allowed: BytecodeOptions.commandLineFlags.keys,
128+
allowedHelp: BytecodeOptions.commandLineFlags)
129+
..addFlag('drop-ast',
130+
help: 'Include only bytecode into the output file', defaultsTo: false)
131+
..addFlag('enable-asserts',
132+
help: 'Whether asserts will be enabled.', defaultsTo: false)
119133
..addMultiOption('enable-experiment',
120134
help: 'Comma separated list of experimental features, eg set-literals.',
121135
hide: true);
@@ -238,6 +252,7 @@ class FrontendCompiler implements CompilerInterface {
238252
bool unsafePackageSerialization;
239253

240254
CompilerOptions _compilerOptions;
255+
BytecodeOptions _bytecodeOptions;
241256
FileSystem _fileSystem;
242257
Uri _mainSource;
243258
ArgResults _options;
@@ -323,6 +338,12 @@ class FrontendCompiler implements CompilerInterface {
323338
return false;
324339
}
325340

341+
compilerOptions.bytecode = options['gen-bytecode'];
342+
final BytecodeOptions bytecodeOptions = new BytecodeOptions(
343+
enableAsserts: options['enable-asserts'],
344+
environmentDefines: environmentDefines)
345+
..parseCommandLineFlags(options['bytecode-options']);
346+
326347
compilerOptions.target = createFrontEndTarget(
327348
options['target'],
328349
trackWidgetCreation: options['track-widget-creation'],
@@ -342,13 +363,15 @@ class FrontendCompiler implements CompilerInterface {
342363
Component component;
343364
if (options['incremental']) {
344365
_compilerOptions = compilerOptions;
366+
_bytecodeOptions = bytecodeOptions;
345367
setVMEnvironmentDefines(environmentDefines, _compilerOptions);
346368

347369
_compilerOptions.omitPlatform = false;
348370
_generator =
349371
generator ?? _createGenerator(new Uri.file(_initializeFromDill));
350372
await invalidateIfInitializingFromDill();
351-
component = await _runWithPrintRedirection(() => _generator.compile());
373+
component = await _runWithPrintRedirection(() async =>
374+
await _generateBytecodeIfNeeded(await _generator.compile()));
352375
} else {
353376
if (options['link-platform']) {
354377
// TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -362,6 +385,9 @@ class FrontendCompiler implements CompilerInterface {
362385
aot: options['aot'],
363386
useGlobalTypeFlowAnalysis: options['tfa'],
364387
environmentDefines: environmentDefines,
388+
genBytecode: compilerOptions.bytecode,
389+
bytecodeOptions: bytecodeOptions,
390+
dropAST: options['drop-ast'],
365391
useProtobufTreeShaker: options['protobuf-tree-shaker']));
366392
}
367393
if (component != null) {
@@ -388,6 +414,22 @@ class FrontendCompiler implements CompilerInterface {
388414
return errors.isEmpty;
389415
}
390416

417+
Future<Component> _generateBytecodeIfNeeded(Component component) async {
418+
if (_compilerOptions.bytecode && errors.isEmpty) {
419+
await runWithFrontEndCompilerContext(
420+
_mainSource, _compilerOptions, component, () {
421+
generateBytecode(component,
422+
coreTypes: _generator.getCoreTypes(),
423+
hierarchy: _generator.getClassHierarchy(),
424+
options: _bytecodeOptions);
425+
if (_options['drop-ast']) {
426+
component = createFreshComponentWithBytecode(component);
427+
}
428+
});
429+
}
430+
return component;
431+
}
432+
391433
void _outputDependenciesDelta(Component component) async {
392434
Set<Uri> uris = new Set<Uri>();
393435
for (Uri uri in component.uriToSource.keys) {
@@ -501,12 +543,12 @@ class FrontendCompiler implements CompilerInterface {
501543
_mainSource = _getFileOrUri(entryPoint);
502544
}
503545
errors.clear();
504-
final Component deltaProgram =
505-
await _generator.compile(entryPoint: _mainSource);
546+
Component deltaProgram = await _generator.compile(entryPoint: _mainSource);
506547

507548
if (deltaProgram != null && transformer != null) {
508549
transformer.transform(deltaProgram);
509550
}
551+
deltaProgram = await _generateBytecodeIfNeeded(deltaProgram);
510552
await writeDillFile(deltaProgram, _kernelBinaryFilename);
511553
_outputStream.writeln(boundaryKey);
512554
await _outputDependenciesDelta(deltaProgram);
@@ -528,8 +570,10 @@ class FrontendCompiler implements CompilerInterface {
528570
Procedure procedure = await _generator.compileExpression(
529571
expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
530572
if (procedure != null) {
573+
Component component = createExpressionEvaluationComponent(procedure);
574+
component = await _generateBytecodeIfNeeded(component);
531575
final IOSink sink = new File(_kernelBinaryFilename).openWrite();
532-
sink.add(serializeProcedure(procedure));
576+
sink.add(serializeComponent(component));
533577
await sink.close();
534578
_outputStream
535579
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');

pkg/vm/test/frontend_server_test.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,22 @@ true
978978
expect(await starter(args), 0);
979979
});
980980

981+
test('compile with bytecode', () async {
982+
var file = new File('${tempDir.path}/foo.dart')..createSync();
983+
file.writeAsStringSync("main() {}\n");
984+
var dillFile = new File('${tempDir.path}/app.dill');
985+
expect(dillFile.existsSync(), equals(false));
986+
final List<String> args = <String>[
987+
'--sdk-root=${sdkRoot.toFilePath()}',
988+
'--incremental',
989+
'--platform=${platformKernel.path}',
990+
'--output-dill=${dillFile.path}',
991+
'--gen-bytecode',
992+
file.path,
993+
];
994+
expect(await starter(args), 0);
995+
});
996+
981997
test('compile "package:"-file', () async {
982998
Directory lib = new Directory('${tempDir.path}/lib')..createSync();
983999
new File('${lib.path}/foo.dart')

0 commit comments

Comments
 (0)