Skip to content

Commit cfde2d4

Browse files
joshualittCommit Bot
authored and
Commit Bot
committed
[dart2js] Fix bug with trimming component.
Also fully unifies all of our phases in `runSequentialPhases` for simplicity. Change-Id: I51dc8993070fe20de3d10fd98edd07adda5e790f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239361 Reviewed-by: Mark Zhou <[email protected]> Commit-Queue: Joshua Litt <[email protected]>
1 parent 706fa83 commit cfde2d4

File tree

1 file changed

+109
-97
lines changed

1 file changed

+109
-97
lines changed

pkg/compiler/lib/src/compiler.dart

Lines changed: 109 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -304,13 +304,9 @@ class Compiler {
304304
programSplitConstraintsData = constraintParser.read(programSplitJson);
305305
}
306306

307-
if (options.cfeOnly) {
308-
await runLoadKernel();
309-
} else if (options.modularMode) {
310-
await runModularAnalysis();
311-
} else {
307+
await selfTask.measureSubtask("compileFromKernel", () async {
312308
await runSequentialPhases();
313-
}
309+
});
314310
}
315311

316312
/// Clear the internal compiler state to prevent memory leaks when invoking
@@ -329,7 +325,13 @@ class Compiler {
329325
}
330326
}
331327

332-
JClosedWorld computeClosedWorld(Uri rootLibraryUri, Iterable<Uri> libraries) {
328+
JClosedWorld computeClosedWorld(
329+
ir.Component component,
330+
List<ModuleData> moduleData,
331+
Uri rootLibraryUri,
332+
Iterable<Uri> libraries) {
333+
frontendStrategy.registerLoadedLibraries(component, libraries);
334+
frontendStrategy.registerModuleData(moduleData);
333335
ResolutionEnqueuer resolutionEnqueuer = frontendStrategy
334336
.createResolutionEnqueuer(enqueueTask, this)
335337
..onEmptyForTesting = onResolutionQueueEmptyForTesting;
@@ -379,59 +381,83 @@ class Compiler {
379381
return closedWorld;
380382
}
381383

382-
Future<load_kernel.Output> runLoadKernel() async {
384+
Future<load_kernel.Output> loadKernel() async {
383385
final input = load_kernel.Input(options, provider, reporter,
384386
initializedCompilerState, forceSerializationForTesting);
385387
load_kernel.Output output =
386388
await loadKernelTask.measure(() async => load_kernel.run(input));
387-
if (output == null || compilationFailed) return null;
388389
reporter.log("Kernel load complete");
389-
if (retainDataForTesting) {
390-
componentForTesting = output.component;
391-
}
392-
if (options.features.newDumpInfo.isEnabled && options.dumpInfo) {
393-
untrimmedComponentForDumpInfo = output.component;
394-
}
395-
396-
if (options.cfeOnly) {
397-
ir.Component component = output.component;
398-
dumpUnusedLibrariesAndTrimComponent(component, output.libraries);
399-
await serializationTask.serializeComponent(component);
400-
}
401390
return output;
402391
}
403392

404-
void dumpUnusedLibrariesAndTrimComponent(
405-
ir.Component component, List<Uri> libraries) {
406-
if (options.fromDill) {
407-
if (options.dumpUnusedLibraries) {
408-
dumpUnusedLibraries(component, libraries);
393+
Future<load_kernel.Output> produceKernel() async {
394+
if (options.readClosedWorldUri == null) {
395+
load_kernel.Output output = await loadKernel();
396+
if (output == null || compilationFailed) return null;
397+
ir.Component component = output.component;
398+
if (retainDataForTesting) {
399+
componentForTesting = component;
400+
}
401+
if (options.features.newDumpInfo.isEnabled && options.dumpInfo) {
402+
untrimmedComponentForDumpInfo = component;
409403
}
410-
if (options.entryUri != null) {
411-
component = trimComponent(component, libraries);
404+
if (options.cfeOnly) {
405+
if (options.fromDill) {
406+
List<Uri> libraries = output.libraries;
407+
if (options.dumpUnusedLibraries) {
408+
dumpUnusedLibraries(component, libraries);
409+
}
410+
if (options.entryUri != null) {
411+
component = trimComponent(component, libraries);
412+
}
413+
}
414+
await serializationTask.serializeComponent(component);
412415
}
416+
// We currently do not return the trimmed component from [produceKernel]
417+
// because downstream phases, in particular modular analysis, currently
418+
// depend on the untrimmed dill.
419+
return output;
420+
} else {
421+
ir.Component component =
422+
await serializationTask.deserializeComponentAndUpdateOptions();
423+
return load_kernel.Output(component, null, null, null, null);
413424
}
414425
}
415426

416-
void runModularAnalysis() async {
417-
load_kernel.Output output = await runLoadKernel();
418-
if (output == null || compilationFailed) return;
427+
bool shouldStopAfterLoadKernel(load_kernel.Output output) =>
428+
output == null || compilationFailed || options.cfeOnly;
419429

430+
Future<ModuleData> runModularAnalysis(
431+
load_kernel.Output output, Set<Uri> moduleLibraries) async {
420432
ir.Component component = output.component;
421433
List<Uri> libraries = output.libraries;
422-
Set<Uri> moduleLibraries = output.moduleLibraries.toSet();
423434
_userCodeLocations
424435
.addAll(moduleLibraries.map((module) => CodeLocation(module)));
425436
final input = modular_analysis.Input(
426437
options, reporter, environment, component, libraries, moduleLibraries);
427-
ModuleData moduleData = await selfTask.measureSubtask(
438+
return await selfTask.measureSubtask(
428439
'runModularAnalysis', () async => modular_analysis.run(input));
429-
if (compilationFailed) return;
430-
serializationTask.testModuleSerialization(moduleData, component);
431-
serializationTask.serializeModuleData(
432-
moduleData, component, moduleLibraries);
433440
}
434441

442+
Future<List<ModuleData>> produceModuleData(load_kernel.Output output) async {
443+
ir.Component component = output.component;
444+
if (options.modularMode) {
445+
Set<Uri> moduleLibraries = output.moduleLibraries.toSet();
446+
ModuleData moduleData = await runModularAnalysis(output, moduleLibraries);
447+
if (options.writeModularAnalysisUri != null && !compilationFailed) {
448+
serializationTask.testModuleSerialization(moduleData, component);
449+
serializationTask.serializeModuleData(
450+
moduleData, component, moduleLibraries);
451+
}
452+
return [moduleData];
453+
} else {
454+
return await serializationTask.deserializeModuleData(component);
455+
}
456+
}
457+
458+
bool get shouldStopAfterModularAnalysis =>
459+
compilationFailed || options.writeModularAnalysisUri != null;
460+
435461
GlobalTypeInferenceResults performGlobalTypeInference(
436462
JClosedWorld closedWorld) {
437463
FunctionEntity mainFunction = closedWorld.elementEnvironment.mainFunction;
@@ -508,48 +534,23 @@ class Compiler {
508534
globalTypeInferenceResultsData);
509535
}
510536

511-
Future<load_kernel.Output> loadComponent() async {
512-
load_kernel.Output output = await runLoadKernel();
513-
if (output == null || compilationFailed) return null;
514-
537+
Future<ClosedWorldAndIndices> produceClosedWorld(
538+
load_kernel.Output output, List<ModuleData> moduleData) async {
515539
ir.Component component = output.component;
516-
List<Uri> libraries = output.libraries;
517-
frontendStrategy.registerLoadedLibraries(component, libraries);
518-
List<ModuleData> data;
519-
if (options.hasModularAnalysisInputs) {
520-
data = await serializationTask.deserializeModuleData(component);
521-
}
522-
frontendStrategy.registerModuleData(data);
523-
524-
// After we've deserialized modular data, we trim the component of any
525-
// unnecessary dependencies.
526-
// Note: It is critical we wait to trim the dill until after we've
527-
// deserialized modular data because some of this data may reference
528-
// 'trimmed' elements.
529-
dumpUnusedLibrariesAndTrimComponent(component, libraries);
530-
return output;
531-
}
532-
533-
Future<ClosedWorldAndIndices> produceClosedWorld() async {
534540
ClosedWorldAndIndices closedWorldAndIndices;
535541
if (options.readClosedWorldUri == null) {
536-
load_kernel.Output loadKernelOutput = await loadComponent();
537-
if (loadKernelOutput != null) {
538-
Uri rootLibraryUri = loadKernelOutput.rootLibraryUri;
539-
Iterable<Uri> libraries = loadKernelOutput.libraries;
540-
_userCodeLocations.add(CodeLocation(rootLibraryUri));
541-
JsClosedWorld closedWorld =
542-
computeClosedWorld(rootLibraryUri, libraries);
543-
closedWorldAndIndices = ClosedWorldAndIndices(closedWorld, null);
544-
if (options.writeClosedWorldUri != null) {
545-
serializationTask.serializeComponent(
546-
closedWorld.elementMap.programEnv.mainComponent);
547-
serializationTask.serializeClosedWorld(closedWorld);
548-
}
542+
Uri rootLibraryUri = output.rootLibraryUri;
543+
Iterable<Uri> libraries = output.libraries;
544+
_userCodeLocations.add(CodeLocation(rootLibraryUri));
545+
JsClosedWorld closedWorld =
546+
computeClosedWorld(component, moduleData, rootLibraryUri, libraries);
547+
closedWorldAndIndices = ClosedWorldAndIndices(closedWorld, null);
548+
if (options.writeClosedWorldUri != null) {
549+
serializationTask.serializeComponent(
550+
closedWorld.elementMap.programEnv.mainComponent);
551+
serializationTask.serializeClosedWorld(closedWorld);
549552
}
550553
} else {
551-
ir.Component component =
552-
await serializationTask.deserializeComponentAndUpdateOptions();
553554
closedWorldAndIndices = await serializationTask.deserializeClosedWorld(
554555
environment, abstractValueStrategy, component);
555556
}
@@ -625,29 +626,40 @@ class Compiler {
625626
bool get shouldStopAfterCodegen => options.writeCodegenUri != null;
626627

627628
void runSequentialPhases() async {
628-
await selfTask.measureSubtask("compileFromKernel", () async {
629-
// Load kernel and compute closed world.
630-
ClosedWorldAndIndices closedWorldAndIndices = await produceClosedWorld();
631-
if (shouldStopAfterClosedWorld(closedWorldAndIndices)) return;
632-
633-
// Run global analysis.
634-
GlobalTypeInferenceResults globalTypeInferenceResults =
635-
await produceGlobalTypeInferenceResults(closedWorldAndIndices);
636-
if (shouldStopAfterGlobalTypeInference) return;
637-
638-
// Run codegen.
639-
CodegenResults codegenResults = await produceCodegenResults(
640-
globalTypeInferenceResults, closedWorldAndIndices.indices);
641-
if (shouldStopAfterCodegen) return;
642-
643-
// Link.
644-
int programSize = runCodegenEnqueuer(codegenResults);
645-
646-
// Dump Info.
647-
if (options.dumpInfo) {
648-
runDumpInfo(codegenResults, programSize);
649-
}
650-
});
629+
// Load kernel.
630+
load_kernel.Output output = await produceKernel();
631+
if (shouldStopAfterLoadKernel(output)) return;
632+
633+
// Run modular analysis. This may be null if modular analysis was not
634+
// requested for this pipeline.
635+
List<ModuleData> moduleData;
636+
if (options.modularMode || options.hasModularAnalysisInputs) {
637+
moduleData = await produceModuleData(output);
638+
}
639+
if (shouldStopAfterModularAnalysis) return;
640+
641+
// Compute closed world.
642+
ClosedWorldAndIndices closedWorldAndIndices =
643+
await produceClosedWorld(output, moduleData);
644+
if (shouldStopAfterClosedWorld(closedWorldAndIndices)) return;
645+
646+
// Run global analysis.
647+
GlobalTypeInferenceResults globalTypeInferenceResults =
648+
await produceGlobalTypeInferenceResults(closedWorldAndIndices);
649+
if (shouldStopAfterGlobalTypeInference) return;
650+
651+
// Run codegen.
652+
CodegenResults codegenResults = await produceCodegenResults(
653+
globalTypeInferenceResults, closedWorldAndIndices.indices);
654+
if (shouldStopAfterCodegen) return;
655+
656+
// Link.
657+
int programSize = runCodegenEnqueuer(codegenResults);
658+
659+
// Dump Info.
660+
if (options.dumpInfo) {
661+
runDumpInfo(codegenResults, programSize);
662+
}
651663
}
652664

653665
void runDumpInfo(CodegenResults codegenResults, int programSize) {

0 commit comments

Comments
 (0)