Skip to content

Commit f132854

Browse files
Anna Gringauzecommit-bot@chromium.org
Anna Gringauze
authored andcommitted
Fix expression evaluation failure after hot restart
The lifetime of program compilers in JavaScriptBundler is too short, moving the program compiler cache to FrontendCompiler instead so the ProgramCompilers created during main compilation could be reused for expression evaluation until the next compilation. Closes: #45266 Change-Id: I7d41476c7064f16cab2783f88c49114a08a0c038 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190301 Commit-Queue: Anna Gringauze <[email protected]> Reviewed-by: Jonah Williams <[email protected]> Reviewed-by: Nicholas Shahan <[email protected]> Reviewed-by: Mark Zhou <[email protected]>
1 parent 494aaaa commit f132854

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

pkg/frontend_server/lib/frontend_server.dart

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ import 'dart:io' hide FileSystemEntity;
1010

1111
import 'package:args/args.dart';
1212
import 'package:dev_compiler/dev_compiler.dart'
13-
show DevCompilerTarget, ExpressionCompiler, parseModuleFormat;
13+
show
14+
DevCompilerTarget,
15+
ExpressionCompiler,
16+
parseModuleFormat,
17+
ProgramCompiler;
1418

1519
// front_end/src imports below that require lint `ignore_for_file`
1620
// are a temporary state of things until frontend team builds better api
@@ -631,14 +635,15 @@ class FrontendCompiler implements CompilerInterface {
631635
final sourceMapsFileSink = sourceMapsFile.openWrite();
632636
final metadataFileSink =
633637
emitDebugMetadata ? metadataFile.openWrite() : null;
634-
await _bundler.compile(
638+
final kernel2JsCompilers = await _bundler.compile(
635639
results.classHierarchy,
636640
results.coreTypes,
637641
results.loadedLibraries,
638642
sourceFileSink,
639643
manifestFileSink,
640644
sourceMapsFileSink,
641645
metadataFileSink);
646+
cachedProgramCompilers.addAll(kernel2JsCompilers);
642647
await Future.wait([
643648
sourceFileSink.close(),
644649
manifestFileSink.close(),
@@ -806,6 +811,12 @@ class FrontendCompiler implements CompilerInterface {
806811
}
807812
}
808813

814+
/// Program compilers per module.
815+
///
816+
/// Produced suring initial compilation of the module to JavaScript,
817+
/// cached to be used for expression compilation in [compileExpressionToJs].
818+
final Map<String, ProgramCompiler> cachedProgramCompilers = {};
819+
809820
@override
810821
Future<Null> compileExpressionToJs(
811822
String libraryUri,
@@ -822,7 +833,7 @@ class FrontendCompiler implements CompilerInterface {
822833
reportError('JavaScript bundler is null');
823834
return;
824835
}
825-
if (!_bundler.compilers.containsKey(moduleName)) {
836+
if (!cachedProgramCompilers.containsKey(moduleName)) {
826837
reportError('Cannot find kernel2js compiler for $moduleName.');
827838
return;
828839
}
@@ -833,13 +844,13 @@ class FrontendCompiler implements CompilerInterface {
833844
_processedOptions.ticker
834845
.logMs('Compiling expression to JavaScript in $moduleName');
835846

836-
var kernel2jsCompiler = _bundler.compilers[moduleName];
847+
final kernel2jsCompiler = cachedProgramCompilers[moduleName];
837848
Component component = _generator.lastKnownGoodComponent;
838849
component.computeCanonicalNames();
839850

840851
_processedOptions.ticker.logMs('Computed component');
841852

842-
var expressionCompiler = new ExpressionCompiler(
853+
final expressionCompiler = new ExpressionCompiler(
843854
_compilerOptions,
844855
parseModuleFormat(_options['dartdevc-module-format'] as String),
845856
errors,
@@ -848,10 +859,10 @@ class FrontendCompiler implements CompilerInterface {
848859
component,
849860
);
850861

851-
var procedure = await expressionCompiler.compileExpressionToJs(
862+
final procedure = await expressionCompiler.compileExpressionToJs(
852863
libraryUri, line, column, jsFrameValues, expression);
853864

854-
var result = errors.length > 0 ? errors[0] : procedure;
865+
final result = errors.length > 0 ? errors[0] : procedure;
855866

856867
// TODO(annagrin): kernelBinaryFilename is too specific
857868
// rename to _outputFileName?

pkg/frontend_server/lib/src/javascript_bundle.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ class JavaScriptBundler {
2929
this.emitDebugMetadata = false,
3030
this.soundNullSafety = false,
3131
String moduleFormat})
32-
: compilers = <String, ProgramCompiler>{},
33-
_moduleFormat = parseModuleFormat(moduleFormat ?? 'amd') {
32+
: _moduleFormat = parseModuleFormat(moduleFormat ?? 'amd') {
3433
_summaries = <Component>[];
3534
_summaryUris = <Uri>[];
3635
_moduleImportForSummary = <Uri, String>{};
@@ -64,7 +63,6 @@ class JavaScriptBundler {
6463
final PackageConfig _packageConfig;
6564
final bool useDebuggerModuleNames;
6665
final bool emitDebugMetadata;
67-
final Map<String, ProgramCompiler> compilers;
6866
final ModuleFormat _moduleFormat;
6967
final bool soundNullSafety;
7068

@@ -75,7 +73,7 @@ class JavaScriptBundler {
7573
Map<Uri, Component> _uriToComponent;
7674

7775
/// Compile each component into a single JavaScript module.
78-
Future<void> compile(
76+
Future<Map<String, ProgramCompiler>> compile(
7977
ClassHierarchy classHierarchy,
8078
CoreTypes coreTypes,
8179
Set<Library> loadedLibraries,
@@ -88,6 +86,7 @@ class JavaScriptBundler {
8886
var metadataOffset = 0;
8987
final manifest = <String, Map<String, List<int>>>{};
9088
final Set<Uri> visited = <Uri>{};
89+
final Map<String, ProgramCompiler> kernel2JsCompilers = {};
9190

9291
final importToSummary = Map<Library, Component>.identity();
9392
final summaryToModule = Map<Component, String>.identity();
@@ -150,9 +149,8 @@ class JavaScriptBundler {
150149
// so it can map dart symbols to js symbols
151150
// [issue 40273](https://github.com/dart-lang/sdk/issues/40273)
152151

153-
// program compiler is used by ExpressionCompiler to evaluate expressions
154-
// on demand
155-
compilers[moduleName] = compiler;
152+
// Save program compiler to reuse for expression evaluation.
153+
kernel2JsCompilers[moduleName] = compiler;
156154

157155
final moduleUrl = urlForComponentUri(moduleUri);
158156
String sourceMapBase;
@@ -201,6 +199,8 @@ class JavaScriptBundler {
201199
};
202200
}
203201
manifestSink.add(utf8.encode(json.encode(manifest)));
202+
203+
return kernel2JsCompilers;
204204
}
205205
}
206206

pkg/frontend_server/test/src/javascript_bundle_test.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,14 @@ void main() {
106106
final metadataSink = _MemorySink();
107107
final coreTypes = CoreTypes(testComponent);
108108

109-
await javaScriptBundler.compile(ClassHierarchy(testComponent, coreTypes),
110-
coreTypes, {}, codeSink, manifestSink, sourcemapSink, metadataSink);
109+
final compilers = await javaScriptBundler.compile(
110+
ClassHierarchy(testComponent, coreTypes),
111+
coreTypes,
112+
{},
113+
codeSink,
114+
manifestSink,
115+
sourcemapSink,
116+
metadataSink);
111117

112118
final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
113119
final String code = utf8.decode(codeSink.buffer);
@@ -122,6 +128,9 @@ void main() {
122128

123129
// verify source map url is correct.
124130
expect(code, contains('sourceMappingURL=c.dart.lib.js.map'));
131+
132+
// verify program compilers are created.
133+
expect(compilers.keys, equals([urlForComponentUri(library.importUri)]));
125134
});
126135

127136
test('converts package: uris into /packages/ uris', () async {

0 commit comments

Comments
 (0)