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

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: Unify native behavior processing Created 5 years, 2 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 /// The [ClassElement] for the [double] class defined in 'dart:core'. 60 /// The [ClassElement] for the [double] class defined in 'dart:core'.
61 ClassElement get doubleClass; 61 ClassElement get doubleClass;
62 62
63 /// The [ClassElement] for the [String] class defined in 'dart:core'. 63 /// The [ClassElement] for the [String] class defined in 'dart:core'.
64 ClassElement get stringClass; 64 ClassElement get stringClass;
65 65
66 /// Returns `true` if [cls] is instantiated. 66 /// Returns `true` if [cls] is instantiated.
67 bool isInstantiated(ClassElement cls); 67 bool isInstantiated(ClassElement cls);
68 68
69 /// Returns `true` if [cls] is implemented by an instantiated class.
70 bool isImplemented(ClassElement cls);
71
69 /// Returns `true` if the class world is closed. 72 /// Returns `true` if the class world is closed.
70 bool get isClosed; 73 bool get isClosed;
71 74
72 /// Return `true` if [x] is a subclass of [y]. 75 /// Return `true` if [x] is a subclass of [y].
73 bool isSubclassOf(ClassElement x, ClassElement y); 76 bool isSubclassOf(ClassElement x, ClassElement y);
74 77
75 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 78 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
76 /// instance of [y]. 79 /// instance of [y].
77 bool isSubtypeOf(ClassElement x, ClassElement y); 80 bool isSubtypeOf(ClassElement x, ClassElement y);
78 81
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 /// Returns `true` if any live class that mixes in [mixin] is also a subclass 119 /// Returns `true` if any live class that mixes in [mixin] is also a subclass
117 /// of [superclass]. 120 /// of [superclass].
118 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin); 121 bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin);
119 122
120 /// Returns `true` if any subclass of [superclass] implements [type]. 123 /// Returns `true` if any subclass of [superclass] implements [type].
121 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type); 124 bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type);
122 125
123 /// Returns `true` if closed-world assumptions can be made, that is, 126 /// Returns `true` if closed-world assumptions can be made, that is,
124 /// incremental compilation isn't enabled. 127 /// incremental compilation isn't enabled.
125 bool get hasClosedWorldAssumption; 128 bool get hasClosedWorldAssumption;
129
130 /// Returns a string representation of the closed world.
131 String dump();
126 } 132 }
127 133
128 class World implements ClassWorld { 134 class World implements ClassWorld {
129 ClassElement get objectClass => compiler.objectClass; 135 ClassElement get objectClass => compiler.objectClass;
130 ClassElement get functionClass => compiler.functionClass; 136 ClassElement get functionClass => compiler.functionClass;
131 ClassElement get boolClass => compiler.boolClass; 137 ClassElement get boolClass => compiler.boolClass;
132 ClassElement get numClass => compiler.numClass; 138 ClassElement get numClass => compiler.numClass;
133 ClassElement get intClass => compiler.intClass; 139 ClassElement get intClass => compiler.intClass;
134 ClassElement get doubleClass => compiler.doubleClass; 140 ClassElement get doubleClass => compiler.doubleClass;
135 ClassElement get stringClass => compiler.stringClass; 141 ClassElement get stringClass => compiler.stringClass;
136 ClassElement get nullClass => compiler.nullClass; 142 ClassElement get nullClass => compiler.nullClass;
137 143
138 /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the 144 /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the
139 /// [ti.FlatTypeMask.flags] property. 145 /// [ti.FlatTypeMask.flags] property.
140 List<Map<ClassElement, ti.TypeMask>> canonicalizedTypeMasks = 146 List<Map<ClassElement, ti.TypeMask>> canonicalizedTypeMasks =
141 new List<Map<ClassElement, ti.TypeMask>>.filled(8, null); 147 new List<Map<ClassElement, ti.TypeMask>>.filled(8, null);
142 148
143 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { 149 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
144 return 150 return
145 invariant(cls, cls.isDeclaration, 151 invariant(cls, cls.isDeclaration,
146 message: '$cls must be the declaration.') && 152 message: '$cls must be the declaration.') &&
147 invariant(cls, cls.isResolved, 153 invariant(cls, cls.isResolved,
148 message: '$cls must be resolved.') && 154 message: '$cls must be resolved.')/* &&
155 // TODO(johnniwinther): Reinsert this or similar invariant.
149 (!mustBeInstantiated || 156 (!mustBeInstantiated ||
150 invariant(cls, isInstantiated(cls), 157 invariant(cls, isInstantiated(cls),
151 message: '$cls is not instantiated.')); 158 message: '$cls is not instantiated.'))*/;
152 } 159 }
153 160
154 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an 161 /// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
155 /// instance of [y]. 162 /// instance of [y].
156 bool isSubtypeOf(ClassElement x, ClassElement y) { 163 bool isSubtypeOf(ClassElement x, ClassElement y) {
157 assert(checkInvariants(x)); 164 assert(checkInvariants(x));
158 assert(checkInvariants(y, mustBeInstantiated: false)); 165 assert(checkInvariants(y, mustBeInstantiated: false));
159 166
160 if (y == objectClass) return true; 167 if (y == objectClass) return true;
161 if (x == objectClass) return false; 168 if (x == objectClass) return false;
162 if (x.asInstanceOf(y) != null) return true; 169 if (x.asInstanceOf(y) != null) return true;
163 if (y != functionClass) return false; 170 if (y != functionClass) return false;
164 return x.callType != null; 171 return x.callType != null;
165 } 172 }
166 173
167 /// Return `true` if [x] is a (non-strict) subclass of [y]. 174 /// Return `true` if [x] is a (non-strict) subclass of [y].
168 bool isSubclassOf(ClassElement x, ClassElement y) { 175 bool isSubclassOf(ClassElement x, ClassElement y) {
169 assert(checkInvariants(x)); 176 assert(checkInvariants(x));
170 assert(checkInvariants(y)); 177 assert(checkInvariants(y));
171 178
172 if (y == objectClass) return true; 179 if (y == objectClass) return true;
173 if (x == objectClass) return false; 180 if (x == objectClass) return false;
174 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) { 181 while (x != null && x.hierarchyDepth >= y.hierarchyDepth) {
175 if (x == y) return true; 182 if (x == y) return true;
176 x = x.superclass; 183 x = x.superclass;
177 } 184 }
178 return false; 185 return false;
179 } 186 }
180 187
181 /// Returns `true` if [cls] is instantiated. 188 /// Returns `true` if [cls] is instantiated either directly or through a
189 /// subclass.
182 bool isInstantiated(ClassElement cls) { 190 bool isInstantiated(ClassElement cls) {
183 return compiler.resolverWorld.isInstantiated(cls); 191 return compiler.resolverWorld.isInstantiated(cls);
184 } 192 }
185 193
194 /// Returns `true` if [cls] is implemented by an instantiated class.
195 bool isImplemented(ClassElement cls) {
196 return compiler.resolverWorld.isImplemented(cls);
197 }
198
186 /// Returns an iterable over the directly instantiated classes that extend 199 /// Returns an iterable over the directly instantiated classes that extend
187 /// [cls] possibly including [cls] itself, if it is live. 200 /// [cls] possibly including [cls] itself, if it is live.
188 Iterable<ClassElement> subclassesOf(ClassElement cls) { 201 Iterable<ClassElement> subclassesOf(ClassElement cls) {
189 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration]; 202 ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
190 if (hierarchy == null) return const <ClassElement>[]; 203 if (hierarchy == null) return const <ClassElement>[];
191 return hierarchy.subclasses( 204 return hierarchy.subclasses(
192 includeIndirectlyInstantiated: false, 205 includeIndirectlyInstantiated: false,
193 includeUninstantiated: false); 206 includeUninstantiated: false);
194 } 207 }
195 208
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 Iterable<MixinApplicationElement> uses = _mixinUses[cls]; 314 Iterable<MixinApplicationElement> uses = _mixinUses[cls];
302 return uses != null ? uses : const <MixinApplicationElement>[]; 315 return uses != null ? uses : const <MixinApplicationElement>[];
303 } 316 }
304 317
305 /// Returns an iterable over the live mixin applications that mixin [cls]. 318 /// Returns an iterable over the live mixin applications that mixin [cls].
306 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) { 319 Iterable<MixinApplicationElement> mixinUsesOf(ClassElement cls) {
307 assert(isClosed); 320 assert(isClosed);
308 if (_liveMixinUses == null) { 321 if (_liveMixinUses == null) {
309 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>(); 322 _liveMixinUses = new Map<ClassElement, List<MixinApplicationElement>>();
310 for (ClassElement mixin in _mixinUses.keys) { 323 for (ClassElement mixin in _mixinUses.keys) {
311 Iterable<MixinApplicationElement> uses = 324 List<MixinApplicationElement> uses = <MixinApplicationElement>[];
312 _mixinUses[mixin].where(isInstantiated); 325
313 if (uses.isNotEmpty) _liveMixinUses[mixin] = uses.toList(); 326 void addLiveUse(MixinApplicationElement mixinApplication) {
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
337 _mixinUses[mixin].forEach(addLiveUse);
338 if (uses.isNotEmpty) {
339 _liveMixinUses[mixin] = uses;
340 }
314 } 341 }
315 } 342 }
316 Iterable<MixinApplicationElement> uses = _liveMixinUses[cls]; 343 Iterable<MixinApplicationElement> uses = _liveMixinUses[cls];
317 return uses != null ? uses : const <MixinApplicationElement>[]; 344 return uses != null ? uses : const <MixinApplicationElement>[];
318 } 345 }
319 346
320 /// Returns `true` if [cls] is mixed into a live class. 347 /// Returns `true` if [cls] is mixed into a live class.
321 bool isUsedAsMixin(ClassElement cls) { 348 bool isUsedAsMixin(ClassElement cls) {
322 return !mixinUsesOf(cls).isEmpty; 349 return !mixinUsesOf(cls).isEmpty;
323 } 350 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 519 }
493 } 520 }
494 521
495 // Use the [:seenClasses:] set to include non-instantiated 522 // Use the [:seenClasses:] set to include non-instantiated
496 // classes: if the superclass of these classes require RTI, then 523 // classes: if the superclass of these classes require RTI, then
497 // they also need RTI, so that a constructor passes the type 524 // they also need RTI, so that a constructor passes the type
498 // variables to the super constructor. 525 // variables to the super constructor.
499 compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes); 526 compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
500 } 527 }
501 528
529 @override
530 String dump() {
531 StringBuffer sb = new StringBuffer();
532 sb.write("Instantiated classes in the closed world:\n");
533 getClassHierarchyNode(compiler.objectClass)
534 .printOn(sb, ' ', instantiatedOnly: true);
535 return sb.toString();
536 }
537
502 void registerMixinUse(MixinApplicationElement mixinApplication, 538 void registerMixinUse(MixinApplicationElement mixinApplication,
503 ClassElement mixin) { 539 ClassElement mixin) {
504 // TODO(johnniwinther): Add map restricted to live classes. 540 // TODO(johnniwinther): Add map restricted to live classes.
505 // We don't support patch classes as mixin. 541 // We don't support patch classes as mixin.
506 assert(mixin.isDeclaration); 542 assert(mixin.isDeclaration);
507 List<MixinApplicationElement> users = 543 List<MixinApplicationElement> users =
508 _mixinUses.putIfAbsent(mixin, () => 544 _mixinUses.putIfAbsent(mixin, () =>
509 new List<MixinApplicationElement>()); 545 new List<MixinApplicationElement>());
510 users.add(mixinApplication); 546 users.add(mixinApplication);
511 } 547 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 // function expressions's element. 675 // function expressions's element.
640 // TODO(herhut): Generate classes for function expressions earlier. 676 // TODO(herhut): Generate classes for function expressions earlier.
641 if (element is SynthesizedCallMethodElementX) { 677 if (element is SynthesizedCallMethodElementX) {
642 return getMightBePassedToApply(element.expression); 678 return getMightBePassedToApply(element.expression);
643 } 679 }
644 return functionsThatMightBePassedToApply.contains(element); 680 return functionsThatMightBePassedToApply.contains(element);
645 } 681 }
646 682
647 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport; 683 bool get hasClosedWorldAssumption => !compiler.hasIncrementalSupport;
648 } 684 }
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