Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show SynthesizedCallMethodElementX; | 7 import 'closure.dart' show SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show Backend; | 8 import 'common/backend_api.dart' show BackendClasses; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| 11 import 'core_types.dart' show CoreClasses; | 11 import 'core_types.dart' show CoreClasses; |
| 12 import 'dart_types.dart'; | 12 import 'dart_types.dart'; |
| 13 import 'elements/elements.dart' | 13 import 'elements/elements.dart' |
| 14 show | 14 show |
| 15 ClassElement, | 15 ClassElement, |
| 16 Element, | 16 Element, |
| 17 FunctionElement, | 17 FunctionElement, |
| 18 MixinApplicationElement, | 18 MixinApplicationElement, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 /// The [ClosedWorld] represents the information known about a program when | 33 /// The [ClosedWorld] represents the information known about a program when |
| 34 /// compiling with closed-world semantics. | 34 /// compiling with closed-world semantics. |
| 35 /// | 35 /// |
| 36 /// Given the entrypoint of an application, we can track what's reachable from | 36 /// Given the entrypoint of an application, we can track what's reachable from |
| 37 /// it, what functions are called, what classes are allocated, which native | 37 /// it, what functions are called, what classes are allocated, which native |
| 38 /// JavaScript types are touched, what language features are used, and so on. | 38 /// JavaScript types are touched, what language features are used, and so on. |
| 39 /// This precise knowledge about what's live in the program is later used in | 39 /// This precise knowledge about what's live in the program is later used in |
| 40 /// optimizations and other compiler decisions during code generation. | 40 /// optimizations and other compiler decisions during code generation. |
| 41 abstract class ClosedWorld implements World { | 41 abstract class ClosedWorld implements World { |
| 42 // TODO(johnniwinther): Refine this into a `BackendClasses` interface. | 42 /// Access to core classes used by the backend. |
| 43 Backend get backend; | 43 BackendClasses get backendClasses; |
| 44 | 44 |
| 45 /// Access to core classes used in the Dart language. | |
| 45 CoreClasses get coreClasses; | 46 CoreClasses get coreClasses; |
| 46 | 47 |
| 47 /// Returns `true` if [cls] is either directly or indirectly instantiated. | 48 /// Returns `true` if [cls] is either directly or indirectly instantiated. |
| 48 bool isInstantiated(ClassElement cls); | 49 bool isInstantiated(ClassElement cls); |
| 49 | 50 |
| 50 /// Returns `true` if [cls] is directly instantiated. | 51 /// Returns `true` if [cls] is directly instantiated. |
| 51 bool isDirectlyInstantiated(ClassElement cls); | 52 bool isDirectlyInstantiated(ClassElement cls); |
| 52 | 53 |
| 53 /// Returns `true` if [cls] is indirectly instantiated, that is through a | 54 /// Returns `true` if [cls] is indirectly instantiated, that is through a |
| 54 /// subclass. | 55 /// subclass. |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 if (classSet == null) { | 495 if (classSet == null) { |
| 495 // Vacuously true. | 496 // Vacuously true. |
| 496 return true; | 497 return true; |
| 497 } | 498 } |
| 498 return classSet.hasOnlyInstantiatedSubclasses; | 499 return classSet.hasOnlyInstantiatedSubclasses; |
| 499 } | 500 } |
| 500 | 501 |
| 501 @override | 502 @override |
| 502 ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) { | 503 ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) { |
| 503 assert(isClosed); | 504 assert(isClosed); |
| 504 if (backend.isJsInterop(cls)) { | 505 if (_backend.isJsInterop(cls)) { |
| 505 return backend.helpers.jsJavaScriptObjectClass; | 506 return _backend.helpers.jsJavaScriptObjectClass; |
| 506 } | 507 } |
| 507 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; | 508 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; |
| 508 return hierarchy != null | 509 return hierarchy != null |
| 509 ? hierarchy.getLubOfInstantiatedSubclasses() | 510 ? hierarchy.getLubOfInstantiatedSubclasses() |
| 510 : null; | 511 : null; |
| 511 } | 512 } |
| 512 | 513 |
| 513 @override | 514 @override |
| 514 ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) { | 515 ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) { |
| 515 assert(isClosed); | 516 assert(isClosed); |
| 516 if (backend.isJsInterop(cls)) { | 517 if (_backend.isJsInterop(cls)) { |
| 517 return backend.helpers.jsJavaScriptObjectClass; | 518 return _backend.helpers.jsJavaScriptObjectClass; |
| 518 } | 519 } |
| 519 ClassSet classSet = _classSets[cls.declaration]; | 520 ClassSet classSet = _classSets[cls.declaration]; |
| 520 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null; | 521 return classSet != null ? classSet.getLubOfInstantiatedSubtypes() : null; |
| 521 } | 522 } |
| 522 | 523 |
| 523 /// Returns an iterable over the common supertypes of the [classes]. | 524 /// Returns an iterable over the common supertypes of the [classes]. |
| 524 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { | 525 Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) { |
| 525 assert(isClosed); | 526 assert(isClosed); |
| 526 Iterator<ClassElement> iterator = classes.iterator; | 527 Iterator<ClassElement> iterator = classes.iterator; |
| 527 if (!iterator.moveNext()) return const <ClassElement>[]; | 528 if (!iterator.moveNext()) return const <ClassElement>[]; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 651 /// Returns `true` if any subclass of [superclass] implements [type]. | 652 /// Returns `true` if any subclass of [superclass] implements [type]. |
| 652 bool hasAnySubclassThatImplements( | 653 bool hasAnySubclassThatImplements( |
| 653 ClassElement superclass, ClassElement type) { | 654 ClassElement superclass, ClassElement type) { |
| 654 assert(isClosed); | 655 assert(isClosed); |
| 655 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); | 656 Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass); |
| 656 if (subclasses == null) return false; | 657 if (subclasses == null) return false; |
| 657 return subclasses.contains(type); | 658 return subclasses.contains(type); |
| 658 } | 659 } |
| 659 | 660 |
| 660 final Compiler _compiler; | 661 final Compiler _compiler; |
| 661 JavaScriptBackend get backend => _compiler.backend; | 662 BackendClasses get backendClasses => _backend.backendClasses; |
| 663 JavaScriptBackend get _backend => _compiler.backend; | |
| 662 CommonMasks get commonMasks => _compiler.commonMasks; | 664 CommonMasks get commonMasks => _compiler.commonMasks; |
| 663 final FunctionSet allFunctions; | 665 final FunctionSet allFunctions; |
| 664 final Set<Element> functionsCalledInLoop = new Set<Element>(); | 666 final Set<Element> functionsCalledInLoop = new Set<Element>(); |
| 665 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); | 667 final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>(); |
| 666 | 668 |
| 667 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); | 669 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>(); |
| 668 | 670 |
| 669 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = | 671 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses = |
| 670 new Map<ClassElement, Set<MixinApplicationElement>>(); | 672 new Map<ClassElement, Set<MixinApplicationElement>>(); |
| 671 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; | 673 Map<ClassElement, List<MixinApplicationElement>> _liveMixinUses; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 686 | 688 |
| 687 final Set<Element> elementsThatCannotThrow = new Set<Element>(); | 689 final Set<Element> elementsThatCannotThrow = new Set<Element>(); |
| 688 | 690 |
| 689 final Set<Element> functionsThatMightBePassedToApply = | 691 final Set<Element> functionsThatMightBePassedToApply = |
| 690 new Set<FunctionElement>(); | 692 new Set<FunctionElement>(); |
| 691 | 693 |
| 692 final Set<Element> alreadyPopulated; | 694 final Set<Element> alreadyPopulated; |
| 693 | 695 |
| 694 bool get isClosed => _closed; | 696 bool get isClosed => _closed; |
| 695 | 697 |
| 696 // Used by selectors. | |
|
Johnni Winther
2016/09/26 14:05:56
No it isn't!
| |
| 697 bool isForeign(Element element) { | |
| 698 return backend.isForeign(element); | |
| 699 } | |
| 700 | |
| 701 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { | 698 Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) { |
| 702 return _typesImplementedBySubclasses[cls.declaration]; | 699 return _typesImplementedBySubclasses[cls.declaration]; |
| 703 } | 700 } |
| 704 | 701 |
| 705 WorldImpl(Compiler compiler) | 702 WorldImpl(Compiler compiler) |
| 706 : allFunctions = new FunctionSet(compiler), | 703 : allFunctions = new FunctionSet(compiler), |
| 707 this._compiler = compiler, | 704 this._compiler = compiler, |
| 708 alreadyPopulated = compiler.cacheStrategy.newSet(); | 705 alreadyPopulated = compiler.cacheStrategy.newSet(); |
| 709 | 706 |
| 710 CoreClasses get coreClasses => _compiler.coreClasses; | 707 CoreClasses get coreClasses => _compiler.coreClasses; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 906 void addFunctionCalledInLoop(Element element) { | 903 void addFunctionCalledInLoop(Element element) { |
| 907 functionsCalledInLoop.add(element.declaration); | 904 functionsCalledInLoop.add(element.declaration); |
| 908 } | 905 } |
| 909 | 906 |
| 910 bool isCalledInLoop(Element element) { | 907 bool isCalledInLoop(Element element) { |
| 911 return functionsCalledInLoop.contains(element.declaration); | 908 return functionsCalledInLoop.contains(element.declaration); |
| 912 } | 909 } |
| 913 | 910 |
| 914 bool fieldNeverChanges(Element element) { | 911 bool fieldNeverChanges(Element element) { |
| 915 if (!element.isField) return false; | 912 if (!element.isField) return false; |
| 916 if (backend.isNative(element)) { | 913 if (_backend.isNative(element)) { |
| 917 // Some native fields are views of data that may be changed by operations. | 914 // Some native fields are views of data that may be changed by operations. |
| 918 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). | 915 // E.g. node.firstChild depends on parentNode.removeBefore(n1, n2). |
| 919 // TODO(sra): Refine the effect classification so that native effects are | 916 // TODO(sra): Refine the effect classification so that native effects are |
| 920 // distinct from ordinary Dart effects. | 917 // distinct from ordinary Dart effects. |
| 921 return false; | 918 return false; |
| 922 } | 919 } |
| 923 | 920 |
| 924 if (element.isFinal || element.isConst) { | 921 if (element.isFinal || element.isConst) { |
| 925 return true; | 922 return true; |
| 926 } | 923 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1007 return getMightBePassedToApply(element.expression); | 1004 return getMightBePassedToApply(element.expression); |
| 1008 } | 1005 } |
| 1009 return functionsThatMightBePassedToApply.contains(element); | 1006 return functionsThatMightBePassedToApply.contains(element); |
| 1010 } | 1007 } |
| 1011 | 1008 |
| 1012 @override | 1009 @override |
| 1013 bool getCurrentlyKnownMightBePassedToApply(Element element) { | 1010 bool getCurrentlyKnownMightBePassedToApply(Element element) { |
| 1014 return getMightBePassedToApply(element); | 1011 return getMightBePassedToApply(element); |
| 1015 } | 1012 } |
| 1016 } | 1013 } |
| OLD | NEW |