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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/deferred_load.dart

Issue 278733003: When mirrors are used with deferred loading we now go through all (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/compiler/dart2js/deferred_mirrors_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 deferred_load; 5 library deferred_load;
6 6
7 import 'dart2jslib.dart' show 7 import 'dart2jslib.dart' show
8 Backend, 8 Backend,
9 Compiler, 9 Compiler,
10 CompilerTask, 10 CompilerTask,
11 Constant, 11 Constant,
12 ConstructedConstant, 12 ConstructedConstant,
13 LibraryLoaderTask,
13 MessageKind, 14 MessageKind,
14 StringConstant, 15 StringConstant,
15 invariant, 16 invariant;
16 Backend;
17 17
18 import 'dart_backend/dart_backend.dart' show 18 import 'dart_backend/dart_backend.dart' show
19 DartBackend; 19 DartBackend;
20 20
21 import 'js_backend/js_backend.dart' show 21 import 'js_backend/js_backend.dart' show
22 JavaScriptBackend; 22 JavaScriptBackend;
23 23
24 import 'elements/elements.dart' show 24 import 'elements/elements.dart' show
25 Element, 25 Element,
26 ClassElement, 26 ClassElement,
(...skipping 19 matching lines...) Expand all
46 NewExpression, 46 NewExpression,
47 Import, 47 Import,
48 LiteralString, 48 LiteralString,
49 LiteralDartString; 49 LiteralDartString;
50 50
51 import 'tree/tree.dart' as ast; 51 import 'tree/tree.dart' as ast;
52 52
53 import 'resolution/resolution.dart' show 53 import 'resolution/resolution.dart' show
54 TreeElements; 54 TreeElements;
55 55
56 import 'mirrors_used.dart' show
57 MirrorUsageAnalyzer,
58 MirrorUsageAnalyzerTask,
59 MirrorUsage;
60
61 /// A "hunk" of the program that will be loaded whenever one of its [imports] 56 /// A "hunk" of the program that will be loaded whenever one of its [imports]
62 /// are loaded. 57 /// are loaded.
63 /// 58 ///
64 /// Elements that are only used in one deferred import, is in an OutputUnit with 59 /// Elements that are only used in one deferred import, is in an OutputUnit with
65 /// the deferred import as single element in the [imports] set. 60 /// the deferred import as single element in the [imports] set.
66 /// 61 ///
67 /// Whenever a deferred Element is shared between several deferred imports it is 62 /// Whenever a deferred Element is shared between several deferred imports it is
68 /// in an output unit with those imports in the [imports] Set. 63 /// in an output unit with those imports in the [imports] Set.
69 /// 64 ///
70 /// OutputUnits are equal if their [imports] are equal. 65 /// OutputUnits are equal if their [imports] are equal.
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 elements.add(constant.type.element); 290 elements.add(constant.type.element);
296 } 291 }
297 constant.getDependencies().forEach(addConstants); 292 constant.getDependencies().forEach(addConstants);
298 } 293 }
299 294
300 /// Collects all direct dependencies of [element]. 295 /// Collects all direct dependencies of [element].
301 /// 296 ///
302 /// The collected dependent elements and constants are are added to 297 /// The collected dependent elements and constants are are added to
303 /// [elements] and [constants] respectively. 298 /// [elements] and [constants] respectively.
304 void collectDependencies(Element element) { 299 void collectDependencies(Element element) {
305 TreeElements treeElements = element.isTypedef 300 TreeElements treeElements =
306 ? element.treeElements 301 compiler.enqueuer.resolution.getCachedElements(element);
sigurdm 2014/05/09 11:27:05 .treeElements is not always present on a TypedefEl
karlklose 2014/05/12 06:53:12 Please file a bug and add a TODO.
sigurdm 2014/05/12 12:10:35 This is not a problem after patch set 2 - because
307 : compiler.enqueuer.resolution.getCachedElements(element);
308 302
309 // TODO(sigurdm): We want to be more specific about this - need a better 303 // TODO(sigurdm): We want to be more specific about this - need a better
310 // way to query "liveness". 304 // way to query "liveness".
311 if (treeElements == null) return; 305 if (treeElements == null) return;
312 306
313 for (Element dependency in treeElements.allElements) { 307 for (Element dependency in treeElements.allElements) {
314 if (Elements.isLocal(dependency) && !dependency.isFunction) continue; 308 if (Elements.isLocal(dependency) && !dependency.isFunction) continue;
315 if (dependency.isErroneous) continue; 309 if (dependency.isErroneous) continue;
316 if (dependency.isStatement) continue; 310 if (dependency.isStatement) continue;
317 if (dependency.isTypeVariable) continue; 311 if (dependency.isTypeVariable) continue;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 } else { 419 } else {
426 _mapDependencies(dependency, import); 420 _mapDependencies(dependency, import);
427 } 421 }
428 } 422 }
429 } 423 }
430 424
431 /// Adds extra dependencies coming from mirror usage. 425 /// Adds extra dependencies coming from mirror usage.
432 /// 426 ///
433 /// The elements are added with [_mapDependencies]. 427 /// The elements are added with [_mapDependencies].
434 void _addMirrorElements() { 428 void _addMirrorElements() {
435 MirrorUsageAnalyzerTask mirrorTask = compiler.mirrorUsageAnalyzerTask; 429 void mapDependenciesIfResolved(Element element, Import deferredImport) {
436 // For each import we record all mirrors-used elements from all the 430 // If there is a target for this class, but no use of mirrors the
karlklose 2014/05/12 06:53:12 What is a 'target'? When does it happen, that an
sigurdm 2014/05/12 12:10:35 Done.
437 // libraries reached directly from that import. 431 // class will not be resolved. We just skip it.
432 if (element is ClassElement &&!element.isResolved) return;
karlklose 2014/05/12 06:53:12 Missing space before '!element'.
sigurdm 2014/05/12 12:10:35 Done.
433 _mapDependencies(element, deferredImport);
434 }
435
436 Set<LibraryElement> seenLibraries = new Set<LibraryElement>();
437
438 // For each deferred import we analyze all elements reachable from the
439 // imported library through non-deferred imports.
440 handleLibrary(LibraryElement library, Import deferredImport) {
441 seenLibraries.add(library);
442
443 library.forEachLocalMember((Element element) {
444 if (compiler.backend.isNeededForReflection(element)) {
445 mapDependenciesIfResolved(element, deferredImport);
446 }
447 });
448
449 for (MetadataAnnotation metadata in library.metadata) {
450 Constant constant =
451 backend.constants.getConstantForMetadata(metadata);
452 if (constant != null) {
453 _mapDependencies(constant.computeType(compiler).element,
454 deferredImport);
455 }
456 }
457 for (LibraryTag tag in library.tags) {
458 for (MetadataAnnotation metadata in tag.metadata) {
459 Constant constant =
460 backend.constants.getConstantForMetadata(metadata);
461 if (constant != null) {
462 _mapDependencies(constant.computeType(compiler).element,
463 deferredImport);
464 }
465 }
466 }
467 }
468
438 for (Import deferredImport in _allDeferredImports.keys) { 469 for (Import deferredImport in _allDeferredImports.keys) {
439 LibraryElement deferredLibrary = _allDeferredImports[deferredImport]; 470 LibraryElement deferredLibrary = _allDeferredImports[deferredImport];
440 for (LibraryElement library in 471 for (LibraryElement library in
441 _nonDeferredReachableLibraries(deferredLibrary)) { 472 _nonDeferredReachableLibraries(deferredLibrary)) {
442 // TODO(sigurdm): The metadata should go to the right output unit. 473 handleLibrary(library, deferredImport);
443 // For now they all go to the main output unit. 474 }
444 for (MetadataAnnotation metadata in library.metadata) { 475 }
445 Constant constant =
446 backend.constants.getConstantForMetadata(metadata);
447 if (constant != null) {
448 _mapDependencies(constant.computeType(compiler).element,
449 _fakeMainImport);
450 }
451 }
452 for (LibraryTag tag in library.tags) {
453 for (MetadataAnnotation metadata in tag.metadata) {
454 Constant constant =
455 backend.constants.getConstantForMetadata(metadata);
456 if (constant != null) {
457 _mapDependencies(constant.computeType(compiler).element,
458 _fakeMainImport);
459 }
460 }
461 }
462 476
463 if (mirrorTask.librariesWithUsage.contains(library)) { 477 // A number of libraries are never imported explicitly - they belong to the
464 478 // main output unit.
465 Map<LibraryElement, List<MirrorUsage>> mirrorsResult = 479 LibraryLoaderTask loader = compiler.libraryLoader;
466 mirrorTask.analyzer.collectMirrorsUsedAnnotation(); 480 for (LibraryElement library in loader.libraryNames.values) {
467 481 if (!seenLibraries.contains(library)) {
468 // If there is a MirrorsUsed annotation we add only the needed 482 handleLibrary(library, _fakeMainImport);
469 // things to the output units for the library.
470 List<MirrorUsage> mirrorUsages = mirrorsResult[library];
471 if (mirrorUsages == null) continue;
472
473 void mapDependenciesIfResolved(Element element) {
474 // If there is a target for this class, but no use of mirrors the
475 // class will not be resolved. We just skip it.
476 if (element is ClassElement &&!element.isResolved) {
477 return;
478 }
479 _mapDependencies(element, deferredImport);
480 }
481
482 for (MirrorUsage usage in mirrorUsages) {
483 if (usage.targets != null) {
484 for (Element dependency in usage.targets) {
485 if (dependency.isLibrary) {
486 LibraryElement library = dependency;
487 library.forEachLocalMember(mapDependenciesIfResolved);
488 } else {
489 mapDependenciesIfResolved(dependency);
490 }
491 }
492 }
493 if (usage.metaTargets != null) {
494 for (Element dependency in usage.metaTargets) {
495 _mapDependencies(dependency, deferredImport);
496 }
497 }
498 }
499 } else {
500 // If there is no MirrorsUsed annotation we add _everything_ to
501 // the output units for the library.
502
503 // TODO(sigurdm): This is too expensive.
504 // Plan: If mirrors are used without MirrorsUsed, create an
505 // "EverythingElse" library that contains all elements that are
506 // not referred by main or deferred libraries that don't contain
507 // mirrors (without MirrorsUsed).
508 //
509 // So basically we want:
510 // mainImport
511 // deferredA
512 // deferredB
513 // deferredCwithMirrorsUsed
514 // deferredEverythingElse
515 //
516 // Where deferredEverythingElse will be loaded for *all* libraries
517 // that contain a mirror usage without MirrorsUsed.
518 // When loading the deferredEverythingElse also load all other
519 // deferred libraries at the same time.
520 bool usesMirrors = false;
521 for (LibraryTag tag in library.tags) {
522 if (tag is! Import) continue;
523 if (library.getLibraryFromTag(tag) == compiler.mirrorsLibrary) {
524 usesMirrors = true;
525 break;
526 }
527 }
528 if (usesMirrors) {
529 // Add all resolved elements to the output unit.
530 for (Element element in
531 compiler.enqueuer.resolution.resolvedElements.keys) {
532 _mapDependencies(element, deferredImport);
533 }
534 for (Element element in
535 compiler.mirrorDependencies.otherDependencies) {
536 _mapDependencies(element, deferredImport);
537 }
538 }
539 }
540 } 483 }
541 } 484 }
542 } 485 }
543 486
544 /// Computes a unique string for the name field for each outputUnit. 487 /// Computes a unique string for the name field for each outputUnit.
545 /// 488 ///
546 /// Also sets up the [hunksToLoad] mapping. 489 /// Also sets up the [hunksToLoad] mapping.
547 void _assignNamesToOutputUnits(Set<OutputUnit> allOutputUnits) { 490 void _assignNamesToOutputUnits(Set<OutputUnit> allOutputUnits) {
548 Set<String> usedImportNames = new Set<String>(); 491 Set<String> usedImportNames = new Set<String>();
549 492
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 Element maybePrefix = elements[identifier]; 769 Element maybePrefix = elements[identifier];
827 if (maybePrefix != null && maybePrefix.isPrefix) { 770 if (maybePrefix != null && maybePrefix.isPrefix) {
828 PrefixElement prefixElement = maybePrefix; 771 PrefixElement prefixElement = maybePrefix;
829 if (prefixElement.isDeferred) { 772 if (prefixElement.isDeferred) {
830 return prefixElement; 773 return prefixElement;
831 } 774 }
832 } 775 }
833 return null; 776 return null;
834 } 777 }
835 } 778 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js/deferred_mirrors_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698