[dart2js] Decouple closed world and serialization.
Change-Id: Idf9420eb1d461b9a2cff90354cfbfee601b75ae8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330861
Reviewed-by: Sigmund Cherem <sigmund@google.com>
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 0d0d556..c46e74e 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -8,11 +8,8 @@
import '../common/elements.dart';
import '../constants/values.dart';
-import '../deferred_load/output_unit.dart' show OutputUnit;
import '../elements/entities.dart';
import '../elements/types.dart' show DartType, InterfaceType;
-import '../inferrer/abstract_value_domain.dart';
-import '../inferrer/types.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart';
@@ -25,8 +22,6 @@
import '../js_backend/type_reference.dart' show TypeReference;
import '../js_emitter/js_emitter.dart' show Emitter;
import '../js_model/elements.dart';
-import '../js_model/js_world.dart';
-import '../js_model/type_recipe.dart' show TypeRecipe;
import '../native/behavior.dart';
import '../serialization/serialization.dart';
import '../universe/feature.dart';
@@ -401,8 +396,8 @@
return CodegenResult(
code,
_worldImpact,
- js.DeferredExpressionData(_names.isEmpty ? [] : _names,
- _expressions.isEmpty ? [] : _expressions));
+ js.DeferredExpressionData(_names.isEmpty ? const [] : _names,
+ _expressions.isEmpty ? const [] : _expressions));
}
}
@@ -411,13 +406,10 @@
/// This is used in the non-modular codegen enqueuer driving code generation.
class OnDemandCodegenResults extends CodegenResults {
@override
- final GlobalTypeInferenceResults globalTypeInferenceResults;
- @override
final CodegenInputs codegenInputs;
final FunctionCompiler _functionCompiler;
- OnDemandCodegenResults(this.globalTypeInferenceResults, this.codegenInputs,
- this._functionCompiler);
+ OnDemandCodegenResults(this.codegenInputs, this._functionCompiler);
@override
CodegenResult getCodegenResults(MemberEntity member) {
@@ -441,7 +433,7 @@
js.Fun? code = source.readJsNodeOrNull() as js.Fun?;
CodegenImpact impact = CodegenImpact.readFromDataSource(source);
final deferredExpressionData =
- js.DeferredExpressionData.readFromDataSource(source);
+ js.DeferredExpressionRegistry.readDataFromDataSource(source);
source.end(tag);
if (code != null) {
code = code.withAnnotation(deferredExpressionData) as js.Fun;
@@ -452,10 +444,11 @@
/// Writes the [CodegenResult] object to [sink].
void writeToDataSink(DataSinkWriter sink) {
sink.begin(tag);
- deferredExpressionData.prepareForSerialization();
- sink.writeJsNodeOrNull(code);
+ final registry = js.DeferredExpressionRegistry();
+ sink.withDeferredExpressionRegistry(
+ registry, () => sink.writeJsNodeOrNull(code));
impact.writeToDataSink(sink);
- deferredExpressionData.writeToDataSink(sink);
+ registry.writeToDataSink(sink);
sink.end(tag);
}
@@ -796,15 +789,14 @@
/// them in the AST.
class JsNodeSerializer implements js.NodeVisitor<void> {
final DataSinkWriter sink;
- final js.DeferredExpressionData deferredExpressionData;
+ final js.DeferredExpressionRegistry? _registry;
- JsNodeSerializer._(this.sink, this.deferredExpressionData);
+ JsNodeSerializer._(this.sink, this._registry);
static void writeToDataSink(DataSinkWriter sink, js.Node node,
- js.DeferredExpressionData deferredExpressionData) {
+ js.DeferredExpressionRegistry? registry) {
sink.begin(JsNodeTags.tag);
- JsNodeSerializer serializer =
- JsNodeSerializer._(sink, deferredExpressionData);
+ JsNodeSerializer serializer = JsNodeSerializer._(sink, registry);
serializer.visit(node);
sink.end(JsNodeTags.tag);
}
@@ -981,7 +973,7 @@
node.writeToDataSink(sink);
_writeInfo(node);
}, identity: true);
- deferredExpressionData.registerModularName(node);
+ _registry?.registerModularName(node);
sink.end(JsNodeTags.modularName);
} else if (node is AsyncName) {
sink.writeEnum(JsNodeKind.asyncName);
@@ -1077,7 +1069,7 @@
node.writeToDataSink(sink);
_writeInfo(node);
}, identity: true);
- deferredExpressionData.registerModularExpression(node);
+ _registry?.registerModularExpression(node);
sink.end(JsNodeTags.modularExpression);
} else if (node is TypeReference) {
sink.writeEnum(JsNodeKind.typeReference);
@@ -1086,7 +1078,7 @@
node.writeToDataSink(sink);
_writeInfo(node);
}, identity: true);
- deferredExpressionData.registerTypeReference(node);
+ _registry?.registerTypeReference(node);
sink.end(JsNodeTags.typeReference);
} else if (node is StringReference) {
sink.writeEnum(JsNodeKind.stringReference);
@@ -1095,7 +1087,7 @@
node.writeToDataSink(sink);
_writeInfo(node);
}, identity: true);
- deferredExpressionData.registerStringReference(node);
+ _registry?.registerStringReference(node);
sink.end(JsNodeTags.stringReference);
} else if (node is DeferredHolderExpression) {
sink.writeEnum(JsNodeKind.deferredHolderExpression);
@@ -1104,7 +1096,7 @@
node.writeToDataSink(sink);
_writeInfo(node);
}, identity: true);
- deferredExpressionData.registerDeferredHolderExpression(node);
+ _registry?.registerDeferredHolderExpression(node);
sink.end(JsNodeTags.deferredHolderExpression);
} else {
throw UnsupportedError(
@@ -1977,60 +1969,6 @@
}
}
-class CodegenReaderImpl implements CodegenReader {
- final JClosedWorld closedWorld;
-
- CodegenReaderImpl(this.closedWorld);
-
- @override
- AbstractValue readAbstractValue(DataSourceReader source) {
- return closedWorld.abstractValueDomain
- .readAbstractValueFromDataSource(source);
- }
-
- @override
- js.Node readJsNode(DataSourceReader source) {
- return JsNodeDeserializer.readFromDataSource(source);
- }
-
- @override
- OutputUnit readOutputUnitReference(DataSourceReader source) {
- return closedWorld.outputUnitData.outputUnits[source.readInt()];
- }
-
- @override
- TypeRecipe readTypeRecipe(DataSourceReader source) {
- return TypeRecipe.readFromDataSource(source);
- }
-}
-
-class CodegenWriterImpl implements CodegenWriter {
- final JClosedWorld closedWorld;
- final js.DeferredExpressionData deferredExpressionData;
-
- CodegenWriterImpl(this.closedWorld, this.deferredExpressionData);
-
- @override
- void writeAbstractValue(DataSinkWriter sink, AbstractValue value) {
- closedWorld.abstractValueDomain.writeAbstractValueToDataSink(sink, value);
- }
-
- @override
- void writeJsNode(DataSinkWriter sink, js.Node node) {
- JsNodeSerializer.writeToDataSink(sink, node, deferredExpressionData);
- }
-
- @override
- void writeOutputUnitReference(DataSinkWriter sink, OutputUnit value) {
- sink.writeInt(closedWorld.outputUnitData.outputUnits.indexOf(value));
- }
-
- @override
- void writeTypeRecipe(DataSinkWriter sink, TypeRecipe recipe) {
- recipe.writeToDataSink(sink);
- }
-}
-
enum ModularNameKind {
rtiField,
className,
@@ -2296,7 +2234,6 @@
/// Interface for reading the code generation results for all [MemberEntity]s.
abstract class CodegenResults {
- GlobalTypeInferenceResults get globalTypeInferenceResults;
CodegenInputs get codegenInputs;
CodegenResult getCodegenResults(MemberEntity member);
}
@@ -2306,14 +2243,11 @@
/// This is used for modular code generation.
class DeserializedCodegenResults extends CodegenResults {
@override
- final GlobalTypeInferenceResults globalTypeInferenceResults;
- @override
final CodegenInputs codegenInputs;
final Map<MemberEntity, CodegenResult> _map;
- DeserializedCodegenResults(
- this.globalTypeInferenceResults, this.codegenInputs, this._map);
+ DeserializedCodegenResults(this.codegenInputs, this._map);
@override
CodegenResult getCodegenResults(MemberEntity member) {
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index aabfe03..2fc3e76 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -36,6 +36,7 @@
import 'elements/entities.dart';
import 'enqueue.dart' show Enqueuer;
import 'environment.dart';
+import 'inferrer/abstract_value_domain.dart';
import 'inferrer/abstract_value_strategy.dart';
import 'inferrer/computable.dart' show ComputableAbstractValueStrategy;
import 'inferrer/powersets/powersets.dart' show PowersetStrategy;
@@ -522,18 +523,13 @@
}
int runCodegenEnqueuer(
- CodegenResults codegenResults, SourceLookup sourceLookup) {
- GlobalTypeInferenceResults globalInferenceResults =
- codegenResults.globalTypeInferenceResults;
- JClosedWorld closedWorld = globalInferenceResults.closedWorld;
+ CodegenResults codegenResults,
+ InferredData inferredData,
+ SourceLookup sourceLookup,
+ JClosedWorld closedWorld) {
CodegenInputs codegenInputs = codegenResults.codegenInputs;
CodegenEnqueuer codegenEnqueuer = backendStrategy.createCodegenEnqueuer(
- enqueueTask,
- closedWorld,
- globalInferenceResults,
- codegenInputs,
- codegenResults,
- sourceLookup)
+ enqueueTask, closedWorld, codegenInputs, codegenResults, sourceLookup)
..onEmptyForTesting = onCodegenQueueEmptyForTesting;
if (retainDataForTesting) {
codegenEnqueuerForTesting = codegenEnqueuer;
@@ -550,8 +546,8 @@
codegenWorldForTesting = codegenWorld;
}
reporter.log('Emitting JavaScript');
- int programSize = backendStrategy.assembleProgram(closedWorld,
- globalInferenceResults.inferredData, codegenInputs, codegenWorld);
+ int programSize = backendStrategy.assembleProgram(
+ closedWorld, inferredData, codegenInputs, codegenWorld);
backendStrategy.onCodegenEnd(codegenInputs);
@@ -684,16 +680,19 @@
CodegenInputs codegenInputs = initializeCodegen(globalTypeInferenceResults);
CodegenResults codegenResults;
if (!stage.shouldReadCodegenShards) {
- codegenResults = OnDemandCodegenResults(globalTypeInferenceResults,
+ codegenResults = OnDemandCodegenResults(
codegenInputs, backendStrategy.functionCompiler);
if (stage == Dart2JSStage.codegenSharded) {
serializationTask.serializeCodegen(
- backendStrategy, codegenResults, indices);
+ backendStrategy,
+ globalTypeInferenceResults.closedWorld.abstractValueDomain,
+ codegenResults,
+ indices);
}
} else {
codegenResults = await serializationTask.deserializeCodegen(
backendStrategy,
- globalTypeInferenceResults,
+ globalTypeInferenceResults.closedWorld,
codegenInputs,
useDeferredSourceReads,
sourceLookup,
@@ -733,13 +732,20 @@
await produceGlobalTypeInferenceResults(
closedWorld!, output.component, indices);
if (shouldStopAfterGlobalTypeInference) return;
+ closedWorld = globalTypeInferenceResults.closedWorld;
// Allow the original references to these to be GCed and only hold
// references to them if we are actually running the dump info task later.
- JClosedWorld? closedWorldForDumpInfo;
SerializationIndices? indicesForDumpInfo;
- if (options.dumpInfoWriteUri != null || options.dumpInfoReadUri != null) {
- closedWorldForDumpInfo = closedWorld;
+ GlobalTypeInferenceResults? globalTypeInferenceResultsForDumpInfo;
+ AbstractValueDomain? abstractValueDomainForDumpInfo;
+ OutputUnitData? outputUnitDataForDumpInfo;
+ if (options.dumpInfoWriteUri != null ||
+ options.dumpInfoReadUri != null ||
+ options.dumpInfo) {
+ globalTypeInferenceResultsForDumpInfo = globalTypeInferenceResults;
+ abstractValueDomainForDumpInfo = closedWorld.abstractValueDomain;
+ outputUnitDataForDumpInfo = closedWorld.outputUnitData;
indicesForDumpInfo = indices;
}
@@ -748,33 +754,43 @@
CodegenResults codegenResults = await produceCodegenResults(
globalTypeInferenceResults, sourceLookup, indices);
if (shouldStopAfterCodegen) return;
+ final inferredData = globalTypeInferenceResults.inferredData;
if (options.dumpInfoReadUri != null) {
final dumpInfoData =
await serializationTask.deserializeDumpInfoProgramData(
- backendStrategy, closedWorldForDumpInfo!, indicesForDumpInfo!);
- await runDumpInfo(codegenResults, dumpInfoData);
+ backendStrategy,
+ abstractValueDomainForDumpInfo!,
+ outputUnitDataForDumpInfo!,
+ indicesForDumpInfo!);
+ await runDumpInfo(
+ codegenResults, globalTypeInferenceResultsForDumpInfo!, dumpInfoData);
} else {
// Link.
- final programSize = runCodegenEnqueuer(codegenResults, sourceLookup);
+ final programSize = runCodegenEnqueuer(
+ codegenResults, inferredData, sourceLookup, closedWorld);
if (options.dumpInfo || options.dumpInfoWriteUri != null) {
final dumpInfoData = DumpInfoProgramData.fromEmitterResults(
backendStrategy, dumpInfoRegistry, programSize);
dumpInfoRegistry.clear();
if (options.dumpInfo) {
- await runDumpInfo(codegenResults, dumpInfoData);
+ await runDumpInfo(codegenResults,
+ globalTypeInferenceResultsForDumpInfo!, dumpInfoData);
} else {
- serializationTask.serializeDumpInfoProgramData(backendStrategy,
- dumpInfoData, closedWorldForDumpInfo!, indicesForDumpInfo!);
+ serializationTask.serializeDumpInfoProgramData(
+ backendStrategy,
+ dumpInfoData,
+ abstractValueDomainForDumpInfo!,
+ indicesForDumpInfo!);
}
}
}
}
- Future<void> runDumpInfo(CodegenResults codegenResults,
+ Future<void> runDumpInfo(
+ CodegenResults codegenResults,
+ GlobalTypeInferenceResults globalTypeInferenceResults,
DumpInfoProgramData dumpInfoProgramData) async {
- GlobalTypeInferenceResults globalTypeInferenceResults =
- codegenResults.globalTypeInferenceResults;
JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
DumpInfoStateData dumpInfoState;
diff --git a/pkg/compiler/lib/src/deferred_load/output_unit.dart b/pkg/compiler/lib/src/deferred_load/output_unit.dart
index a116e6f..e9551f8 100644
--- a/pkg/compiler/lib/src/deferred_load/output_unit.dart
+++ b/pkg/compiler/lib/src/deferred_load/output_unit.dart
@@ -22,6 +22,8 @@
///
/// We never create two OutputUnits sharing the same set of [imports].
class OutputUnit implements Comparable<OutputUnit> {
+ static const String tag = 'output-unit';
+
/// `true` if this output unit is for the main output file.
final bool isMainOutput;
@@ -33,6 +35,23 @@
OutputUnit(this.isMainOutput, this.name, this.imports);
+ void writeToDataSink(DataSinkWriter sink) {
+ sink.begin(tag);
+ sink.writeBool(isMainOutput);
+ sink.writeString(name);
+ sink.writeImports(imports);
+ sink.end(tag);
+ }
+
+ static OutputUnit readFromDataSource(DataSourceReader source) {
+ source.begin(tag);
+ final isMainOutput = source.readBool();
+ final name = source.readString();
+ final imports = source.readImports().toSet();
+ source.end(tag);
+ return OutputUnit(isMainOutput, name, imports);
+ }
+
@override
int compareTo(OutputUnit other) {
if (identical(this, other)) return 0;
@@ -167,12 +186,8 @@
factory OutputUnitData.readFromDataSource(DataSourceReader source) {
source.begin(tag);
bool isProgramSplit = source.readBool();
- List<OutputUnit> outputUnits = source.readList(() {
- bool isMainOutput = source.readBool();
- String name = source.readString();
- Set<ImportEntity> importSet = source.readImports().toSet();
- return OutputUnit(isMainOutput, name, importSet);
- });
+ List<OutputUnit> outputUnits =
+ source.readList(source.readOutputUnitReference);
OutputUnit mainOutputUnit = outputUnits[source.readInt()];
Map<ClassEntity, OutputUnit> classToUnit = source.readClassMap(() {
@@ -219,9 +234,7 @@
Map<OutputUnit, int> outputUnitIndices = {};
sink.writeList(outputUnits, (OutputUnit outputUnit) {
outputUnitIndices[outputUnit] = outputUnitIndices.length;
- sink.writeBool(outputUnit.isMainOutput);
- sink.writeString(outputUnit.name);
- sink.writeImports(outputUnit.imports);
+ sink.writeOutputUnitReference(outputUnit);
});
sink.writeInt(outputUnitIndices[mainOutputUnit]!);
sink.writeClassMap(_classToUnit, (OutputUnit outputUnit) {
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 53fdd3b..bcb43a5 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -23,7 +23,8 @@
import 'common/ram_usage.dart';
import 'constants/values.dart'
show ConstantValue, ConstantValueKind, DeferredGlobalConstantValue;
-import 'deferred_load/output_unit.dart' show OutputUnit, deferredPartFileName;
+import 'deferred_load/output_unit.dart'
+ show OutputUnit, OutputUnitData, deferredPartFileName;
import 'elements/entities.dart';
import 'elements/entity_utils.dart' as entity_utils;
import 'elements/names.dart';
@@ -231,7 +232,7 @@
}
factory DumpInfoProgramData.readFromDataSource(
- DataSourceReader source, JClosedWorld closedWorld,
+ DataSourceReader source, OutputUnitData outputUnitData,
{required bool includeCodeText}) {
final programSize = source.readInt();
final outputUnitSizesLength = source.readInt();
@@ -275,7 +276,7 @@
.readList(() => ConstantUse.readFromDataSource(source))
.forEach((use) {
assert(use.value.kind == ConstantValueKind.DEFERRED_GLOBAL);
- closedWorld.outputUnitData.registerConstantDeferredUse(
+ outputUnitData.registerConstantDeferredUse(
use.value as DeferredGlobalConstantValue);
});
return impactBuilder;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 62e2f61..87088ec 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -203,34 +203,15 @@
return null;
}
-/// Contains pointers to deferred expressions within a portion of the AST.
-///
-/// These objects are attached nodes that have been deserialized but whose
-/// bodies are kept in a serialized state. This allows us to skip deserializing
-/// the entire function body when we are trying to link these deferred
-/// expressions. A [DeferredExpressionData] will be added to
-/// [Node.annotations] for these functions. Visitors that just need these
-/// deferred expressions should then check the annotations for a [Node] and
-/// process them accordingly rather than deserializing all the [Node] children.
-class DeferredExpressionData {
- final List<ModularName> modularNames;
- final List<ModularExpression> modularExpressions;
- final List<TypeReference> typeReferences;
- final List<StringReference> stringReferences;
- final List<DeferredHolderExpression> deferredHolderExpressions;
+class DeferredExpressionRegistry {
+ final List<ModularName> modularNames = [];
+ final List<ModularExpression> modularExpressions = [];
+ final List<TypeReference> typeReferences = [];
+ final List<StringReference> stringReferences = [];
+ final List<DeferredHolderExpression> deferredHolderExpressions = [];
- DeferredExpressionData(this.modularNames, this.modularExpressions)
- : typeReferences = [],
- stringReferences = [],
- deferredHolderExpressions = [];
- DeferredExpressionData._(
- this.modularNames,
- this.modularExpressions,
- this.typeReferences,
- this.stringReferences,
- this.deferredHolderExpressions);
-
- factory DeferredExpressionData.readFromDataSource(DataSourceReader source) {
+ static DeferredExpressionData readDataFromDataSource(
+ DataSourceReader source) {
final modularNames =
source.readListOrNull(() => source.readJsNode() as ModularName) ??
const [];
@@ -250,11 +231,8 @@
typeReferences, stringReferences, deferredHolderExpressions);
}
- bool _serializing = false;
-
void writeToDataSink(DataSinkWriter sink) {
// Set [_serializing] so that we don't re-register nodes.
- _serializing = true;
sink.writeList(modularNames, (ModularName node) => sink.writeJsNode(node));
sink.writeList(
modularExpressions, (ModularExpression node) => sink.writeJsNode(node));
@@ -264,40 +242,57 @@
stringReferences, (StringReference node) => sink.writeJsNode(node));
sink.writeList(deferredHolderExpressions,
(DeferredHolderExpression node) => sink.writeJsNode(node));
- _serializing = false;
- }
-
- void prepareForSerialization() {
- modularNames.clear();
- modularExpressions.clear();
}
void registerModularName(ModularName node) {
- if (_serializing) return;
modularNames.add(node);
}
void registerModularExpression(ModularExpression node) {
- if (_serializing) return;
modularExpressions.add(node);
}
void registerTypeReference(TypeReference node) {
- if (_serializing) return;
typeReferences.add(node);
}
void registerStringReference(StringReference node) {
- if (_serializing) return;
stringReferences.add(node);
}
void registerDeferredHolderExpression(DeferredHolderExpression node) {
- if (_serializing) return;
deferredHolderExpressions.add(node);
}
}
+/// Contains pointers to deferred expressions within a portion of the AST.
+///
+/// These objects are attached nodes that have been deserialized but whose
+/// bodies are kept in a serialized state. This allows us to skip deserializing
+/// the entire function body when we are trying to link these deferred
+/// expressions. A [DeferredExpressionData] will be added to
+/// [Node.annotations] for these functions. Visitors that just need these
+/// deferred expressions should then check the annotations for a [Node] and
+/// process them accordingly rather than deserializing all the [Node] children.
+class DeferredExpressionData {
+ final List<ModularName> modularNames;
+ final List<ModularExpression> modularExpressions;
+ final List<TypeReference> typeReferences;
+ final List<StringReference> stringReferences;
+ final List<DeferredHolderExpression> deferredHolderExpressions;
+
+ DeferredExpressionData(this.modularNames, this.modularExpressions)
+ : typeReferences = const [],
+ stringReferences = const [],
+ deferredHolderExpressions = const [];
+ DeferredExpressionData._(
+ this.modularNames,
+ this.modularExpressions,
+ this.typeReferences,
+ this.stringReferences,
+ this.deferredHolderExpressions);
+}
+
/// A code [Block] that has not been fully deserialized but instead holds a
/// [Deferrable] to get the enclosed statements.
///
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 6384790..c84eba8 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -237,7 +237,6 @@
CodegenEnqueuer createCodegenEnqueuer(
CompilerTask task,
JClosedWorld closedWorld,
- GlobalTypeInferenceResults globalInferenceResults,
CodegenInputs codegen,
CodegenResults codegenResults,
SourceLookup sourceLookup) {
@@ -245,8 +244,7 @@
closedWorld.interceptorData,
closedWorld.commonElements,
closedWorld.nativeData);
- _onCodegenEnqueuerStart(
- globalInferenceResults, codegen, oneShotInterceptorData);
+ _onCodegenEnqueuerStart(closedWorld, codegen, oneShotInterceptorData);
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
CommonElements commonElements = closedWorld.commonElements;
BackendImpacts impacts = BackendImpacts(commonElements, _compiler.options);
@@ -261,7 +259,7 @@
oneShotInterceptorData),
KernelCodegenWorkItemBuilder(
this,
- closedWorld,
+ closedWorld.abstractValueDomain,
codegenResults,
// TODO(johnniwinther): Avoid the need for a [ComponentLookup]. This
// is caused by some type masks holding a kernel node for using in
@@ -283,11 +281,8 @@
}
/// Called before the compiler starts running the codegen enqueuer.
- void _onCodegenEnqueuerStart(
- GlobalTypeInferenceResults globalTypeInferenceResults,
- CodegenInputs codegen,
+ void _onCodegenEnqueuerStart(JClosedWorld closedWorld, CodegenInputs codegen,
OneShotInterceptorData oneShotInterceptorData) {
- JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
FixedNames fixedNames = codegen.fixedNames;
_namer = _compiler.options.enableMinification
? _compiler.options.useFrequencyNamer
@@ -324,7 +319,7 @@
WorldImpact generateCode(
WorkItem work,
- JClosedWorld closedWorld,
+ AbstractValueDomain abstractValueDomain,
CodegenResults codegenResults,
ComponentLookup componentLookup,
SourceLookup sourceLookup) {
@@ -337,14 +332,13 @@
DataSinkWriter sink = DataSinkWriter(
ObjectDataSink(data), _compiler.options, indices,
useDataKinds: useDataKinds);
- sink.registerCodegenWriter(
- CodegenWriterImpl(closedWorld, result.deferredExpressionData));
+ sink.registerAbstractValueDomain(abstractValueDomain);
result.writeToDataSink(sink);
sink.close();
DataSourceReader source = DataSourceReader(
ObjectDataSource(data), _compiler.options, indices,
useDataKinds: useDataKinds);
- source.registerCodegenReader(CodegenReaderImpl(closedWorld));
+ source.registerAbstractValueDomain(abstractValueDomain);
source.registerComponentLookup(componentLookup);
source.registerSourceLookup(sourceLookup);
result = CodegenResult.readFromDataSource(source);
@@ -430,25 +424,25 @@
class KernelCodegenWorkItemBuilder implements WorkItemBuilder {
final JsBackendStrategy _backendStrategy;
- final JClosedWorld _closedWorld;
+ final AbstractValueDomain _abstractValueDomain;
final CodegenResults _codegenResults;
final ComponentLookup _componentLookup;
final SourceLookup _sourceLookup;
- KernelCodegenWorkItemBuilder(this._backendStrategy, this._closedWorld,
+ KernelCodegenWorkItemBuilder(this._backendStrategy, this._abstractValueDomain,
this._codegenResults, this._componentLookup, this._sourceLookup);
@override
WorkItem? createWorkItem(MemberEntity entity) {
if (entity.isAbstract) return null;
- return KernelCodegenWorkItem(_backendStrategy, _closedWorld,
+ return KernelCodegenWorkItem(_backendStrategy, _abstractValueDomain,
_codegenResults, _componentLookup, _sourceLookup, entity);
}
}
class KernelCodegenWorkItem extends WorkItem {
final JsBackendStrategy _backendStrategy;
- final JClosedWorld _closedWorld;
+ final AbstractValueDomain _abstractValueDomain;
final CodegenResults _codegenResults;
final ComponentLookup _componentLookup;
final SourceLookup _sourceLookup;
@@ -457,7 +451,7 @@
KernelCodegenWorkItem(
this._backendStrategy,
- this._closedWorld,
+ this._abstractValueDomain,
this._codegenResults,
this._componentLookup,
this._sourceLookup,
@@ -465,8 +459,8 @@
@override
WorldImpact run() {
- return _backendStrategy.generateCode(
- this, _closedWorld, _codegenResults, _componentLookup, _sourceLookup);
+ return _backendStrategy.generateCode(this, _abstractValueDomain,
+ _codegenResults, _componentLookup, _sourceLookup);
}
}
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index b119412..2028ef7 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -7,6 +7,7 @@
import 'package:kernel/ast.dart' as ir;
import '../closure.dart';
import '../common.dart';
+import '../common/codegen.dart';
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
import '../deferred_load/output_unit.dart' show OutputUnit;
diff --git a/pkg/compiler/lib/src/serialization/sink.dart b/pkg/compiler/lib/src/serialization/sink.dart
index f048578..cf9186a 100644
--- a/pkg/compiler/lib/src/serialization/sink.dart
+++ b/pkg/compiler/lib/src/serialization/sink.dart
@@ -68,7 +68,8 @@
final Map<Type, IndexedSink> _generalCaches = {};
- late CodegenWriter _codegenWriter;
+ late AbstractValueDomain _abstractValueDomain;
+ js.DeferredExpressionRegistry? _deferredExpressionRegistry;
final Map<String, int>? tagFrequencyMap;
@@ -1183,28 +1184,30 @@
/// Writes an abstract [value] to this data sink.
///
- /// This feature is only available a [CodegenWriter] has been registered.
+ /// This feature is only available a [AbstractValueDomain] has been
+ /// registered.
void writeAbstractValue(AbstractValue value) {
- _codegenWriter.writeAbstractValue(this, value);
+ _abstractValueDomain.writeAbstractValueToDataSink(this, value);
}
/// Writes a reference to the output unit [value] to this data sink.
- ///
- /// This feature is only available a [CodegenWriter] has been registered.
void writeOutputUnitReference(OutputUnit value) {
- _codegenWriter.writeOutputUnitReference(this, value);
+ writeCached<OutputUnit>(value, (v) => v.writeToDataSink(this));
+ }
+
+ void withDeferredExpressionRegistry(
+ js.DeferredExpressionRegistry registry, void Function() f) {
+ _deferredExpressionRegistry = registry;
+ f();
+ _deferredExpressionRegistry = null;
}
/// Writes a js node [value] to this data sink.
- ///
- /// This feature is only available a [CodegenWriter] has been registered.
void writeJsNode(js.Node value) {
- _codegenWriter.writeJsNode(this, value);
+ JsNodeSerializer.writeToDataSink(this, value, _deferredExpressionRegistry);
}
/// Writes a potentially `null` js node [value] to this data sink.
- ///
- /// This feature is only available a [CodegenWriter] has been registered.
void writeJsNodeOrNull(js.Node? value) {
writeBool(value != null);
if (value != null) {
@@ -1213,16 +1216,14 @@
}
/// Writes TypeRecipe [value] to this data sink.
- ///
- /// This feature is only available a [CodegenWriter] has been registered.
void writeTypeRecipe(TypeRecipe value) {
- _codegenWriter.writeTypeRecipe(this, value);
+ value.writeToDataSink(this);
}
- /// Register a [CodegenWriter] with this data sink to support serialization
- /// of codegen only data.
- void registerCodegenWriter(CodegenWriter writer) {
- _codegenWriter = writer;
+ /// Register a [AbstractValueDomain] with this data sink to support
+ /// serialization of abstract values.
+ void registerAbstractValueDomain(AbstractValueDomain domain) {
+ _abstractValueDomain = domain;
}
/// Invoke [f] in the context of [member]. This sets up support for
diff --git a/pkg/compiler/lib/src/serialization/source.dart b/pkg/compiler/lib/src/serialization/source.dart
index 7086aa7..a141c35 100644
--- a/pkg/compiler/lib/src/serialization/source.dart
+++ b/pkg/compiler/lib/src/serialization/source.dart
@@ -65,7 +65,7 @@
final ValueInterner? interner;
final SerializationIndices importedIndices;
ComponentLookup? _componentLookup;
- CodegenReader? _codegenReader;
+ AbstractValueDomain? _abstractValueDomain;
SourceLookup? _sourceLookup;
late final IndexedSource<String> _stringIndex;
@@ -138,9 +138,10 @@
SourceLookup get sourceLookup => _sourceLookup!;
- /// deserialization of codegen only data.
- void registerCodegenReader(CodegenReader reader) {
- _codegenReader = reader;
+ /// Registers a [AbstractValueDomain] with this data source to support
+ /// deserialization of abstract values.
+ void registerAbstractValueDomain(AbstractValueDomain domain) {
+ _abstractValueDomain = domain;
}
/// Evaluates [f] with [DataSource] for the provided [source] as the
@@ -149,17 +150,17 @@
E readWithSource<E>(DataSourceReader source, E f()) {
final lastSource = _sourceReader;
final lastComponentLookup = _componentLookup;
- final lastCodegenReader = _codegenReader;
final lastStartOffset = startOffset;
+ final lastAbstractValueDomain = _abstractValueDomain;
_sourceReader = source._sourceReader;
_componentLookup = source._componentLookup;
- _codegenReader = source._codegenReader;
startOffset = source.startOffset;
+ _abstractValueDomain = source._abstractValueDomain;
final value = f();
_sourceReader = lastSource;
_componentLookup = lastComponentLookup;
- _codegenReader = lastCodegenReader;
startOffset = lastStartOffset;
+ _abstractValueDomain = lastAbstractValueDomain;
return value;
}
@@ -1417,39 +1418,25 @@
}
/// Reads an [AbstractValue] from this data source.
- ///
- /// This feature is only available a [CodegenReader] has been registered.
AbstractValue readAbstractValue() {
assert(
- _codegenReader != null,
+ _abstractValueDomain != null,
"Can not deserialize an AbstractValue "
- "without a registered codegen reader.");
- return _codegenReader!.readAbstractValue(this);
+ "without a registered AbstractValueDomain.");
+ return _abstractValueDomain!.readAbstractValueFromDataSource(this);
}
/// Reads a reference to an [OutputUnit] from this data source.
- ///
- /// This feature is only available a [CodegenReader] has been registered.
OutputUnit readOutputUnitReference() {
- assert(
- _codegenReader != null,
- "Can not deserialize an OutputUnit reference "
- "without a registered codegen reader.");
- return _codegenReader!.readOutputUnitReference(this);
+ return readCached<OutputUnit>(() => OutputUnit.readFromDataSource(this));
}
/// Reads a [js.Node] value from this data source.
- ///
- /// This feature is only available a [CodegenReader] has been registered.
js.Node readJsNode() {
- assert(_codegenReader != null,
- "Can not deserialize a JS node without a registered codegen reader.");
- return _codegenReader!.readJsNode(this);
+ return JsNodeDeserializer.readFromDataSource(this);
}
/// Reads a potentially `null` [js.Node] value from this data source.
- ///
- /// This feature is only available a [CodegenReader] has been registered.
js.Node? readJsNodeOrNull() {
bool hasValue = readBool();
if (hasValue) {
@@ -1459,12 +1446,8 @@
}
/// Reads a [TypeRecipe] value from this data source.
- ///
- /// This feature is only available a [CodegenReader] has been registered.
TypeRecipe readTypeRecipe() {
- assert(_codegenReader != null,
- "Can not deserialize a TypeRecipe without a registered codegen reader.");
- return _codegenReader!.readTypeRecipe(this);
+ return TypeRecipe.readFromDataSource(this);
}
MemberData _getMemberData(ir.Member node) {
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 54b9d55..694b70c 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'package:compiler/src/js/js.dart';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_from_binary.dart' as ir;
import 'package:kernel/binary/ast_to_binary.dart' as ir;
@@ -12,10 +11,12 @@
import '../commandline_options.dart' show Flags;
import '../common/codegen.dart';
import '../common/tasks.dart';
+import '../deferred_load/output_unit.dart';
import '../diagnostics/diagnostic_listener.dart';
import '../dump_info.dart';
import '../elements/entities.dart';
import '../environment.dart';
+import '../inferrer/abstract_value_domain.dart';
import '../inferrer/abstract_value_strategy.dart';
import '../inferrer/types.dart';
import '../io/source_information.dart';
@@ -265,11 +266,11 @@
});
}
- void serializeCodegen(JsBackendStrategy backendStrategy,
- CodegenResults codegenResults, SerializationIndices indices) {
- GlobalTypeInferenceResults globalTypeInferenceResults =
- codegenResults.globalTypeInferenceResults;
- JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
+ void serializeCodegen(
+ JsBackendStrategy backendStrategy,
+ AbstractValueDomain domain,
+ CodegenResults codegenResults,
+ SerializationIndices indices) {
int shard = _options.codegenShard!;
int shards = _options.codegenShards!;
Map<MemberEntity, CodegenResult> results = {};
@@ -291,9 +292,8 @@
DataSinkWriter(BinaryDataSink(dataOutput), _options, indices);
_reporter.log('Writing data to ${uri}');
sink.writeMembers(lazyMemberBodies);
+ sink.registerAbstractValueDomain(domain);
sink.writeMemberMap(results, (MemberEntity member, CodegenResult result) {
- sink.registerCodegenWriter(
- CodegenWriterImpl(closedWorld, result.deferredExpressionData));
sink.writeDeferrable(() => result.writeToDataSink(sink));
});
sink.close();
@@ -302,13 +302,12 @@
Future<CodegenResults> deserializeCodegen(
JsBackendStrategy backendStrategy,
- GlobalTypeInferenceResults globalTypeInferenceResults,
+ JClosedWorld closedWorld,
CodegenInputs codegenInputs,
bool useDeferredSourceReads,
SourceLookup sourceLookup,
SerializationIndices indices) async {
int shards = _options.codegenShards!;
- JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
Map<MemberEntity, Deferrable<CodegenResult>> results = {};
for (int shard = 0; shard < shards; shard++) {
Uri uri = Uri.parse(
@@ -325,15 +324,7 @@
});
}
return DeserializedCodegenResults(
- globalTypeInferenceResults, codegenInputs, DeferrableValueMap(results));
- }
-
- static CodegenResult _readCodegenResult(
- DataSourceReader source, JClosedWorld closedWorld) {
- CodegenReader reader = CodegenReaderImpl(closedWorld);
- source.registerCodegenReader(reader);
- CodegenResult result = CodegenResult.readFromDataSource(source);
- return result;
+ codegenInputs, DeferrableValueMap(results));
}
void _deserializeCodegenInput(
@@ -355,9 +346,10 @@
source.registerSourceLookup(sourceLookup);
final lazyMemberBodies = source.readMembers();
closedWorld.elementMap.registerLazyMemberBodies(lazyMemberBodies);
+ source.registerAbstractValueDomain(closedWorld.abstractValueDomain);
Map<MemberEntity, Deferrable<CodegenResult>> codegenResults =
source.readMemberMap((MemberEntity member) {
- return source.readDeferrableWithArg(_readCodegenResult, closedWorld,
+ return source.readDeferrable(CodegenResult.readFromDataSource,
cacheData: false);
});
_reporter.log('Read ${codegenResults.length} members from ${uri}');
@@ -367,21 +359,21 @@
void serializeDumpInfoProgramData(
JsBackendStrategy backendStrategy,
DumpInfoProgramData dumpInfoProgramData,
- JClosedWorld closedWorld,
+ AbstractValueDomain abstractValueDomain,
SerializationIndices indices) {
final outputUri = _options.dumpInfoWriteUri!;
api.BinaryOutputSink dataOutput =
_outputProvider.createBinarySink(outputUri);
final sink = DataSinkWriter(BinaryDataSink(dataOutput), _options, indices);
- sink.registerCodegenWriter(
- CodegenWriterImpl(closedWorld, DeferredExpressionData([], [])));
+ sink.registerAbstractValueDomain(abstractValueDomain);
dumpInfoProgramData.writeToDataSink(sink);
sink.close();
}
Future<DumpInfoProgramData> deserializeDumpInfoProgramData(
JsBackendStrategy backendStrategy,
- JClosedWorld closedWorld,
+ AbstractValueDomain abstractValueDomain,
+ OutputUnitData outputUnitData,
SerializationIndices indices) async {
final inputUri = _options.dumpInfoReadUri!;
final dataInput =
@@ -391,8 +383,8 @@
_options,
indices);
backendStrategy.prepareCodegenReader(source);
- source.registerCodegenReader(CodegenReaderImpl(closedWorld));
- return DumpInfoProgramData.readFromDataSource(source, closedWorld,
+ source.registerAbstractValueDomain(abstractValueDomain);
+ return DumpInfoProgramData.readFromDataSource(source, outputUnitData,
includeCodeText: !_options.useDumpInfoBinaryFormat);
}
}
diff --git a/pkg/compiler/test/end_to_end/exit_code_test.dart b/pkg/compiler/test/end_to_end/exit_code_test.dart
index 318c0a3..b0d8b91 100644
--- a/pkg/compiler/test/end_to_end/exit_code_test.dart
+++ b/pkg/compiler/test/end_to_end/exit_code_test.dart
@@ -21,8 +21,8 @@
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/diagnostics/spannable.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/inferrer/abstract_value_domain.dart';
import 'package:compiler/src/js_model/js_strategy.dart';
-import 'package:compiler/src/js_model/js_world.dart' show JClosedWorld;
import 'package:compiler/src/null_compiler_output.dart';
import 'package:compiler/src/serialization/serialization.dart';
import 'package:compiler/src/options.dart' show CompilerOptions;
@@ -107,13 +107,13 @@
@override
WorldImpact generateCode(
WorkItem work,
- JClosedWorld closedWorld,
+ AbstractValueDomain abstractValueDomain,
CodegenResults codegenResults,
ComponentLookup componentLookup,
SourceLookup sourceLookup) {
compiler.test('Compiler.codegen');
- return super.generateCode(
- work, closedWorld, codegenResults, componentLookup, sourceLookup);
+ return super.generateCode(work, abstractValueDomain, codegenResults,
+ componentLookup, sourceLookup);
}
}
diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart
index 2fa3398..062a6fa 100644
--- a/pkg/compiler/test/serialization/serialization_test_helper.dart
+++ b/pkg/compiler/test/serialization/serialization_test_helper.dart
@@ -30,13 +30,17 @@
Future<void> generateJavaScriptCode(Compiler compiler,
GlobalTypeInferenceResults globalTypeInferenceResults) async {
final codegenInputs = compiler.initializeCodegen(globalTypeInferenceResults);
- final codegenResults = OnDemandCodegenResults(globalTypeInferenceResults,
+ final codegenResults = OnDemandCodegenResults(
codegenInputs, compiler.backendStrategy.functionCompiler);
final programSize = compiler.runCodegenEnqueuer(
- codegenResults, SourceLookup(compiler.componentForTesting));
+ codegenResults,
+ globalTypeInferenceResults.inferredData,
+ SourceLookup(compiler.componentForTesting),
+ globalTypeInferenceResults.closedWorld);
if (compiler.options.dumpInfo) {
await compiler.runDumpInfo(
codegenResults,
+ globalTypeInferenceResults,
DumpInfoProgramData.fromEmitterResults(
compiler.backendStrategy, compiler.dumpInfoRegistry, programSize));
}