Skip to content

Commit 0952026

Browse files
MarkzipanCommit Queue
authored andcommitted
[frontend_server] Add a flag that disables strongly connected component library bundling for JS.
DDC's new module system no longer requires that libraries in a referential cycle be in the same compilation module. Disabling SCCs allows allows us to compile modules more finely and with more stability, which simplifies hot reload operations. Change-Id: I9ca9fc343b31d9df40aa88b562fe1f5916bad6a4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446743 Commit-Queue: Mark Zhou <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent e8aeb4a commit 0952026

File tree

2 files changed

+73
-38
lines changed

2 files changed

+73
-38
lines changed

pkg/frontend_server/lib/frontend_server.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ ArgParser argParser = new ArgParser(allowTrailingOptions: true)
228228
..addFlag('print-incremental-dependencies',
229229
help: 'Print list of sources added and removed from compilation',
230230
defaultsTo: true)
231+
..addFlag('js-strongly-connected-components',
232+
help: 'Whether or not to combine JavaScript libraries into '
233+
'strongly connected components',
234+
defaultsTo: true,
235+
hide: true)
231236
..addOption('resident-info-file-name',
232237
help: 'Allowing for incremental compilation of changes when using the '
233238
'Dart CLI. '
@@ -711,6 +716,8 @@ class FrontendCompiler implements CompilerInterface {
711716
options['filesystem-scheme'], options['dartdevc-module-format'],
712717
fullComponent: true,
713718
recompileRestart: false,
719+
useStronglyConnectedComponents:
720+
options['js-strongly-connected-components'],
714721
extraDdcOptions: extraDdcOptions);
715722
}
716723
await writeDillFile(
@@ -855,6 +862,7 @@ class FrontendCompiler implements CompilerInterface {
855862
String filename, String fileSystemScheme, String moduleFormat,
856863
{required bool fullComponent,
857864
required bool recompileRestart,
865+
required bool useStronglyConnectedComponents,
858866
List<String>? extraDdcOptions}) async {
859867
PackageConfig packageConfig = await loadPackageConfigUri(
860868
_compilerOptions.packagesFileUri ??
@@ -868,6 +876,7 @@ class FrontendCompiler implements CompilerInterface {
868876
fileSystemScheme,
869877
useDebuggerModuleNames: useDebuggerModuleNames,
870878
emitDebugMetadata: emitDebugMetadata,
879+
useStronglyConnectedComponents: useStronglyConnectedComponents,
871880
moduleFormat: moduleFormat,
872881
canaryFeatures: canaryFeatures,
873882
extraDdcOptions: extraDdcOptions ?? [],
@@ -1073,6 +1082,8 @@ class FrontendCompiler implements CompilerInterface {
10731082
_options['filesystem-scheme'], _options['dartdevc-module-format'],
10741083
fullComponent: false,
10751084
recompileRestart: recompileRestart,
1085+
useStronglyConnectedComponents:
1086+
_options['js-strongly-connected-components'],
10761087
extraDdcOptions: extraDdcOptions);
10771088
} catch (e) {
10781089
_outputStream.writeln('$e');

pkg/frontend_server/lib/src/javascript_bundle.dart

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class IncrementalJavaScriptBundler {
4141
this.useDebuggerModuleNames = false,
4242
this.emitDebugMetadata = false,
4343
this.emitDebugSymbols = false,
44+
this.useStronglyConnectedComponents = true,
4445
this.canaryFeatures = false,
4546
String? moduleFormat,
4647
this.extraDdcOptions = const [],
@@ -49,6 +50,7 @@ class IncrementalJavaScriptBundler {
4950
final bool useDebuggerModuleNames;
5051
final bool emitDebugMetadata;
5152
final bool emitDebugSymbols;
53+
final bool useStronglyConnectedComponents;
5254
final ModuleFormat _moduleFormat;
5355
final List<String> extraDdcOptions;
5456
final bool canaryFeatures;
@@ -71,18 +73,25 @@ class IncrementalJavaScriptBundler {
7173
Component fullComponent, Uri mainUri, PackageConfig packageConfig) async {
7274
_lastFullComponent = fullComponent;
7375
_currentComponent = fullComponent;
74-
_strongComponents = new StrongComponents(
75-
fullComponent,
76-
_loadedLibraries,
77-
mainUri,
78-
_fileSystem,
79-
);
8076
// Initialize fresh hot reload metadata for this compile and throw out all
8177
// information collected from any previous series of hot reloads compiles.
8278
_libraryMetadataRepository = new HotReloadLibraryMetadataRepository();
83-
await _strongComponents.computeLibraryBundles();
84-
_updateSummaries(
85-
_strongComponents.libraryBundleImportToLibraries.keys, packageConfig);
79+
Iterable<Uri> initialLibraryUris;
80+
if (useStronglyConnectedComponents) {
81+
_strongComponents = new StrongComponents(
82+
fullComponent,
83+
_loadedLibraries,
84+
mainUri,
85+
_fileSystem,
86+
);
87+
await _strongComponents.computeLibraryBundles();
88+
initialLibraryUris =
89+
_strongComponents.libraryBundleImportToLibraries.keys;
90+
} else {
91+
initialLibraryUris =
92+
fullComponent.libraries.map((library) => library.importUri);
93+
}
94+
_updateSummaries(initialLibraryUris, packageConfig);
8695
}
8796

8897
/// Update the incremental bundler from a partial component and the last full
@@ -108,23 +117,29 @@ class IncrementalJavaScriptBundler {
108117
}
109118
_currentComponent = partialComponent;
110119
_updateFullComponent(lastFullComponent, partialComponent);
111-
_strongComponents = new StrongComponents(
112-
_lastFullComponent,
113-
_loadedLibraries,
114-
mainUri,
115-
_fileSystem,
116-
);
120+
Iterable<Uri> invalidatedLibraryUris;
117121

118-
await _strongComponents.computeLibraryBundles(<Uri, Library>{
119-
for (Library library in partialComponent.libraries)
120-
library.importUri: library,
121-
});
122-
Set<Uri> invalidated = <Uri>{
123-
for (Library library in partialComponent.libraries)
124-
_strongComponents
125-
.libraryImportToLibraryBundleImport[library.importUri]!,
126-
};
127-
_updateSummaries(invalidated, packageConfig);
122+
if (useStronglyConnectedComponents) {
123+
_strongComponents = new StrongComponents(
124+
_lastFullComponent,
125+
_loadedLibraries,
126+
mainUri,
127+
_fileSystem,
128+
);
129+
await _strongComponents.computeLibraryBundles(<Uri, Library>{
130+
for (Library library in partialComponent.libraries)
131+
library.importUri: library,
132+
});
133+
invalidatedLibraryUris = <Uri>{
134+
for (Library library in partialComponent.libraries)
135+
_strongComponents
136+
.libraryImportToLibraryBundleImport[library.importUri]!,
137+
};
138+
} else {
139+
invalidatedLibraryUris =
140+
partialComponent.libraries.map((library) => library.importUri);
141+
}
142+
_updateSummaries(invalidatedLibraryUris, packageConfig);
128143
}
129144

130145
void _updateFullComponent(Component lastKnownGood, Component candidate) {
@@ -151,9 +166,14 @@ class IncrementalJavaScriptBundler {
151166
/// Update the summaries using the [libraryBundleImports].
152167
void _updateSummaries(
153168
Iterable<Uri> libraryBundleImports, PackageConfig packageConfig) {
169+
final Map<Uri, Library> libraryUriToLibrary = {
170+
for (Library library in _lastFullComponent.libraries)
171+
library.importUri: library,
172+
};
154173
for (Uri uri in libraryBundleImports) {
155-
final List<Library> libraries =
156-
_strongComponents.libraryBundleImportToLibraries[uri]!.toList();
174+
final List<Library> libraries = useStronglyConnectedComponents
175+
? _strongComponents.libraryBundleImportToLibraries[uri]!.toList()
176+
: [libraryUriToLibrary[uri]!];
157177
final Component summaryComponent = new Component(
158178
libraries: libraries,
159179
nameRoot: _lastFullComponent.root,
@@ -226,18 +246,22 @@ class IncrementalJavaScriptBundler {
226246
library.importUri.isScheme('dart')) {
227247
continue;
228248
}
229-
final Uri libraryBundleImport = _strongComponents
230-
.libraryImportToLibraryBundleImport[library.importUri]!;
231-
if (visited.containsKey(libraryBundleImport)) {
249+
250+
final Uri libraryOrLibraryBundleImportUri = useStronglyConnectedComponents
251+
? _strongComponents
252+
.libraryImportToLibraryBundleImport[library.importUri]!
253+
: library.importUri;
254+
if (visited.containsKey(libraryOrLibraryBundleImportUri)) {
232255
kernel2JsCompilers[library.importUri.toString()] =
233-
visited[libraryBundleImport]!;
256+
visited[libraryOrLibraryBundleImportUri]!;
234257
continue;
235258
}
236259

237-
final Component summaryComponent = _uriToComponent[libraryBundleImport]!;
260+
final Component summaryComponent =
261+
_uriToComponent[libraryOrLibraryBundleImportUri]!;
238262

239263
final String componentUrl =
240-
urlForComponentUri(libraryBundleImport, packageConfig);
264+
urlForComponentUri(libraryOrLibraryBundleImportUri, packageConfig);
241265
// Library bundle name to use in trackLibraries. Use the full path for
242266
// tracking if library bundle uri is not a package uri.
243267
final String libraryBundleName = makeLibraryBundleName(componentUrl);
@@ -301,15 +325,15 @@ class IncrementalJavaScriptBundler {
301325

302326
// Save program compiler to reuse for expression evaluation.
303327
kernel2JsCompilers[library.importUri.toString()] = compiler;
304-
visited[libraryBundleImport] = compiler;
328+
visited[libraryOrLibraryBundleImportUri] = compiler;
305329

306330
String? sourceMapBase;
307-
if (libraryBundleImport.isScheme('package')) {
331+
if (libraryOrLibraryBundleImportUri.isScheme('package')) {
308332
// Source locations come through as absolute file uris. In order to
309333
// make relative paths in the source map we get the absolute uri for
310334
// the library bundle and make them relative to that.
311-
sourceMapBase =
312-
p.dirname((packageConfig.resolve(libraryBundleImport))!.path);
335+
sourceMapBase = p.dirname(
336+
(packageConfig.resolve(libraryOrLibraryBundleImportUri))!.path);
313337
}
314338

315339
final JSCode code = jsProgramToCode(
@@ -344,7 +368,7 @@ class IncrementalJavaScriptBundler {
344368
symbolsSink!.add(symbolsBytes!);
345369
}
346370
final String libraryBundleJSPath =
347-
_summaryToLibraryBundleJSPath[libraryBundleImport]!;
371+
_summaryToLibraryBundleJSPath[libraryOrLibraryBundleImportUri]!;
348372
manifest[libraryBundleJSPath] = {
349373
'code': <int>[codeOffset, codeOffset += codeBytes.length],
350374
'sourcemap': <int>[

0 commit comments

Comments
 (0)