| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// This is an interface to the Dart Kernel parser and Kernel binary generator. | 5 /// This is an interface to the Dart Kernel parser and Kernel binary generator. |
| 6 /// | 6 /// |
| 7 /// It is used by the kernel-isolate to load Dart source code and generate | 7 /// It is used by the kernel-isolate to load Dart source code and generate |
| 8 /// Kernel binary format. | 8 /// Kernel binary format. |
| 9 /// | 9 /// |
| 10 /// This is either invoked as the root script of the Kernel isolate when used | 10 /// This is either invoked as the root script of the Kernel isolate when used |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); | 39 const bool verbose = const bool.fromEnvironment('DFE_VERBOSE'); |
| 40 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE'); | 40 const bool strongMode = const bool.fromEnvironment('DFE_STRONG_MODE'); |
| 41 | 41 |
| 42 abstract class Compiler { | 42 abstract class Compiler { |
| 43 final FileSystem fileSystem; | 43 final FileSystem fileSystem; |
| 44 final List<String> errors = new List<String>(); | 44 final List<String> errors = new List<String>(); |
| 45 | 45 |
| 46 CompilerOptions options; | 46 CompilerOptions options; |
| 47 | 47 |
| 48 Compiler(this.fileSystem) { | 48 Compiler(this.fileSystem, Uri platformKernel) { |
| 49 Uri packagesUri = (Platform.packageConfig != null) | 49 Uri packagesUri = (Platform.packageConfig != null) |
| 50 ? Uri.parse(Platform.packageConfig) | 50 ? Uri.parse(Platform.packageConfig) |
| 51 : null; | 51 : null; |
| 52 | 52 |
| 53 Uri sdkSummary = Uri.base | |
| 54 .resolveUri(new Uri.file(Platform.resolvedExecutable)) | |
| 55 .resolveUri(new Uri.directory("patched_sdk")) | |
| 56 // TODO(sigmund): use outline.dill when the mixin transformer is | |
| 57 // modular. | |
| 58 .resolve('platform.dill'); | |
| 59 | |
| 60 if (verbose) { | 53 if (verbose) { |
| 61 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); | 54 print("DFE: Platform.packageConfig: ${Platform.packageConfig}"); |
| 62 print("DFE: packagesUri: ${packagesUri}"); | 55 print("DFE: packagesUri: ${packagesUri}"); |
| 63 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); | 56 print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}"); |
| 64 print("DFE: sdkSummary: ${sdkSummary}"); | 57 print("DFE: platformKernel: ${platformKernel}"); |
| 65 } | 58 } |
| 66 | 59 |
| 67 options = new CompilerOptions() | 60 options = new CompilerOptions() |
| 68 ..strongMode = strongMode | 61 ..strongMode = strongMode |
| 69 ..fileSystem = fileSystem | 62 ..fileSystem = fileSystem |
| 70 ..target = new VmFastaTarget(new TargetFlags(strongMode: strongMode)) | 63 ..target = new VmFastaTarget(new TargetFlags(strongMode: strongMode)) |
| 71 ..packagesFileUri = packagesUri | 64 ..packagesFileUri = packagesUri |
| 72 ..sdkSummary = sdkSummary | 65 ..sdkSummary = platformKernel |
| 73 ..verbose = verbose | 66 ..verbose = verbose |
| 74 ..throwOnErrors = false | 67 ..throwOnErrors = false |
| 75 ..reportMessages = true | 68 ..reportMessages = true |
| 76 ..onError = (CompilationMessage e) { | 69 ..onError = (CompilationMessage e) { |
| 77 if (e.severity == Severity.error) { | 70 if (e.severity == Severity.error) { |
| 78 // TODO(sigmund): support emitting code with errors as long as they | 71 // TODO(sigmund): support emitting code with errors as long as they |
| 79 // are handled in the generated code (issue #30194). | 72 // are handled in the generated code (issue #30194). |
| 80 errors.add(e.message); | 73 errors.add(e.message); |
| 81 } | 74 } |
| 82 }; | 75 }; |
| 83 } | 76 } |
| 84 | 77 |
| 85 Future<Program> compile(Uri script); | 78 Future<Program> compile(Uri script); |
| 86 } | 79 } |
| 87 | 80 |
| 88 class IncrementalCompiler extends Compiler { | 81 class IncrementalCompiler extends Compiler { |
| 89 IncrementalKernelGenerator generator; | 82 IncrementalKernelGenerator generator; |
| 90 | 83 |
| 91 IncrementalCompiler(FileSystem fileSystem) : super(fileSystem); | 84 IncrementalCompiler(FileSystem fileSystem, Uri platformKernel) |
| 85 : super(fileSystem, platformKernel); |
| 92 | 86 |
| 93 @override | 87 @override |
| 94 Future<Program> compile(Uri script) async { | 88 Future<Program> compile(Uri script) async { |
| 95 if (generator == null) { | 89 if (generator == null) { |
| 96 generator = await IncrementalKernelGenerator.newInstance(options, script); | 90 generator = await IncrementalKernelGenerator.newInstance(options, script); |
| 97 } | 91 } |
| 98 DeltaProgram deltaProgram = await generator.computeDelta(); | 92 DeltaProgram deltaProgram = await generator.computeDelta(); |
| 99 // TODO(aam): Accepting/rejecting should be done based on VM response. | 93 // TODO(aam): Accepting/rejecting should be done based on VM response. |
| 100 generator.acceptLastDelta(); | 94 generator.acceptLastDelta(); |
| 101 return deltaProgram.newProgram; | 95 return deltaProgram.newProgram; |
| 102 } | 96 } |
| 103 | 97 |
| 104 void invalidate(Uri uri) { | 98 void invalidate(Uri uri) { |
| 105 generator.invalidate(uri); | 99 generator.invalidate(uri); |
| 106 } | 100 } |
| 107 } | 101 } |
| 108 | 102 |
| 109 class SingleShotCompiler extends Compiler { | 103 class SingleShotCompiler extends Compiler { |
| 110 final bool requireMain; | 104 final bool requireMain; |
| 111 | 105 |
| 112 SingleShotCompiler(FileSystem fileSystem, this.requireMain) | 106 SingleShotCompiler( |
| 113 : super(fileSystem); | 107 FileSystem fileSystem, Uri platformKernel, this.requireMain) |
| 108 : super(fileSystem, platformKernel); |
| 114 | 109 |
| 115 @override | 110 @override |
| 116 Future<Program> compile(Uri script) async { | 111 Future<Program> compile(Uri script) async { |
| 117 return requireMain | 112 return requireMain |
| 118 ? kernelForProgram(script, options) | 113 ? kernelForProgram(script, options) |
| 119 : kernelForBuildUnit([script], options..chaseDependencies = true); | 114 : kernelForBuildUnit([script], options..chaseDependencies = true); |
| 120 } | 115 } |
| 121 } | 116 } |
| 122 | 117 |
| 123 final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>(); | 118 final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>(); |
| 124 | 119 |
| 125 Future<Compiler> lookupOrBuildNewIncrementalCompiler( | 120 Future<Compiler> lookupOrBuildNewIncrementalCompiler( |
| 126 int isolateId, List sourceFiles) async { | 121 int isolateId, List sourceFiles, Uri platformKernel) async { |
| 127 IncrementalCompiler compiler; | 122 IncrementalCompiler compiler; |
| 128 if (isolateCompilers.containsKey(isolateId)) { | 123 if (isolateCompilers.containsKey(isolateId)) { |
| 129 compiler = isolateCompilers[isolateId]; | 124 compiler = isolateCompilers[isolateId]; |
| 130 final HybridFileSystem fileSystem = compiler.fileSystem; | 125 final HybridFileSystem fileSystem = compiler.fileSystem; |
| 131 if (sourceFiles != null) { | 126 if (sourceFiles != null) { |
| 132 for (int i = 0; i < sourceFiles.length ~/ 2; i++) { | 127 for (int i = 0; i < sourceFiles.length ~/ 2; i++) { |
| 133 Uri uri = Uri.parse(sourceFiles[i * 2]); | 128 Uri uri = Uri.parse(sourceFiles[i * 2]); |
| 134 fileSystem.memory | 129 fileSystem.memory |
| 135 .entityForUri(uri) | 130 .entityForUri(uri) |
| 136 .writeAsBytesSync(sourceFiles[i * 2 + 1]); | 131 .writeAsBytesSync(sourceFiles[i * 2 + 1]); |
| 137 compiler.invalidate(uri); | 132 compiler.invalidate(uri); |
| 138 } | 133 } |
| 139 } | 134 } |
| 140 } else { | 135 } else { |
| 141 final FileSystem fileSystem = sourceFiles == null | 136 final FileSystem fileSystem = sourceFiles == null |
| 142 ? PhysicalFileSystem.instance | 137 ? PhysicalFileSystem.instance |
| 143 : _buildFileSystem(sourceFiles); | 138 : _buildFileSystem(sourceFiles); |
| 144 | 139 |
| 145 // TODO(aam): IncrementalCompiler instance created below have to be | 140 // TODO(aam): IncrementalCompiler instance created below have to be |
| 146 // destroyed when corresponding isolate is shut down. To achieve that kernel | 141 // destroyed when corresponding isolate is shut down. To achieve that kernel |
| 147 // isolate needs to receive a message indicating that particular | 142 // isolate needs to receive a message indicating that particular |
| 148 // isolate was shut down. Message should be handled here in this script. | 143 // isolate was shut down. Message should be handled here in this script. |
| 149 compiler = new IncrementalCompiler(fileSystem); | 144 compiler = new IncrementalCompiler(fileSystem, platformKernel); |
| 150 isolateCompilers[isolateId] = compiler; | 145 isolateCompilers[isolateId] = compiler; |
| 151 } | 146 } |
| 152 return compiler; | 147 return compiler; |
| 153 } | 148 } |
| 154 | 149 |
| 155 // Process a request from the runtime. See KernelIsolate::CompileToKernel in | 150 // Process a request from the runtime. See KernelIsolate::CompileToKernel in |
| 156 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. | 151 // kernel_isolate.cc and Loader::SendKernelRequest in loader.cc. |
| 157 Future _processLoadRequest(request) async { | 152 Future _processLoadRequest(request) async { |
| 158 if (verbose) print("DFE: request: $request"); | 153 if (verbose) print("DFE: request: $request"); |
| 159 | 154 |
| 160 int tag = request[0]; | 155 int tag = request[0]; |
| 161 final SendPort port = request[1]; | 156 final SendPort port = request[1]; |
| 162 final String inputFileUri = request[2]; | 157 final String inputFileUri = request[2]; |
| 163 final Uri script = Uri.base.resolve(inputFileUri); | 158 final Uri script = Uri.base.resolve(inputFileUri); |
| 164 final bool incremental = request[3]; | 159 final Uri platformKernel = request[3] != null |
| 160 ? Uri.base.resolveUri(new Uri.file(request[3])) |
| 161 : Uri.base |
| 162 .resolveUri(new Uri.file(Platform.resolvedExecutable)) |
| 163 .resolveUri(new Uri.directory("patched_sdk")) |
| 164 // TODO(sigmund): use outline.dill when the mixin transformer is |
| 165 // modular. |
| 166 .resolve('platform.dill'); |
| 165 | 167 |
| 166 final List sourceFiles = request.length > 5 ? request[5] : null; | 168 final bool incremental = request[4]; |
| 169 |
| 170 final List sourceFiles = request.length > 6 ? request[6] : null; |
| 167 | 171 |
| 168 Compiler compiler; | 172 Compiler compiler; |
| 169 // TODO(aam): There should be no need to have an option to choose | 173 // TODO(aam): There should be no need to have an option to choose |
| 170 // one compiler or another. We should always use an incremental | 174 // one compiler or another. We should always use an incremental |
| 171 // compiler as its functionality is a super set of the other one. We need to | 175 // compiler as its functionality is a super set of the other one. We need to |
| 172 // watch the performance though. | 176 // watch the performance though. |
| 173 if (incremental) { | 177 if (incremental) { |
| 174 final int isolateId = request[4]; | 178 final int isolateId = request[5]; |
| 175 compiler = | 179 compiler = await lookupOrBuildNewIncrementalCompiler( |
| 176 await lookupOrBuildNewIncrementalCompiler(isolateId, sourceFiles); | 180 isolateId, sourceFiles, platformKernel); |
| 177 } else { | 181 } else { |
| 178 final FileSystem fileSystem = sourceFiles == null | 182 final FileSystem fileSystem = sourceFiles == null |
| 179 ? PhysicalFileSystem.instance | 183 ? PhysicalFileSystem.instance |
| 180 : _buildFileSystem(sourceFiles); | 184 : _buildFileSystem(sourceFiles); |
| 181 compiler = new SingleShotCompiler( | 185 compiler = new SingleShotCompiler( |
| 182 fileSystem, sourceFiles == null /* requireMain */); | 186 fileSystem, platformKernel, sourceFiles == null /* requireMain */); |
| 183 } | 187 } |
| 184 | 188 |
| 185 CompilationResult result; | 189 CompilationResult result; |
| 186 try { | 190 try { |
| 187 if (verbose) { | 191 if (verbose) { |
| 188 print("DFE: scriptUri: ${script}"); | 192 print("DFE: scriptUri: ${script}"); |
| 189 } | 193 } |
| 190 | 194 |
| 191 Program program = await compiler.compile(script); | 195 Program program = await compiler.compile(script); |
| 192 | 196 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 // Compilation error. | 259 // Compilation error. |
| 256 throw response[4]; | 260 throw response[4]; |
| 257 } else { | 261 } else { |
| 258 throw "Unexpected response: $response"; | 262 throw "Unexpected response: $response"; |
| 259 } | 263 } |
| 260 }; | 264 }; |
| 261 var request = [ | 265 var request = [ |
| 262 tag, | 266 tag, |
| 263 responsePort.sendPort, | 267 responsePort.sendPort, |
| 264 scriptUri, | 268 scriptUri, |
| 265 1 /* isolateId chosen randomly */, | 269 null /* platformKernel */, |
| 266 false /* incremental */ | 270 false /* incremental */, |
| 271 1 /* isolateId chosen randomly */ |
| 267 ]; | 272 ]; |
| 268 _processLoadRequest(request); | 273 _processLoadRequest(request); |
| 269 } | 274 } |
| 270 | 275 |
| 271 main([args]) { | 276 main([args]) { |
| 272 if (args?.length == 2 && args[0] == '--train') { | 277 if (args?.length == 2 && args[0] == '--train') { |
| 273 // This entry point is used when creating an app snapshot. The argument | 278 // This entry point is used when creating an app snapshot. The argument |
| 274 // provides a script to compile to warm-up generated code. | 279 // provides a script to compile to warm-up generated code. |
| 275 train(args[1]); | 280 train(args[1]); |
| 276 } else { | 281 } else { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 _CompilationCrash(this.exception, this.stack); | 361 _CompilationCrash(this.exception, this.stack); |
| 357 | 362 |
| 358 @override | 363 @override |
| 359 Status get status => Status.crash; | 364 Status get status => Status.crash; |
| 360 | 365 |
| 361 @override | 366 @override |
| 362 String get errorString => "${exception}\n${stack}"; | 367 String get errorString => "${exception}\n${stack}"; |
| 363 | 368 |
| 364 String toString() => "_CompilationCrash(${errorString})"; | 369 String toString() => "_CompilationCrash(${errorString})"; |
| 365 } | 370 } |
| OLD | NEW |