Skip to content

Commit cf4d274

Browse files
natebiggsCommit Queue
authored andcommitted
[ddc] Add options to emit, read and diff delta dills for hot reload.
This will allow DartPad (which invokes DDC directly) to maintain delta dills across each reload. Change-Id: I801208c6b8f50a0aa20b6f509aa3e32a827a9cdb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405661 Reviewed-by: Nicholas Shahan <[email protected]> Commit-Queue: Nate Biggs <[email protected]>
1 parent 6d54fd3 commit cf4d274

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

pkg/dev_compiler/lib/src/command/command.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import 'package:build_integration/file_system/multi_root.dart';
1111
import 'package:front_end/src/api_prototype/macros.dart' as macros
1212
show isMacroLibraryUri;
1313
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
14+
import 'package:kernel/binary/ast_from_binary.dart' as kernel
15+
show BinaryBuilder;
1416
import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
1517
import 'package:kernel/class_hierarchy.dart';
1618
import 'package:kernel/core_types.dart';
@@ -28,6 +30,7 @@ import '../js_ast/js_ast.dart' show js;
2830
import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
2931
import '../kernel/compiler.dart';
3032
import '../kernel/compiler_new.dart';
33+
import '../kernel/hot_reload_delta_inspector.dart';
3134
import '../kernel/module_metadata.dart';
3235
import '../kernel/module_symbols.dart';
3336
import '../kernel/module_symbols_collector.dart';
@@ -363,6 +366,33 @@ Future<CompilerResult> _compile(List<String> args,
363366
var component = result.component;
364367
var compiledLibraries = result.compiledLibraries;
365368

369+
final reloadDeltaKernel = options.reloadDeltaKernel;
370+
final reloadLastAcceptedKernel = options.reloadLastAcceptedKernel;
371+
if (reloadDeltaKernel != null) {
372+
if (reloadLastAcceptedKernel != null) {
373+
final lastAcceptedComponent = Component();
374+
kernel.BinaryBuilder((await File(reloadLastAcceptedKernel).readAsBytes()))
375+
.readComponent(lastAcceptedComponent);
376+
final deltaInspector = HotReloadDeltaInspector();
377+
final rejectionReasons = deltaInspector.compareGenerations(
378+
lastAcceptedComponent, compiledLibraries);
379+
if (rejectionReasons.isNotEmpty) {
380+
throw StateError(
381+
'Hot reload rejected due to:\n${rejectionReasons.join('\n')}');
382+
}
383+
}
384+
var sink = File(reloadDeltaKernel).openWrite();
385+
kernel.BinaryPrinter(sink, includeSources: false, includeSourceBytes: false)
386+
.writeComponentFile(compiledLibraries);
387+
await sink.flush();
388+
await sink.close();
389+
} else {
390+
if (reloadLastAcceptedKernel != null) {
391+
throw ArgumentError("Must provide 'new-reload-delta-kernel' if "
392+
"'old-reload-delta-kernel' provided.");
393+
}
394+
}
395+
366396
// Output files can be written in parallel, so collect the futures.
367397
var outFiles = <Future>[];
368398
if (argResults['summarize'] as bool) {

pkg/dev_compiler/lib/src/command/options.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ class Options {
3030
/// expressions on demand in the current scope of a breakpoint.
3131
final bool emitFullCompiledKernel;
3232

33+
final String? reloadLastAcceptedKernel;
34+
final String? reloadDeltaKernel;
35+
3336
/// Whether to emit a summary file containing API signatures.
3437
///
3538
/// This is required for a modular build process.
@@ -117,6 +120,8 @@ class Options {
117120
this.emitDebugMetadata = false,
118121
this.emitDebugSymbols = false,
119122
this.emitFullCompiledKernel = false,
123+
this.reloadLastAcceptedKernel,
124+
this.reloadDeltaKernel,
120125
this.summaryModules = const {},
121126
this.moduleFormats = const [],
122127
required this.moduleName,
@@ -143,6 +148,9 @@ class Options {
143148
emitDebugSymbols: args['emit-debug-symbols'] as bool,
144149
emitFullCompiledKernel:
145150
args['experimental-output-compiled-kernel'] as bool,
151+
reloadLastAcceptedKernel:
152+
args['reload-last-accepted-kernel'] as String?,
153+
reloadDeltaKernel: args['reload-delta-kernel'] as String?,
146154
summaryModules:
147155
_parseCustomSummaryModules(args['summary'] as List<String>),
148156
moduleFormats: parseModuleFormatOption(args),
@@ -213,6 +221,17 @@ class Options {
213221
'the .js output.',
214222
defaultsTo: false,
215223
hide: true)
224+
..addOption('reload-last-accepted-kernel',
225+
help: 'Provides a file path to read a dill file. The enclosed kernel '
226+
'will be diffed against the kernel produced by this compilation '
227+
'as an incremental hot reload step.',
228+
hide: true)
229+
..addOption('reload-delta-kernel',
230+
help: 'Provides a file path to write a dill file to. The resulting '
231+
'kernel can be passed to future compilations via '
232+
'`reload-last-accepted-kernel` to get incremental hot reload '
233+
'checks.',
234+
hide: true)
216235
..addMultiOption('precompiled-macro',
217236
help:
218237
'Configuration for precompiled macro binaries or kernel files.\n'

pkg/dev_compiler/lib/src/kernel/hot_reload_delta_inspector.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class HotReloadDeltaInspector {
2323
// TODO(nshahan): Annotate delta component with information for DDC.
2424
List<String> compareGenerations(Component lastAccepted, Component delta) {
2525
_partialLastAcceptedLibraryIndex = LibraryIndex(lastAccepted,
26-
[for (var library in delta.libraries) '${library.fileUri}']);
26+
[for (var library in delta.libraries) '${library.importUri}']);
2727
_rejectionMessages.clear();
2828

2929
for (var library in delta.libraries) {

0 commit comments

Comments
 (0)