Skip to content

Commit c6f47d9

Browse files
natebiggsCommit Queue
authored andcommitted
[dart2wasm] Save load IDs on serialized component.
Allows load ID assignments to be preserved when dart2wasm is being used with phases. Change-Id: I610fb56c46e0b52c1b73293f1d3fb8932f0d9434 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/456220 Commit-Queue: Nate Biggs <[email protected]> Reviewed-by: Martin Kustermann <[email protected]>
1 parent 6c6cba8 commit c6f47d9

File tree

2 files changed

+80
-41
lines changed

2 files changed

+80
-41
lines changed

pkg/dart2wasm/lib/deferred_loading.dart

Lines changed: 77 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
8686
final WasmCompilerOptions options;
8787
final WasmTarget kernelTarget;
8888
final CoreTypes coreTypes;
89-
final Map<String, Map<String, String>> loadIdMap = {};
9089
late final ModuleOutputData moduleOutputData;
9190

9291
DeferredLoadingModuleStrategy(
@@ -95,7 +94,7 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
9594
@override
9695
void prepareComponent() {
9796
if (options.loadsIdsUri != null) {
98-
component.accept(_DeferredLoadingLoadIdTransformer(coreTypes, loadIdMap));
97+
component.accept(_DeferredLoadingLoadIdTransformer(component, coreTypes));
9998
}
10099
}
101100

@@ -142,8 +141,7 @@ class DeferredLoadingModuleStrategy extends ModuleStrategy {
142141
moduleMap[enclosingLibrary] = outputMapping;
143142
});
144143

145-
await _initDeferredImports(
146-
component, coreTypes, options, loadIdMap, moduleMap);
144+
await _initDeferredImports(component, coreTypes, options, moduleMap);
147145

148146
moduleOutputData =
149147
ModuleOutputData([mainModule, ...rootSetToModule.values]);
@@ -229,7 +227,6 @@ class StressTestModuleStrategy extends ModuleStrategy {
229227
final WasmTarget kernelTarget;
230228
final ClassHierarchy classHierarchy;
231229
final WasmCompilerOptions options;
232-
final Map<String, Map<String, String>> loadIdMap = {};
233230
late final ModuleOutputData moduleOutputData;
234231

235232
/// We load all 'dart:*' libraries since just doing the deferred load of modules
@@ -287,7 +284,7 @@ class StressTestModuleStrategy extends ModuleStrategy {
287284
[invokeMain.enclosingLibrary], classHierarchy, coreTypes);
288285

289286
if (options.loadsIdsUri != null) {
290-
component.accept(_DeferredLoadingLoadIdTransformer(coreTypes, loadIdMap));
287+
component.accept(_DeferredLoadingLoadIdTransformer(component, coreTypes));
291288
}
292289
}
293290

@@ -310,7 +307,7 @@ class StressTestModuleStrategy extends ModuleStrategy {
310307
importMap[importName] = [module];
311308
}
312309

313-
await _initDeferredImports(component, coreTypes, options, loadIdMap,
310+
await _initDeferredImports(component, coreTypes, options,
314311
{coreTypes.index.getLibrary('dart:_internal'): importMap});
315312

316313
moduleOutputData = ModuleOutputData([mainModule, ...modules]);
@@ -324,13 +321,11 @@ Future<void> _initDeferredImports(
324321
Component component,
325322
CoreTypes coreTypes,
326323
WasmCompilerOptions options,
327-
Map<String, Map<String, String>> loadIdMap,
328324
Map<Library, Map<String, List<ModuleMetadata>>> moduleMap) async {
329325
if (options.loadsIdsUri == null) {
330326
_initDeferredImportsPrefix(component, coreTypes, options, moduleMap);
331327
} else {
332-
await _initDeferredImportsLoadIds(
333-
component, coreTypes, options, loadIdMap, moduleMap);
328+
await _initDeferredImportsLoadIds(component, coreTypes, options, moduleMap);
334329
}
335330
}
336331

@@ -377,34 +372,38 @@ Future<void> _initDeferredImportsLoadIds(
377372
Component component,
378373
CoreTypes coreTypes,
379374
WasmCompilerOptions options,
380-
Map<String, Map<String, String>> loadIdMap,
381375
Map<Library, Map<String, List<ModuleMetadata>>> moduleMap) async {
382-
await (File.fromUri(options.loadsIdsUri!)..createSync()).writeAsString(
383-
_generateDeferredMapJson(component.mainMethod!.enclosingLibrary.importUri,
384-
moduleMap, loadIdMap));
376+
final file = File.fromUri(options.loadsIdsUri!);
377+
await file.create(recursive: true);
378+
await file.writeAsString(
379+
_generateDeferredMapJson(
380+
component, component.mainMethod!.enclosingLibrary.importUri, moduleMap),
381+
);
385382
}
386383

387-
String _generateDeferredMapJson(
388-
Uri rootLibraryUri,
389-
Map<Library, Map<String, List<ModuleMetadata>>> moduleMap,
390-
Map<String, Map<String, String>> loadIds) {
384+
String _generateDeferredMapJson(Component component, Uri rootLibraryUri,
385+
Map<Library, Map<String, List<ModuleMetadata>>> moduleMap) {
386+
final loadIdRepo =
387+
component.metadata[LoadIdRepository._tag] as LoadIdRepository;
391388
final output = <String, dynamic>{};
392-
moduleMap.forEach((library, imports) {
389+
loadIdRepo.mapping.forEach((dep, loadId) {
390+
final loadIdStr = '$loadId';
391+
final prefix = dep.name!;
392+
final library = dep.enclosingLibrary;
393+
final modules = moduleMap[library]?[prefix];
394+
395+
// Can be null if the library or import was tree-shaken by TFA.
396+
if (modules == null) return;
397+
393398
final libOutput =
394-
output[relativizeUri(rootLibraryUri, library.importUri, false)] = {};
395-
libOutput['name'] = library.name ?? '<unnamed>';
396-
final libImports = libOutput['imports'] = <String, List<String>>{};
397-
final libPrefixMappings =
398-
libOutput['importPrefixToLoadId'] = <String, String>{};
399-
final prefixLoadIds = loadIds['${library.importUri}']!;
400-
imports.forEach((prefix, modules) {
401-
final loadId = prefixLoadIds[prefix]!;
402-
final prefixImports = libImports[loadId] = <String>[];
403-
libPrefixMappings[prefix] = loadId;
404-
for (final module in modules) {
405-
prefixImports.add(module.moduleName);
406-
}
407-
});
399+
output[relativizeUri(rootLibraryUri, library.importUri, false)] ??= {
400+
'name': library.name ?? '<unnamed>',
401+
'imports': <String, List<String>>{},
402+
'importPrefixToLoadId': <String, String>{},
403+
};
404+
405+
libOutput['imports']![loadIdStr] = [...modules.map((m) => m.moduleName)];
406+
libOutput['importPrefixToLoadId'][prefix] = loadIdStr;
408407
});
409408

410409
return const JsonEncoder.withIndent(' ').convert(output);
@@ -415,32 +414,69 @@ class _DeferredLoadingLoadIdTransformer extends Transformer {
415414
final Procedure? _checkLibraryIsLoaded;
416415
final Procedure _loadLibraryFromLoadId;
417416
final Procedure _checkLibraryIsLoadedFromLoadId;
418-
final Map<String, Map<String, String>> loadIdCollector;
419-
int loadIdCounter = 1;
417+
final LoadIdRepository _loadIdRepository = LoadIdRepository();
418+
Map<String, int> _libraryLoadIds = {};
419+
int _loadIdCounter = 1;
420420

421-
_DeferredLoadingLoadIdTransformer(CoreTypes coreTypes, this.loadIdCollector)
421+
_DeferredLoadingLoadIdTransformer(Component component, CoreTypes coreTypes)
422422
: _loadLibrary = coreTypes.index.tryGetProcedure(
423423
'dart:_internal', LibraryIndex.topLevel, 'loadLibrary'),
424424
_checkLibraryIsLoaded = coreTypes.index.tryGetProcedure(
425425
'dart:_internal', LibraryIndex.topLevel, 'checkLibraryIsLoaded'),
426426
_loadLibraryFromLoadId = coreTypes.index
427427
.getTopLevelProcedure('dart:_internal', 'loadLibraryFromLoadId'),
428428
_checkLibraryIsLoadedFromLoadId = coreTypes.index.getTopLevelProcedure(
429-
'dart:_internal', 'checkLibraryIsLoadedFromLoadId');
429+
'dart:_internal', 'checkLibraryIsLoadedFromLoadId') {
430+
component.addMetadataRepository(_loadIdRepository);
431+
}
432+
433+
@override
434+
TreeNode visitLibrary(Library node) {
435+
// Assign a load ID to each deferred import.
436+
_libraryLoadIds = {};
437+
for (final dep in node.dependencies) {
438+
if (!dep.isDeferred) continue;
439+
final loadId = _loadIdCounter++;
440+
_loadIdRepository.mapping[dep] = loadId;
441+
_libraryLoadIds[dep.name!] = loadId;
442+
}
443+
444+
// Don't visit this library if there are no deferred imports.
445+
return _libraryLoadIds.isEmpty ? node : super.visitLibrary(node);
446+
}
430447

431448
@override
432449
TreeNode visitStaticInvocation(StaticInvocation node) {
433450
if (node.target != _loadLibrary && node.target != _checkLibraryIsLoaded) {
434451
return super.visitStaticInvocation(node);
435452
}
436-
final [libraryName as StringLiteral, importPrefix as StringLiteral] =
437-
node.arguments.positional;
438-
final loadId = (loadIdCollector[libraryName.value] ??=
439-
{})[importPrefix.value] ??= '${loadIdCounter++}';
453+
final [_, importPrefix as StringLiteral] = node.arguments.positional;
454+
final loadId = '${_libraryLoadIds[importPrefix.value]!}';
440455
return StaticInvocation(
441456
node.target == _loadLibrary
442457
? _loadLibraryFromLoadId
443458
: _checkLibraryIsLoadedFromLoadId,
444459
Arguments([StringLiteral(loadId)]));
445460
}
446461
}
462+
463+
/// Contains load IDs for each deferred [LibraryDependency] in the component.
464+
class LoadIdRepository extends MetadataRepository<int> {
465+
static const String _tag = 'dart2wasm.loadIds';
466+
467+
@override
468+
final Map<LibraryDependency, int> mapping = {};
469+
470+
@override
471+
int readFromBinary(Node node, BinarySource source) {
472+
return source.readUInt30();
473+
}
474+
475+
@override
476+
String get tag => _tag;
477+
478+
@override
479+
void writeToBinary(int metadata, Node node, BinarySink sink) {
480+
sink.writeUInt30(metadata);
481+
}
482+
}

pkg/dart2wasm/lib/util.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import 'package:vm/metadata/procedure_attributes.dart'
1717
import 'package:vm/metadata/table_selector.dart'
1818
show TableSelectorMetadataRepository;
1919

20+
import 'deferred_loading.dart' show LoadIdRepository;
21+
2022
bool hasPragma(CoreTypes coreTypes, Annotatable node, String name) {
2123
return getPragma(coreTypes, node, name, defaultValue: '') != null;
2224
}
@@ -80,6 +82,7 @@ String intToBase64(int i) => base64.encode(_intToLittleEndianBytes(i));
8082

8183
Component createEmptyComponent() {
8284
return Component()
85+
..addMetadataRepository(LoadIdRepository())
8386
..addMetadataRepository(ProcedureAttributesMetadataRepository())
8487
..addMetadataRepository(TableSelectorMetadataRepository())
8588
..addMetadataRepository(DirectCallMetadataRepository())

0 commit comments

Comments
 (0)