Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_target.dart

Issue 2893493004: First step for modular output in fasta. (Closed)
Patch Set: cl comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 library fasta.kernel_target; 5 library fasta.kernel_target;
6 6
7 import 'dart:async' show Future; 7 import 'dart:async' show Future;
8 8
9 import 'dart:io' show File; 9 import 'dart:io' show File;
10 10
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 KernelNamedTypeBuilder, 76 KernelNamedTypeBuilder,
77 KernelProcedureBuilder, 77 KernelProcedureBuilder,
78 LibraryBuilder, 78 LibraryBuilder,
79 MemberBuilder, 79 MemberBuilder,
80 NamedTypeBuilder, 80 NamedTypeBuilder,
81 TypeBuilder, 81 TypeBuilder,
82 TypeDeclarationBuilder, 82 TypeDeclarationBuilder,
83 TypeVariableBuilder; 83 TypeVariableBuilder;
84 84
85 import 'verifier.dart' show verifyProgram; 85 import 'verifier.dart' show verifyProgram;
86 import 'kernel_outline_shaker.dart'
87 show trimProgram, RetainedDataBuilder, RootsMarker;
86 88
87 class KernelTarget extends TargetImplementation { 89 class KernelTarget extends TargetImplementation {
88 /// The [FileSystem] which should be used to access files. 90 /// The [FileSystem] which should be used to access files.
89 final FileSystem fileSystem; 91 final FileSystem fileSystem;
90 92
91 final bool strongMode; 93 final bool strongMode;
92 94
93 final DillTarget dillTarget; 95 final DillTarget dillTarget;
94 96
95 /// Shared with [CompilerContext]. 97 /// Shared with [CompilerContext].
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 cls.implementedTypes.clear(); 209 cls.implementedTypes.clear();
208 cls.supertype = null; 210 cls.supertype = null;
209 cls.mixedInType = null; 211 cls.mixedInType = null;
210 builder.supertype = new KernelNamedTypeBuilder("Object", null, 212 builder.supertype = new KernelNamedTypeBuilder("Object", null,
211 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri)) 213 builder.charOffset, builder.fileUri ?? Uri.parse(cls.fileUri))
212 ..builder = objectClassBuilder; 214 ..builder = objectClassBuilder;
213 builder.interfaces = null; 215 builder.interfaces = null;
214 builder.mixedInType = null; 216 builder.mixedInType = null;
215 } 217 }
216 218
217 void handleInputError(InputError error, {bool isFullProgram}) { 219 void handleInputError(InputError error,
220 {bool isFullProgram, bool trimDependencies: false}) {
218 if (error != null) { 221 if (error != null) {
219 String message = error.format(); 222 String message = error.format();
220 print(message); 223 print(message);
221 errors.add(message); 224 errors.add(message);
222 } 225 }
223 _program = erroneousProgram(isFullProgram); 226 _program = erroneousProgram(isFullProgram);
227 if (trimDependencies) {
228 trimDependenciesInProgram(_program, dillTarget.loader.libraries);
229 }
224 } 230 }
225 231
226 @override 232 @override
227 Future<Program> buildOutlines({CanonicalName nameRoot}) async { 233 Future<Program> buildOutlines({CanonicalName nameRoot}) async {
228 if (loader.first == null) return null; 234 if (loader.first == null) return null;
229 try { 235 try {
230 loader.createTypeInferenceEngine(); 236 loader.createTypeInferenceEngine();
231 await loader.buildOutlines(); 237 await loader.buildOutlines();
232 loader.coreLibrary 238 loader.coreLibrary
233 .becomeCoreLibrary(const DynamicType(), const VoidType()); 239 .becomeCoreLibrary(const DynamicType(), const VoidType());
(...skipping 15 matching lines...) Expand all
249 loader.prepareInitializerInference(); 255 loader.prepareInitializerInference();
250 loader.performInitializerInference(); 256 loader.performInitializerInference();
251 } on InputError catch (e) { 257 } on InputError catch (e) {
252 handleInputError(e, isFullProgram: false); 258 handleInputError(e, isFullProgram: false);
253 } catch (e, s) { 259 } catch (e, s) {
254 return reportCrash(e, s, loader?.currentUriForCrashReporting); 260 return reportCrash(e, s, loader?.currentUriForCrashReporting);
255 } 261 }
256 return _program; 262 return _program;
257 } 263 }
258 264
265 /// Build the kernel representation of the program loaded by this target. The
266 /// program will contain full bodies for the code loaded from sources, and
267 /// only references to the code loaded by the [DillTarget], which may or may
268 /// not include method bodies (depending on what was loaded into that target,
269 /// an outline or a full kernel program).
270 ///
271 /// When [trimDependencies] is true, this also runs a tree-shaker that deletes
272 /// anything from the [DillTarget] that is not needed for the source program,
273 /// this includes function bodies and types that are not reachable.
274 ///
275 /// If [verify], run the default kernel verification on the resulting program.
259 @override 276 @override
260 Future<Program> buildProgram({bool verify: false}) async { 277 Future<Program> buildProgram(
278 {bool verify: false, bool trimDependencies: false}) async {
261 if (loader.first == null) return null; 279 if (loader.first == null) return null;
262 if (errors.isNotEmpty) { 280 if (errors.isNotEmpty) {
263 handleInputError(null, isFullProgram: true); 281 handleInputError(null,
282 isFullProgram: true, trimDependencies: trimDependencies);
264 return _program; 283 return _program;
265 } 284 }
266 try { 285 try {
267 await loader.buildBodies(); 286 await loader.buildBodies();
287 _program = link(new List<Library>.from(loader.libraries),
288 trimDependencies: trimDependencies);
268 loader.finishStaticInvocations(); 289 loader.finishStaticInvocations();
269 finishAllConstructors(); 290 finishAllConstructors();
270 loader.finishNativeMethods(); 291 loader.finishNativeMethods();
271 runBuildTransformations(); 292 runBuildTransformations();
272 293
273 if (verify) this.verify(); 294 if (verify) this.verify();
274 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format())); 295 errors.addAll(loader.collectCompileTimeErrors().map((e) => e.format()));
275 if (errors.isNotEmpty) { 296 if (errors.isNotEmpty) {
276 handleInputError(null, isFullProgram: true); 297 handleInputError(null,
298 isFullProgram: true, trimDependencies: trimDependencies);
277 } 299 }
278 } on InputError catch (e) { 300 } on InputError catch (e) {
279 handleInputError(e, isFullProgram: true); 301 handleInputError(e,
302 isFullProgram: true, trimDependencies: trimDependencies);
280 } catch (e, s) { 303 } catch (e, s) {
281 return reportCrash(e, s, loader?.currentUriForCrashReporting); 304 return reportCrash(e, s, loader?.currentUriForCrashReporting);
282 } 305 }
283 return _program; 306 return _program;
284 } 307 }
285 308
286 Future writeDepsFile(Uri output, Uri depsFile, 309 Future writeDepsFile(Uri output, Uri depsFile,
287 {Iterable<Uri> extraDependencies}) async { 310 {Iterable<Uri> extraDependencies}) async {
288 String toRelativeFilePath(Uri uri) { 311 String toRelativeFilePath(Uri uri) {
289 // Ninja expects to find file names relative to the current working 312 // Ninja expects to find file names relative to the current working
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 library.addBuilder(mainBuilder.name, mainBuilder, -1); 366 library.addBuilder(mainBuilder.name, mainBuilder, -1);
344 mainBuilder.body = new ExpressionStatement( 367 mainBuilder.body = new ExpressionStatement(
345 new Throw(new StringLiteral("${errors.join('\n')}"))); 368 new Throw(new StringLiteral("${errors.join('\n')}")));
346 } 369 }
347 library.build(loader.coreLibrary); 370 library.build(loader.coreLibrary);
348 return link(<Library>[library.library]); 371 return link(<Library>[library.library]);
349 } 372 }
350 373
351 /// Creates a program by combining [libraries] with the libraries of 374 /// Creates a program by combining [libraries] with the libraries of
352 /// `dillTarget.loader.program`. 375 /// `dillTarget.loader.program`.
353 Program link(List<Library> libraries, {CanonicalName nameRoot}) { 376 Program link(List<Library> libraries,
377 {CanonicalName nameRoot, bool trimDependencies: false}) {
354 Map<String, Source> uriToSource = 378 Map<String, Source> uriToSource =
355 new Map<String, Source>.from(this.uriToSource); 379 new Map<String, Source>.from(this.uriToSource);
356 380
357 libraries.addAll(dillTarget.loader.libraries); 381 List<Library> extraLibraries = dillTarget.loader.libraries;
382 libraries.addAll(extraLibraries);
358 // TODO(scheglov) Should we also somehow update `uriToSource`? 383 // TODO(scheglov) Should we also somehow update `uriToSource`?
359 // uriToSource.addAll(binary.uriToSource); 384 // uriToSource.addAll(binary.uriToSource);
360 385
361 // TODO(ahe): Remove this line. Kernel seems to generate a default line map 386 // TODO(ahe): Remove this line. Kernel seems to generate a default line map
362 // that used when there's no fileUri on an element. Instead, ensure all 387 // that used when there's no fileUri on an element. Instead, ensure all
363 // elements have a fileUri. 388 // elements have a fileUri.
364 uriToSource[""] = new Source(<int>[0], const <int>[]); 389 uriToSource[""] = new Source(<int>[0], const <int>[]);
365 Program program = new Program( 390 Program program = new Program(
366 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource); 391 nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource);
367 if (loader.first != null) { 392 if (loader.first != null) {
393 // TODO(sigmund): do only for full program
368 Builder builder = loader.first.lookup("main", -1, null); 394 Builder builder = loader.first.lookup("main", -1, null);
369 if (builder is KernelProcedureBuilder) { 395 if (builder is KernelProcedureBuilder) {
370 program.mainMethod = builder.procedure; 396 program.mainMethod = builder.procedure;
371 } 397 }
372 } 398 }
373 if (errors.isEmpty || dillTarget.isLoaded) { 399 if (trimDependencies) {
374 runLinkTransformations(program); 400 trimDependenciesInProgram(program, extraLibraries);
375 } 401 }
402
376 ticker.logMs("Linked program"); 403 ticker.logMs("Linked program");
377 return program; 404 return program;
378 } 405 }
379 406
380 void installDefaultSupertypes() { 407 void installDefaultSupertypes() {
381 Class objectClass = this.objectClass; 408 Class objectClass = this.objectClass;
382 loader.builders.forEach((Uri uri, LibraryBuilder library) { 409 loader.builders.forEach((Uri uri, LibraryBuilder library) {
383 library.forEach((String name, Builder builder) { 410 library.forEach((String name, Builder builder) {
384 if (builder is SourceClassBuilder) { 411 if (builder is SourceClassBuilder) {
385 Class cls = builder.target; 412 Class cls = builder.target;
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 }); 658 });
632 } 659 }
633 660
634 /// Run all transformations that are needed when building a program for the 661 /// Run all transformations that are needed when building a program for the
635 /// first time. 662 /// first time.
636 void runBuildTransformations() { 663 void runBuildTransformations() {
637 transformMixinApplications(); 664 transformMixinApplications();
638 otherTransformations(); 665 otherTransformations();
639 } 666 }
640 667
641 /// Run all transformations that are needed when linking a program.
642 void runLinkTransformations(Program program) {}
643
644 void transformMixinApplications() { 668 void transformMixinApplications() {
645 new MixinFullResolution().transform(_program); 669 new MixinFullResolution().transform(_program);
646 ticker.logMs("Transformed mixin applications"); 670 ticker.logMs("Transformed mixin applications");
647 } 671 }
648 672
649 void otherTransformations() { 673 void otherTransformations() {
650 // TODO(ahe): Don't generate type variables in the first place. 674 // TODO(ahe): Don't generate type variables in the first place.
651 if (!strongMode) { 675 if (!strongMode) {
652 _program.accept(new Erasure()); 676 _program.accept(new Erasure());
653 ticker.logMs("Erased type variables in generic methods"); 677 ticker.logMs("Erased type variables in generic methods");
(...skipping 20 matching lines...) Expand all
674 } 698 }
675 for (Constructor constructor in superclass.constructors) { 699 for (Constructor constructor in superclass.constructors) {
676 if (constructor.name.name.isEmpty) { 700 if (constructor.name.name.isEmpty) {
677 return constructor.function.requiredParameterCount == 0 701 return constructor.function.requiredParameterCount == 0
678 ? constructor 702 ? constructor
679 : null; 703 : null;
680 } 704 }
681 } 705 }
682 return null; 706 return null;
683 } 707 }
708
709 /// Tree-shakes most code from [librariesToShake] by visiting all other
710 /// libraries in [program] and marking the APIs from [librariesToShake] that are
711 /// in use.
712 trimDependenciesInProgram(Program program, List<Library> librariesToShake) {
713 var toShake = librariesToShake.map((lib) => lib.importUri).toSet();
714 var isIncluded = (Uri uri) => !toShake.contains(uri);
715 var data = new RetainedDataBuilder();
716 // TODO(sigmund): replace this step with data that is directly computed from
717 // the builders: we should know the tree-shaking roots without having to do a
718 // second visit over the tree.
719 new RootsMarker(data).run(program, isIncluded);
720 trimProgram(program, data, isIncluded);
721 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart ('k') | pkg/front_end/lib/src/fasta/kernel/verifier.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698