Skip to content

Commit 317c55f

Browse files
committed
Reland "Use batch mode compilation for -cdartkp --strong"
Preliminary testing shows, this increases performance by around 20%. The main benefit is by re-using a warmed-up VM and not start one from scratch for every compilation. Going forward we can do more optimizations, e.g. reading the platform dill file only once into memory (instead of repeatedly) ... => This requires us using the new state-full IKG compiler. Issue #31585 Change-Id: I2d3448783fc118611baf4671187a897227a65a6c Reviewed-on: https://dart-review.googlesource.com/28400 Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent 6538cb9 commit 317c55f

File tree

8 files changed

+100
-34
lines changed

8 files changed

+100
-34
lines changed

pkg/vm/bin/gen_kernel.dart

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'dart:async';
56
import 'dart:io';
67

78
import 'package:args/args.dart' show ArgParser, ArgResults;
89
import 'package:front_end/src/api_prototype/front_end.dart';
910
import 'package:kernel/binary/ast_to_binary.dart';
1011
import 'package:kernel/kernel.dart' show Program;
12+
import 'package:kernel/src/tool/batch_util.dart' as batch_util;
1113
import 'package:kernel/target/targets.dart' show TargetFlags;
1214
import 'package:kernel/target/vm.dart' show VmTarget;
1315
import 'package:vm/kernel_front_end.dart' show compileToKernel;
@@ -43,12 +45,20 @@ const _severityCaptions = const <Severity, String>{
4345
};
4446

4547
main(List<String> arguments) async {
48+
if (arguments.isNotEmpty && arguments.last == '--batch') {
49+
await runBatchModeCompiler();
50+
} else {
51+
exit(await compile(arguments));
52+
}
53+
}
54+
55+
Future<int> compile(List<String> arguments) async {
4656
final ArgResults options = _argParser.parse(arguments);
4757
final String platformKernel = options['platform'];
4858

4959
if ((options.rest.length != 1) || (platformKernel == null)) {
5060
print(_usage);
51-
exit(_badUsageExitCode);
61+
return _badUsageExitCode;
5262
}
5363

5464
final String filename = options.rest.single;
@@ -82,11 +92,41 @@ main(List<String> arguments) async {
8292
aot: aot);
8393

8494
if ((errors > 0) || (program == null)) {
85-
exit(_compileTimeErrorExitCode);
95+
return _compileTimeErrorExitCode;
8696
}
8797

8898
final IOSink sink = new File(kernelBinaryFilename).openWrite();
8999
final BinaryPrinter printer = new BinaryPrinter(sink);
90100
printer.writeProgramFile(program);
91101
await sink.close();
102+
103+
return 0;
104+
}
105+
106+
Future runBatchModeCompiler() async {
107+
await batch_util.runBatch((List<String> arguments) async {
108+
// TODO(kustermann): Once we know where the new IKG api is and how to use
109+
// it, we should take advantage of it.
110+
//
111+
// Important things to note:
112+
//
113+
// * Our global transformations must never alter the AST structures which
114+
// the statefull IKG generator keeps across compilations.
115+
// => We need to make our own copy.
116+
//
117+
// * We must ensure the stateful IKG generator keeps giving us all the
118+
// compile-time errors, warnings, hints for every compilation and we
119+
// report the compilation result accordingly.
120+
//
121+
final exitCode = await compile(arguments);
122+
switch (exitCode) {
123+
case 0:
124+
return batch_util.CompilerOutcome.Ok;
125+
case _compileTimeErrorExitCode:
126+
case _badUsageExitCode:
127+
return batch_util.CompilerOutcome.Fail;
128+
default:
129+
throw 'Could not obtain correct exit code from compiler.';
130+
}
131+
});
92132
}

pkg/vm/tool/gen_kernel

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
3+
# for details. All rights reserved. Use of this source code is governed by a
4+
# BSD-style license that can be found in the LICENSE file.
5+
6+
# Script for generating kernel files using Dart 2 pipeline: Fasta with
7+
# strong mode enabled.
8+
9+
set -e
10+
11+
function follow_links() {
12+
file="$1"
13+
while [ -h "$file" ]; do
14+
# On Mac OS, readlink -f doesn't work.
15+
file="$(readlink "$file")"
16+
done
17+
echo "$file"
18+
}
19+
20+
# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
21+
PROG_NAME="$(follow_links "$BASH_SOURCE")"
22+
23+
# Handle the case where dart-sdk/bin has been symlinked to.
24+
CUR_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
25+
26+
SDK_DIR="$CUR_DIR/../../.."
27+
28+
if [[ `uname` == 'Darwin' ]]; then
29+
DART="$SDK_DIR/tools/sdks/mac/dart-sdk/bin/dart"
30+
OUT_DIR="$SDK_DIR/xcodebuild"
31+
else
32+
DART="$SDK_DIR/tools/sdks/linux/dart-sdk/bin/dart"
33+
OUT_DIR="$SDK_DIR/out"
34+
fi
35+
36+
exec "$DART" "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" $@

tests/language_2/language_2_kernel.status

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,7 @@ compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
296296
compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
297297
compile_time_constant_static5_test/23: CompileTimeError # Issue 31402 (Field declaration)
298298
conditional_import_string_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
299-
conditional_import_string_test: DartkCompileTimeError
300299
conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
301-
conditional_import_test: DartkCompileTimeError
302300
conditional_method_invocation_test/12: MissingCompileTimeError
303301
conditional_method_invocation_test/13: MissingCompileTimeError
304302
conditional_property_access_test/10: MissingCompileTimeError

tests/lib_2/lib_2_kernel.status

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ async/timer_not_available_test: RuntimeError
6565
async/timer_repeat_test: CompileTimeError # Issue 31402 (Invocation arguments)
6666
async/timer_test: CompileTimeError # Issue 31402 (Invocation arguments)
6767
async/zone_run_unary_test: CompileTimeError # Issue 31537
68-
convert/streamed_conversion_json_utf8_decode_test: DartkCompileTimeError
6968
convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
70-
html/*: DartkCompileTimeError
7169
html/*: SkipByDesign # dart:html not supported on VM.
7270
isolate/compile_time_error_test/01: MissingCompileTimeError
7371
isolate/count_test: CompileTimeError # Issue 31402 (Invocation arguments)

tools/testing/dart/command.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ class Command {
5252
workingDirectory: workingDirectory);
5353
}
5454

55-
static Command kernelCompilation(
55+
static Command vmKernelCompilation(
5656
String outputFile,
5757
bool neverSkipCompilation,
5858
List<Uri> bootstrapDependencies,
5959
String executable,
6060
List<String> arguments,
6161
Map<String, String> environment) {
62-
return new KernelCompilationCommand._(outputFile, neverSkipCompilation,
62+
return new VMKernelCompilationCommand._(outputFile, neverSkipCompilation,
6363
bootstrapDependencies, executable, arguments, environment);
6464
}
6565

@@ -282,15 +282,15 @@ class CompilationCommand extends ProcessCommand {
282282
deepJsonCompare(_bootstrapDependencies, other._bootstrapDependencies);
283283
}
284284

285-
class KernelCompilationCommand extends CompilationCommand {
286-
KernelCompilationCommand._(
285+
class VMKernelCompilationCommand extends CompilationCommand {
286+
VMKernelCompilationCommand._(
287287
String outputFile,
288288
bool neverSkipCompilation,
289289
List<Uri> bootstrapDependencies,
290290
String executable,
291291
List<String> arguments,
292292
Map<String, String> environmentOverrides)
293-
: super._('dartk', outputFile, neverSkipCompilation,
293+
: super._('vm_compile_to_kernel', outputFile, neverSkipCompilation,
294294
bootstrapDependencies, executable, arguments, environmentOverrides);
295295

296296
int get maxNumRetries => 1;

tools/testing/dart/command_output.dart

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,8 @@ class DevCompilerCommandOutput extends CommandOutput {
856856
}
857857
}
858858

859-
class KernelCompilationCommandOutput extends CompilationCommandOutput {
860-
KernelCompilationCommandOutput(
859+
class VMKernelCompilationCommandOutput extends CompilationCommandOutput {
860+
VMKernelCompilationCommandOutput(
861861
Command command,
862862
int exitCode,
863863
bool timedOut,
@@ -879,16 +879,12 @@ class KernelCompilationCommandOutput extends CompilationCommandOutput {
879879
Expectation result = super.result(testCase);
880880
if (result.canBeOutcomeOf(Expectation.crash)) {
881881
return Expectation.dartkCrash;
882-
} else if (result.canBeOutcomeOf(Expectation.timeout)) {
883-
return Expectation.dartkTimeout;
884-
} else if (result.canBeOutcomeOf(Expectation.compileTimeError)) {
885-
return Expectation.dartkCompileTimeError;
886882
}
887883
return result;
888884
}
889885

890886
/// If the compiler was able to produce a Kernel IR file we want to run the
891-
/// result on the Dart VM. We therefore mark the [KernelCompilationCommand]
887+
/// result on the Dart VM. We therefore mark the [VMKernelCompilationCommand]
892888
/// as successful.
893889
///
894890
/// This ensures we test that the DartVM produces correct CompileTime errors
@@ -954,8 +950,8 @@ CommandOutput createCommandOutput(Command command, int exitCode, bool timedOut,
954950
} else if (command is VmCommand) {
955951
return new VMCommandOutput(
956952
command, exitCode, timedOut, stdout, stderr, time, pid);
957-
} else if (command is KernelCompilationCommand) {
958-
return new KernelCompilationCommandOutput(
953+
} else if (command is VMKernelCompilationCommand) {
954+
return new VMKernelCompilationCommandOutput(
959955
command, exitCode, timedOut, stdout, stderr, time, compilationSkipped);
960956
} else if (command is AdbPrecompilationCommand) {
961957
return new VMCommandOutput(

tools/testing/dart/compiler_configuration.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -595,20 +595,18 @@ class PrecompilerCompilerConfiguration extends CompilerConfiguration {
595595

596596
Command computeCompileToKernelCommand(String tempDir, List<String> arguments,
597597
Map<String, String> environmentOverrides) {
598-
var buildDir = _configuration.buildDirectory;
599-
String exec = Platform.executable;
598+
final genKernel =
599+
Platform.script.resolve('../../../pkg/vm/tool/gen_kernel').toFilePath();
600+
final dillFile = tempKernelFile(tempDir);
600601
var args = [
601-
'--packages=.packages',
602-
'pkg/vm/bin/gen_kernel.dart',
603-
'--platform=${buildDir}/vm_platform_strong.dill',
604602
'--aot',
603+
'--platform=${_configuration.buildDirectory}/vm_platform_strong.dill',
605604
'-o',
606-
tempKernelFile(tempDir),
605+
dillFile,
607606
];
608-
args.addAll(arguments.where((name) => name.endsWith('.dart')));
609-
return Command.compilation('compile_to_kernel', tempDir,
610-
bootstrapDependencies(), exec, args, environmentOverrides,
611-
alwaysCompile: !_useSdk);
607+
args.add(arguments.where((name) => name.endsWith('.dart')).single);
608+
return Command.vmKernelCompilation(dillFile, true, bootstrapDependencies(),
609+
genKernel, args, environmentOverrides);
612610
}
613611

614612
/// Creates a command to clean up large temporary kernel files.

tools/testing/dart/test_runner.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,10 +1145,10 @@ class CommandExecutorImpl implements CommandExecutor {
11451145
Future<CommandOutput> _runCommand(Command command, int timeout) {
11461146
if (command is BrowserTestCommand) {
11471147
return _startBrowserControllerTest(command, timeout);
1148-
} else if (command is KernelCompilationCommand) {
1149-
// For now, we always run dartk in batch mode.
1148+
} else if (command is VMKernelCompilationCommand) {
1149+
// For now, we always run vm_compile_to_kernel in batch mode.
11501150
var name = command.displayName;
1151-
assert(name == 'dartk');
1151+
assert(name == 'vm_compile_to_kernel');
11521152
return _getBatchRunner(name)
11531153
.runCommand(name, command, timeout, command.arguments);
11541154
} else if (command is CompilationCommand &&
@@ -1331,7 +1331,7 @@ bool shouldRetryCommand(CommandOutput output) {
13311331

13321332
// The dartk batch compiler sometimes runs out of memory. In such a case we
13331333
// will retry running it.
1334-
if (command is KernelCompilationCommand) {
1334+
if (command is VMKernelCompilationCommand) {
13351335
if (output.hasCrashed) {
13361336
bool containsOutOfMemoryMessage(String line) {
13371337
return line.contains('Exhausted heap space, trying to allocat');

0 commit comments

Comments
 (0)