Skip to content

Commit 9f4f0ac

Browse files
alexmarkovcommit-bot@chromium.org
authored andcommitted
[vm/bytecode] Generate dependencies in front-end server in bytecode mode
When bytecode component is created without AST, Component.uriToSource mapping is also dropped. Front-end server relies on Component.uriToSource in order to generated dependencies file and send list of compiled source to flutter tools. This change fixes listing of dependencies in bytecode mode without AST. Change-Id: I7c2b6f48571ec3ca42de330bdc1feef3ba7425d5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/117596 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 678f561 commit 9f4f0ac

File tree

3 files changed

+78
-19
lines changed

3 files changed

+78
-19
lines changed

pkg/vm/lib/frontend_server.dart

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ class FrontendCompiler implements CompilerInterface {
361361
}
362362

363363
Component component;
364+
Iterable<Uri> compiledSources;
364365
if (options['incremental']) {
365366
_compilerOptions = compilerOptions;
366367
_bytecodeOptions = bytecodeOptions;
@@ -370,8 +371,11 @@ class FrontendCompiler implements CompilerInterface {
370371
_generator =
371372
generator ?? _createGenerator(new Uri.file(_initializeFromDill));
372373
await invalidateIfInitializingFromDill();
373-
component = await _runWithPrintRedirection(() async =>
374-
await _generateBytecodeIfNeeded(await _generator.compile()));
374+
component = await _runWithPrintRedirection(() async {
375+
final c = await _generator.compile();
376+
compiledSources = c.uriToSource.keys;
377+
return await _generateBytecodeIfNeeded(c);
378+
});
375379
} else {
376380
if (options['link-platform']) {
377381
// TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -380,7 +384,7 @@ class FrontendCompiler implements CompilerInterface {
380384
sdkRoot.resolve(platformKernelDill)
381385
];
382386
}
383-
component = await _runWithPrintRedirection(() => compileToKernel(
387+
final results = await _runWithPrintRedirection(() => compileToKernel(
384388
_mainSource, compilerOptions,
385389
aot: options['aot'],
386390
useGlobalTypeFlowAnalysis: options['tfa'],
@@ -389,6 +393,8 @@ class FrontendCompiler implements CompilerInterface {
389393
bytecodeOptions: bytecodeOptions,
390394
dropAST: options['drop-ast'],
391395
useProtobufTreeShaker: options['protobuf-tree-shaker']));
396+
component = results.component;
397+
compiledSources = results.compiledSources;
392398
}
393399
if (component != null) {
394400
if (transformer != null) {
@@ -399,12 +405,12 @@ class FrontendCompiler implements CompilerInterface {
399405
filterExternal: importDill != null);
400406

401407
_outputStream.writeln(boundaryKey);
402-
await _outputDependenciesDelta(component);
408+
await _outputDependenciesDelta(compiledSources);
403409
_outputStream
404410
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
405411
final String depfile = options['depfile'];
406412
if (depfile != null) {
407-
await writeDepfile(compilerOptions.fileSystem, component,
413+
await writeDepfile(compilerOptions.fileSystem, compiledSources,
408414
_kernelBinaryFilename, depfile);
409415
}
410416

@@ -430,9 +436,9 @@ class FrontendCompiler implements CompilerInterface {
430436
return component;
431437
}
432438

433-
void _outputDependenciesDelta(Component component) async {
439+
void _outputDependenciesDelta(Iterable<Uri> compiledSources) async {
434440
Set<Uri> uris = new Set<Uri>();
435-
for (Uri uri in component.uriToSource.keys) {
441+
for (Uri uri in compiledSources) {
436442
// Skip empty or corelib dependencies.
437443
if (uri == null || uri.scheme == 'org-dartlang-sdk') continue;
438444
uris.add(uri);
@@ -557,10 +563,11 @@ class FrontendCompiler implements CompilerInterface {
557563
if (deltaProgram != null && transformer != null) {
558564
transformer.transform(deltaProgram);
559565
}
566+
final compiledSources = deltaProgram.uriToSource.keys;
560567
deltaProgram = await _generateBytecodeIfNeeded(deltaProgram);
561568
await writeDillFile(deltaProgram, _kernelBinaryFilename);
562569
_outputStream.writeln(boundaryKey);
563-
await _outputDependenciesDelta(deltaProgram);
570+
await _outputDependenciesDelta(compiledSources);
564571
_outputStream
565572
.writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
566573
_kernelBinaryFilename = _kernelBinaryFilenameIncremental;

pkg/vm/lib/kernel_front_end.dart

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ Future<int> runCompiler(ArgResults options, String usage) async {
212212
}
213213
..embedSourceText = embedSources;
214214

215-
final component = await compileToKernel(mainUri, compilerOptions,
215+
final results = await compileToKernel(mainUri, compilerOptions,
216216
aot: aot,
217217
useGlobalTypeFlowAnalysis: tfa,
218218
environmentDefines: environmentDefines,
@@ -223,7 +223,7 @@ Future<int> runCompiler(ArgResults options, String usage) async {
223223

224224
errorPrinter.printCompilationMessages();
225225

226-
if (errorDetector.hasCompilationErrors || (component == null)) {
226+
if (errorDetector.hasCompilationErrors || (results.component == null)) {
227227
return compileTimeErrorExitCode;
228228
}
229229

@@ -233,22 +233,23 @@ Future<int> runCompiler(ArgResults options, String usage) async {
233233

234234
final IOSink sink = new File(outputFileName).openWrite();
235235
final BinaryPrinter printer = new BinaryPrinter(sink);
236-
printer.writeComponentFile(component);
236+
printer.writeComponentFile(results.component);
237237
await sink.close();
238238

239239
if (bytecodeOptions.showBytecodeSizeStatistics && !splitOutputByPackages) {
240240
BytecodeSizeStatistics.dump();
241241
}
242242

243243
if (depfile != null) {
244-
await writeDepfile(fileSystem, component, outputFileName, depfile);
244+
await writeDepfile(
245+
fileSystem, results.compiledSources, outputFileName, depfile);
245246
}
246247

247248
if (splitOutputByPackages) {
248249
await writeOutputSplitByPackages(
249250
mainUri,
250251
compilerOptions,
251-
component,
252+
results.component,
252253
outputFileName,
253254
genBytecode: genBytecode,
254255
bytecodeOptions: bytecodeOptions,
@@ -259,12 +260,22 @@ Future<int> runCompiler(ArgResults options, String usage) async {
259260
return successExitCode;
260261
}
261262

263+
/// Results of [compileToKernel]: generated kernel [Component] and
264+
/// collection of compiled sources.
265+
class KernelCompilationResults {
266+
final Component component;
267+
final Iterable<Uri> compiledSources;
268+
269+
KernelCompilationResults(this.component, this.compiledSources);
270+
}
271+
262272
/// Generates a kernel representation of the program whose main library is in
263273
/// the given [source]. Intended for whole program (non-modular) compilation.
264274
///
265275
/// VM-specific replacement of [kernelForProgram].
266276
///
267-
Future<Component> compileToKernel(Uri source, CompilerOptions options,
277+
Future<KernelCompilationResults> compileToKernel(
278+
Uri source, CompilerOptions options,
268279
{bool aot: false,
269280
bool useGlobalTypeFlowAnalysis: false,
270281
Map<String, String> environmentDefines,
@@ -280,6 +291,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
280291
setVMEnvironmentDefines(environmentDefines, options);
281292
CompilerResult compilerResult = await kernelForProgram(source, options);
282293
Component component = compilerResult?.component;
294+
final compiledSources = component?.uriToSource?.keys;
283295

284296
// Run global transformations only if component is correct.
285297
if (aot && component != null) {
@@ -306,7 +318,7 @@ Future<Component> compileToKernel(Uri source, CompilerOptions options,
306318
// Restore error handler (in case 'options' are reused).
307319
options.onDiagnostic = errorDetector.previousErrorHandler;
308320

309-
return component;
321+
return new KernelCompilationResults(component, compiledSources);
310322
}
311323

312324
void setVMEnvironmentDefines(
@@ -686,12 +698,12 @@ String _escapePath(String path) {
686698

687699
/// Create ninja dependencies file, as described in
688700
/// https://ninja-build.org/manual.html#_depfile
689-
Future<void> writeDepfile(FileSystem fileSystem, Component component,
701+
Future<void> writeDepfile(FileSystem fileSystem, Iterable<Uri> compiledSources,
690702
String output, String depfile) async {
691703
final IOSink file = new File(depfile).openWrite();
692704
file.write(_escapePath(output));
693705
file.write(':');
694-
for (Uri dep in component.uriToSource.keys) {
706+
for (Uri dep in compiledSources) {
695707
// Skip empty or corelib dependencies.
696708
if (dep == null || dep.scheme == 'org-dartlang-sdk') continue;
697709
Uri uri = await asFileUri(fileSystem, dep);

pkg/vm/test/frontend_server_test.dart

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,14 @@ Future<int> main() async {
313313
'--incremental',
314314
];
315315

316+
Directory tempDir;
317+
setUp(() {
318+
tempDir = Directory.systemTemp.createTempSync();
319+
});
320+
tearDown(() {
321+
tempDir.delete(recursive: true);
322+
});
323+
316324
test('compile then accept', () async {
317325
final StreamController<List<int>> inputStreamController =
318326
new StreamController<List<int>>();
@@ -359,11 +367,13 @@ Future<int> main() async {
359367
binaryPrinterFactory: printerFactory,
360368
);
361369

362-
inputStreamController.add('compile file1.dart\n'.codeUnits);
370+
final source = new File('${tempDir.path}/file1.dart');
371+
inputStreamController.add('compile ${source.path}\n'.codeUnits);
363372
await receivedResult.first;
364373
inputStreamController.add('accept\n'.codeUnits);
365374
receivedResult = new ReceivePort();
366-
inputStreamController.add('recompile def\nfile1.dart\ndef\n'.codeUnits);
375+
inputStreamController
376+
.add('recompile def\n${source.path}\ndef\n'.codeUnits);
367377
await receivedResult.first;
368378

369379
inputStreamController.add('quit\n'.codeUnits);
@@ -989,11 +999,41 @@ true
989999
'--platform=${platformKernel.path}',
9901000
'--output-dill=${dillFile.path}',
9911001
'--gen-bytecode',
1002+
'--drop-ast',
9921003
file.path,
9931004
];
9941005
expect(await starter(args), 0);
9951006
});
9961007

1008+
test('compile with bytecode and produce deps file', () async {
1009+
var sourceFoo = new File('${tempDir.path}/foo.dart')..createSync();
1010+
sourceFoo.writeAsStringSync("import 'bar.dart'; main() { barfunc(); }\n");
1011+
var sourceBar = new File('${tempDir.path}/bar.dart')..createSync();
1012+
sourceBar.writeAsStringSync("barfunc() {}\n");
1013+
var dillFile = new File('${tempDir.path}/app.dill');
1014+
expect(dillFile.existsSync(), equals(false));
1015+
var depFile = new File('${tempDir.path}/app.dill.d');
1016+
expect(depFile.existsSync(), equals(false));
1017+
final List<String> args = <String>[
1018+
'--sdk-root=${sdkRoot.toFilePath()}',
1019+
'--incremental',
1020+
'--platform=${platformKernel.path}',
1021+
'--output-dill=${dillFile.path}',
1022+
'--depfile=${depFile.path}',
1023+
'--gen-bytecode',
1024+
'--drop-ast',
1025+
sourceFoo.path,
1026+
];
1027+
expect(await starter(args), 0);
1028+
expect(depFile.existsSync(), true);
1029+
var depContents = depFile.readAsStringSync();
1030+
print(depContents);
1031+
var depContentsParsed = depContents.split(': ');
1032+
expect(path.basename(depContentsParsed[0]), path.basename(dillFile.path));
1033+
expect(depContentsParsed[1], contains(path.basename(sourceFoo.path)));
1034+
expect(depContentsParsed[1], contains(path.basename(sourceBar.path)));
1035+
});
1036+
9971037
test('compile "package:"-file', () async {
9981038
Directory lib = new Directory('${tempDir.path}/lib')..createSync();
9991039
new File('${lib.path}/foo.dart')

0 commit comments

Comments
 (0)