mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 13:28:03 +00:00
[dart2js] Disable kernel transformer when using modular analysis.
Mutating the kernel AST can cause serialization and deserialization to go out of sync when modular analysis is enabled, crashing dart2js. Change-Id: If19afabacf1cb120a6804bd12ef268316de41f1b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286862 Reviewed-by: Sigmund Cherem <sigmund@google.com> Reviewed-by: Nate Biggs <natebiggs@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
parent
3c633384d3
commit
6414db5327
|
@ -397,7 +397,7 @@ class Compiler {
|
|||
}
|
||||
|
||||
Future<load_kernel.Output?> produceKernel() async {
|
||||
if (options.readClosedWorldUri == null) {
|
||||
if (shouldComputeClosedWorld) {
|
||||
load_kernel.Output? output = await loadKernel();
|
||||
if (output == null || compilationFailed) return null;
|
||||
ir.Component component = output.component;
|
||||
|
@ -445,42 +445,37 @@ class Compiler {
|
|||
bool shouldStopAfterLoadKernel(load_kernel.Output? output) =>
|
||||
output == null || compilationFailed || options.cfeOnly;
|
||||
|
||||
void simplifyConstConditionals(load_kernel.Output output) {
|
||||
if (options.readClosedWorldUri == null) {
|
||||
void reportMessage(
|
||||
fe.LocatedMessage message, List<fe.LocatedMessage>? context) {
|
||||
reportLocatedMessage(reporter, message, context);
|
||||
}
|
||||
|
||||
bool shouldNotInline(ir.TreeNode node) {
|
||||
if (node is! ir.Annotatable) {
|
||||
return false;
|
||||
}
|
||||
return computePragmaAnnotationDataFromIr(node).any((pragma) =>
|
||||
pragma == const PragmaAnnotationData('noInline') ||
|
||||
pragma == const PragmaAnnotationData('never-inline'));
|
||||
}
|
||||
|
||||
// No existing closed world means we're in phase 1, so run the
|
||||
// transformer.
|
||||
fe.ConstConditionalSimplifier(
|
||||
const Dart2jsDartLibrarySupport(),
|
||||
const Dart2jsConstantsBackend(
|
||||
supportsUnevaluatedConstants: false),
|
||||
output.component,
|
||||
reportMessage,
|
||||
environmentDefines: environment.definitions,
|
||||
evaluationMode: options.useLegacySubtyping
|
||||
? fe.EvaluationMode.weak
|
||||
: fe.EvaluationMode.strong,
|
||||
shouldNotInline: shouldNotInline)
|
||||
.run();
|
||||
void simplifyConstConditionals(ir.Component component) {
|
||||
void reportMessage(
|
||||
fe.LocatedMessage message, List<fe.LocatedMessage>? context) {
|
||||
reportLocatedMessage(reporter, message, context);
|
||||
}
|
||||
|
||||
// If the closed world is deserialized instead, then the input .dill should
|
||||
// already have the modified AST.
|
||||
bool shouldNotInline(ir.TreeNode node) {
|
||||
if (node is! ir.Annotatable) {
|
||||
return false;
|
||||
}
|
||||
return computePragmaAnnotationDataFromIr(node).any((pragma) =>
|
||||
pragma == const PragmaAnnotationData('noInline') ||
|
||||
pragma == const PragmaAnnotationData('never-inline'));
|
||||
}
|
||||
|
||||
fe.ConstConditionalSimplifier(
|
||||
const Dart2jsDartLibrarySupport(),
|
||||
const Dart2jsConstantsBackend(supportsUnevaluatedConstants: false),
|
||||
component,
|
||||
reportMessage,
|
||||
environmentDefines: environment.definitions,
|
||||
evaluationMode: options.useLegacySubtyping
|
||||
? fe.EvaluationMode.weak
|
||||
: fe.EvaluationMode.strong,
|
||||
shouldNotInline: shouldNotInline)
|
||||
.run();
|
||||
}
|
||||
|
||||
bool get usingModularAnalysis =>
|
||||
options.modularMode || options.hasModularAnalysisInputs;
|
||||
|
||||
Future<ModuleData> runModularAnalysis(
|
||||
load_kernel.Output output, Set<Uri> moduleLibraries) async {
|
||||
ir.Component component = output.component;
|
||||
|
@ -600,11 +595,28 @@ class Compiler {
|
|||
globalTypeInferenceResultsData);
|
||||
}
|
||||
|
||||
bool get shouldComputeClosedWorld => options.readClosedWorldUri == null;
|
||||
|
||||
Future<DataAndIndices<JClosedWorld>?> produceClosedWorld(
|
||||
load_kernel.Output output, ModuleData? moduleData) async {
|
||||
ir.Component component = output.component;
|
||||
DataAndIndices<JClosedWorld> closedWorldAndIndices;
|
||||
if (options.readClosedWorldUri == null) {
|
||||
if (shouldComputeClosedWorld) {
|
||||
if (!usingModularAnalysis) {
|
||||
// If we're deserializing the closed world, the input .dill already
|
||||
// contains the modified AST, so the transformer only needs to run if
|
||||
// the closed world is being computed from scratch.
|
||||
//
|
||||
// However, the transformer is not currently compatible with modular
|
||||
// analysis. When modular analysis is enabled in Blaze, some aspects run
|
||||
// before this phase of the compiler. This can cause dart2js to crash if
|
||||
// the kernel AST is mutated, since we will attempt to serialize and
|
||||
// deserialize against different ASTs.
|
||||
//
|
||||
// TODO(fishythefish): Make this compatible with modular analysis.
|
||||
simplifyConstConditionals(component);
|
||||
}
|
||||
|
||||
Uri rootLibraryUri = output.rootLibraryUri!;
|
||||
List<Uri> libraries = output.libraries!;
|
||||
final closedWorld =
|
||||
|
@ -724,19 +736,17 @@ class Compiler {
|
|||
final output = await produceKernel();
|
||||
if (shouldStopAfterLoadKernel(output)) return;
|
||||
|
||||
simplifyConstConditionals(output!);
|
||||
|
||||
// Run modular analysis. This may be null if modular analysis was not
|
||||
// requested for this pipeline.
|
||||
ModuleData? moduleData;
|
||||
if (options.modularMode || options.hasModularAnalysisInputs) {
|
||||
moduleData = await produceModuleData(output);
|
||||
if (usingModularAnalysis) {
|
||||
moduleData = await produceModuleData(output!);
|
||||
}
|
||||
if (shouldStopAfterModularAnalysis) return;
|
||||
|
||||
// Compute closed world.
|
||||
DataAndIndices<JClosedWorld>? closedWorldAndIndices =
|
||||
await produceClosedWorld(output, moduleData);
|
||||
await produceClosedWorld(output!, moduleData);
|
||||
if (shouldStopAfterClosedWorld(closedWorldAndIndices)) return;
|
||||
|
||||
// Run global analysis.
|
||||
|
|
Loading…
Reference in a new issue