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

Side by Side Diff: pkg/compiler/lib/src/world.dart

Issue 1352533002: Enqueue superclasses instead of supertypes. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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) 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 7 import 'closure.dart' show
8 SynthesizedCallMethodElementX; 8 SynthesizedCallMethodElementX;
9 import 'common/backend_api.dart' show 9 import 'common/backend_api.dart' show
10 Backend; 10 Backend;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 60
61 /// The [ClassElement] for the [double] class defined in 'dart:core'. 61 /// The [ClassElement] for the [double] class defined in 'dart:core'.
62 ClassElement get doubleClass; 62 ClassElement get doubleClass;
63 63
64 /// The [ClassElement] for the [String] class defined in 'dart:core'. 64 /// The [ClassElement] for the [String] class defined in 'dart:core'.
65 ClassElement get stringClass; 65 ClassElement get stringClass;
66 66
67 /// Returns `true` if [cls] is instantiated. 67 /// Returns `true` if [cls] is instantiated.
68 bool isInstantiated(ClassElement cls); 68 bool isInstantiated(ClassElement cls);
69 69
70 /// Returns `true` if [cls] is implemented by an instantiated class.
71 bool isImplemented(ClassElement cls);
72
70 /// Returns `true` if the class world is closed. 73 /// Returns `true` if the class world is closed.
71 bool get isClosed; 74 bool get isClosed;
72 75
73 /// Return `true` if [x] is a subclass of [y]. 76 /// Return `true` if [x] is a subclass of [y].
74 bool isSubclassOf(ClassElement x, ClassElement y); 77 bool isSubclassOf(ClassElement x, ClassElement y);
75 78
76 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 79 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
77 /// instance of [y]. 80 /// instance of [y].
78 bool isSubtypeOf(ClassElement x, ClassElement y); 81 bool isSubtypeOf(ClassElement x, ClassElement y);
79 82
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 /// Returns `true` if any live class that mixes in [mixin] is also a subclass 120 /// Returns `true` if any live class that mixes in [mixin] is also a subclass
118 /// of [superclass]. 121 /// of [superclass].
119 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin); 122 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin);
120 123
121 /// Returns `true` if any subclass of [superclass] implements [type]. 124 /// Returns `true` if any subclass of [superclass] implements [type].
122 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); 125 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type);
123 126
124 /// Returns `true` if closed-world assumptions can be made, that is, 127 /// Returns `true` if closed-world assumptions can be made, that is,
125 /// incremental compilation isn't enabled. 128 /// incremental compilation isn't enabled.
126 bool get hasClosedWorldAssumption; 129 bool get hasClosedWorldAssumption;
130
131 /// Returns a string representation of the closed world.
132 String dump();
127 } 133 }
128 134
129 class World implements ClassWorld { 135 class World implements ClassWorld {
130 ClassElement get objectClass => compiler.objectClass; 136 ClassElement get objectClass => compiler.objectClass;
131 ClassElement get functionClass => compiler.functionClass; 137 ClassElement get functionClass => compiler.functionClass;
132 ClassElement get boolClass => compiler.boolClass; 138 ClassElement get boolClass => compiler.boolClass;
133 ClassElement get numClass => compiler.numClass; 139 ClassElement get numClass => compiler.numClass;
134 ClassElement get intClass => compiler.intClass; 140 ClassElement get intClass => compiler.intClass;
135 ClassElement get doubleClass => compiler.doubleClass; 141 ClassElement get doubleClass => compiler.doubleClass;
136 ClassElement get stringClass => compiler.stringClass; 142 ClassElement get stringClass => compiler.stringClass;
137 ClassElement get nullClass => compiler.nullClass; 143 ClassElement get nullClass => compiler.nullClass;
138 144
139 /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the 145 /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the
140 /// [ti.FlatTypeMask.flags] property. 146 /// [ti.FlatTypeMask.flags] property.
141 List<Map<ClassElement, ti.TypeMask>> canonicalizedTypeMasks = 147 List<Map<ClassElement, ti.TypeMask>> canonicalizedTypeMasks =
142 new List<Map<ClassElement, ti.TypeMask>>.filled(8, null); 148 new List<Map<ClassElement, ti.TypeMask>>.filled(8, null);
143 149
144 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { 150 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
145 return 151 return
146 invariant(cls, cls.isDeclaration, 152 invariant(cls, cls.isDeclaration,
147 message: '$cls must be the declaration.') && 153 message: '$cls must be the declaration.') &&
148 invariant(cls, cls.isResolved, 154 invariant(cls, cls.isResolved,
149 message: '$cls must be resolved.') && 155 message: '$cls must be resolved.')/* &&
156 // TODO(johnniwinther): Reinsert this or similar invariant.
150 (!mustBeInstantiated || 157 (!mustBeInstantiated ||
151 invariant(cls, isInstantiated(cls), 158 invariant(cls, isInstantiated(cls),
152 message: '$cls is not instantiated.')); 159 message: '$cls is not instantiated.'))*/;
153 } 160 }
154 161
155 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 162 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
156 /// instance of [y]. 163 /// instance of [y].
157 bool isSubtypeOf(ClassElement x, ClassElement y) { 164 bool isSubtypeOf(ClassElement x, ClassElement y) {
158 assert(checkInvariants(x)); 165 assert(checkInvariants(x));
159 assert(checkInvariants(y, mustBeInstantiated: false)); 166 assert(checkInvariants(y, mustBeInstantiated: false));
160 167
161 if (y == objectClass) return true; 168 if (y == objectClass) return true;
162 if (x == objectClass) return false; 169 if (x == objectClass) return false;
163 if (x.asInstanceOf(y) != null) return true; 170 if (x.asInstanceOf(y) != null) return true;
164 if (y != functionClass) return false; 171 if (y != functionClass) return false;
165 return x.callType != null; 172 return x.callType != null;
166 } 173 }
167 174
168 /// Return `true` if [x] is a (non-strict) subclass of [y]. 175 /// Return `true` if [x] is a (non-strict) subclass of [y].
169 bool isSubclassOf(ClassElement x, ClassElement y) { 176 bool isSubclassOf(ClassElement x, ClassElement y) {
170 assert(checkInvariants(x)); 177 assert(checkInvariants(x));
171 assert(checkInvariants(y)); 178 assert(checkInvariants(y));
172 179
173 if (y == objectClass) return true; 180 if (y == objectClass) return true;
174 if (x == objectClass) return false; 181 if (x == objectClass) return false;
175 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { 182 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) {
176 if (x == y) return true; 183 if (x == y) return true;
177 x = x.superclass; 184 x = x.superclass;
178 } 185 }
179 return false; 186 return false;
180 } 187 }
181 188
182 /// Returns `true` if [cls] is instantiated. 189 /// Returns `true` if [cls] is instantiated either directly or through a
190 /// subclass.
183 bool isInstantiated(ClassElement cls) { 191 bool isInstantiated(ClassElement cls) {
184 return compiler.resolverWorld.isInstantiated(cls); 192 return compiler.resolverWorld.isInstantiated(cls);
185 } 193 }
186 194
195 /// Returns `true` if [cls] is implemented by an instantiated class.
196 bool isImplemented(ClassElement cls) {
197 return compiler.resolverWorld.isImplemented(cls);
198 }
199
187 /// Returns an iterable over the directly instantiated classes that extend 200 /// Returns an iterable over the directly instantiated classes that extend
188 /// [cls] possibly including [cls] itself, if it is live. 201 /// [cls] possibly including [cls] itself, if it is live.
189 Iterable<ClassElement> subclassesOf(ClassElement cls) { 202 Iterable<ClassElement> subclassesOf(ClassElement cls) {
190 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 203 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
191 if (hierarchy == null) return const <ClassElement>[]; 204 if (hierarchy == null) return const <ClassElement>[];
192 return hierarchy.subclasses( 205 return hierarchy.subclasses(
193 includeIndirectlyInstantiated: false, 206 includeIndirectlyInstantiated: false,
194 includeUninstantiated: false); 207 includeUninstantiated: false);
195 } 208 }
196 209
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 Iterable<MixinApplicationElement> uses = _mixinUses[cls]; 315 Iterable<MixinApplicationElement> uses = _mixinUses[cls];
303 return uses != null ? uses : const <MixinApplicationElement>[]; 316 return uses != null ? uses : const <MixinApplicationElement>[];
304 } 317 }
305 318
306 /// Returns an iterable over the live mixin applications that mixin [cls]. 319 /// Returns an iterable over the live mixin applications that mixin [cls].
307 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { 320 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) {
308 assert(isClosed); 321 assert(isClosed);
309 if (_liveMixinUses == null) { 322 if (_liveMixinUses == null) {
310 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); 323 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>();
311 for (ClassElement mixin in _mixinUses.keys) { 324 for (ClassElement mixin in _mixinUses.keys) {
312 Iterable<MixinApplicationElement> uses = 325 List<MixinApplicationElement> uses = <MixinApplicationElement>[];
313 _mixinUses[mixin].where(isInstantiated); 326 void addLiveUse(MixinApplicationElement mixinApplication) {
karlklose 2015/09/17 10:42:38 Consider push this local function to the beginning
Johnni Winther 2015/09/17 12:56:40 It uses [uses]. Added an empty line before and aft
314 if (uses.isNotEmpty) _liveMixinUses[mixin] = uses.toList(); 327 if (isInstantiated(mixinApplication)) {
328 uses.add(mixinApplication);
329 } else if (mixinApplication.isNamedMixinApplication) {
330 List<MixinApplicationElement> next = _mixinUses[mixinApplication];
331 if (next != null) {
332 next.forEach(addLiveUse);
333 }
334 }
335 }
336 _mixinUses[mixin].forEach(addLiveUse);
337 if (uses.isNotEmpty) {
338 _liveMixinUses[mixin] = uses;
339 }
315 } 340 }
316 } 341 }
317 Iterable<MixinApplicationElement> uses = _liveMixinUses[cls]; 342 Iterable<MixinApplicationElement> uses = _liveMixinUses[cls];
318 return uses != null ? uses : const <MixinApplicationElement>[]; 343 return uses != null ? uses : const <MixinApplicationElement>[];
319 } 344 }
320 345
321 /// Returns `true` if [cls] is mixed into a live class. 346 /// Returns `true` if [cls] is mixed into a live class.
322 bool isUsedAsMixin(ClassElement cls) { 347 bool isUsedAsMixin(ClassElement cls) {
323 return !mixinUsesOf(cls).isEmpty; 348 return !mixinUsesOf(cls).isEmpty;
324 } 349 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 } 523 }
499 } 524 }
500 525
501 // Use the [:seenClasses:] set to include non-instantiated 526 // Use the [:seenClasses:] set to include non-instantiated
502 // classes: if the superclass of these classes require RTI, then 527 // classes: if the superclass of these classes require RTI, then
503 // they also need RTI, so that a constructor passes the type 528 // they also need RTI, so that a constructor passes the type
504 // variables to the super constructor. 529 // variables to the super constructor.
505 compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); 530 compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
506 } 531 }
507 532
533 @override
534 String dump() {
535 StringBuffer sb = new StringBuffer();
536 sb.write("Instantiated classes in the closed world:\n");
537 getClassHierarchyNode(compiler.objectClass)
538 .printOn(sb, ' ', instantiatedOnly: true);
539 return sb.toString();
540 }
541
508 void registerMixinUse(MixinApplicationElement mixinApplication, 542 void registerMixinUse(MixinApplicationElement mixinApplication,
509 ClassElement mixin) { 543 ClassElement mixin) {
510 // TODO(johnniwinther): Add map restricted to live classes. 544 // TODO(johnniwinther): Add map restricted to live classes.
511 // We don't support patch classes as mixin. 545 // We don't support patch classes as mixin.
512 assert(mixin.isDeclaration); 546 assert(mixin.isDeclaration);
513 List<MixinApplicationElement> users = 547 List<MixinApplicationElement> users =
514 _mixinUses.putIfAbsent(mixin, () => 548 _mixinUses.putIfAbsent(mixin, () =>
515 new List<MixinApplicationElement>()); 549 new List<MixinApplicationElement>());
516 users.add(mixinApplication); 550 users.add(mixinApplication);
517 } 551 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // function expressions's element. 679 // function expressions's element.
646 // TODO(herhut): Generate classes for function expressions earlier. 680 // TODO(herhut): Generate classes for function expressions earlier.
647 if (element is SynthesizedCallMethodElementX) { 681 if (element is SynthesizedCallMethodElementX) {
648 return getMightBePassedToApply(element.expression); 682 return getMightBePassedToApply(element.expression);
649 } 683 }
650 return functionsThatMightBePassedToApply.contains(element); 684 return functionsThatMightBePassedToApply.contains(element);
651 } 685 }
652 686
653 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; 687 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport;
654 } 688 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/universe.dart ('k') | sdk/lib/_internal/js_runtime/lib/interceptors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698