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 |