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

Side by Side Diff: pkg/compiler/lib/src/js_backend/enqueuer.dart

Issue 2314703002: Split World usage into open, inference, and closed world. (Closed)
Patch Set: Created 4 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.js.enqueue; 5 library dart2js.js.enqueue;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import '../common/backend_api.dart' show Backend; 9 import '../common/backend_api.dart' show Backend;
10 import '../common/codegen.dart' show CodegenWorkItem; 10 import '../common/codegen.dart' show CodegenWorkItem;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 79
80 Backend get backend => _compiler.backend; 80 Backend get backend => _compiler.backend;
81 81
82 CompilerOptions get options => _compiler.options; 82 CompilerOptions get options => _compiler.options;
83 83
84 Registry get globalDependencies => _compiler.globalDependencies; 84 Registry get globalDependencies => _compiler.globalDependencies;
85 85
86 Registry get mirrorDependencies => _compiler.mirrorDependencies; 86 Registry get mirrorDependencies => _compiler.mirrorDependencies;
87 87
88 ClassWorld get _world => _compiler.world; 88 ClassWorld get _world => _compiler.closedWorld;
89 89
90 bool get queueIsEmpty => queue.isEmpty; 90 bool get queueIsEmpty => queue.isEmpty;
91 91
92 /// Returns [:true:] if this enqueuer is the resolution enqueuer. 92 /// Returns [:true:] if this enqueuer is the resolution enqueuer.
93 bool get isResolutionQueue => false; 93 bool get isResolutionQueue => false;
94 94
95 QueueFilter get filter => _compiler.enqueuerFilter; 95 QueueFilter get filter => _compiler.enqueuerFilter;
96 96
97 DiagnosticReporter get reporter => _compiler.reporter; 97 DiagnosticReporter get reporter => _compiler.reporter;
98 98
99 /** 99 /**
100 * Documentation wanted -- johnniwinther 100 * Documentation wanted -- johnniwinther
101 * 101 *
102 * Invariant: [element] must be a declaration element. 102 * Invariant: [element] must be a declaration element.
103 */ 103 */
104 void addToWorkList(Element element) { 104 void addToWorkList(Element element) {
105 assert(invariant(element, element.isDeclaration)); 105 assert(invariant(element, element.isDeclaration));
106 // Don't generate code for foreign elements. 106 // Don't generate code for foreign elements.
107 if (backend.isForeign(element)) return; 107 if (backend.isForeign(element)) return;
108 108
109 // Codegen inlines field initializers. It only needs to generate 109 // Codegen inlines field initializers. It only needs to generate
110 // code for checked setters. 110 // code for checked setters.
111 if (element.isField && element.isInstanceMember) { 111 if (element.isField && element.isInstanceMember) {
112 if (!options.enableTypeAssertions || 112 if (!options.enableTypeAssertions || element.enclosingElement.isClosure) {
113 element.enclosingElement.isClosure) {
114 return; 113 return;
115 } 114 }
116 } 115 }
117 116
118 if (options.hasIncrementalSupport && !isProcessed(element)) { 117 if (options.hasIncrementalSupport && !isProcessed(element)) {
119 newlyEnqueuedElements.add(element); 118 newlyEnqueuedElements.add(element);
120 } 119 }
121 120
122 if (queueIsClosed) { 121 if (queueIsClosed) {
123 throw new SpannableAssertionFailure( 122 throw new SpannableAssertionFailure(
(...skipping 14 matching lines...) Expand all
138 .visitImpact(element, worldImpact, impactVisitor, impactUse); 137 .visitImpact(element, worldImpact, impactVisitor, impactUse);
139 } 138 }
140 139
141 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { 140 void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
142 task.measure(() { 141 task.measure(() {
143 ClassElement cls = type.element; 142 ClassElement cls = type.element;
144 bool isNative = backend.isNative(cls); 143 bool isNative = backend.isNative(cls);
145 universe.registerTypeInstantiation(type, 144 universe.registerTypeInstantiation(type,
146 isNative: isNative, 145 isNative: isNative,
147 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { 146 byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
148 backend 147 backend.registerImplementedClass(cls, this, globalDependencies);
149 .registerImplementedClass(cls, this, globalDependencies);
150 }); 148 });
151 // TODO(johnniwinther): Share this reasoning with [Universe]. 149 // TODO(johnniwinther): Share this reasoning with [Universe].
152 if (!cls.isAbstract || isNative || mirrorUsage) { 150 if (!cls.isAbstract || isNative || mirrorUsage) {
153 processInstantiatedClass(cls); 151 processInstantiatedClass(cls);
154 } 152 }
155 }); 153 });
156 } 154 }
157 155
158 bool checkNoEnqueuedInvokedInstanceMethods() { 156 bool checkNoEnqueuedInvokedInstanceMethods() {
159 return filter.checkNoEnqueuedInvokedInstanceMethods(this); 157 return filter.checkNoEnqueuedInvokedInstanceMethods(this);
(...skipping 11 matching lines...) Expand all
171 169
172 if (member.isField) { 170 if (member.isField) {
173 // The obvious thing to test here would be "member.isNative", 171 // The obvious thing to test here would be "member.isNative",
174 // however, that only works after metadata has been parsed/analyzed, 172 // however, that only works after metadata has been parsed/analyzed,
175 // and that may not have happened yet. 173 // and that may not have happened yet.
176 // So instead we use the enclosing class, which we know have had 174 // So instead we use the enclosing class, which we know have had
177 // its metadata parsed and analyzed. 175 // its metadata parsed and analyzed.
178 // Note: this assumes that there are no non-native fields on native 176 // Note: this assumes that there are no non-native fields on native
179 // classes, which may not be the case when a native class is subclassed. 177 // classes, which may not be the case when a native class is subclassed.
180 if (backend.isNative(cls)) { 178 if (backend.isNative(cls)) {
181 _compiler.world.registerUsedElement(member);
182 if (universe.hasInvokedGetter(member, _world) || 179 if (universe.hasInvokedGetter(member, _world) ||
183 universe.hasInvocation(member, _world)) { 180 universe.hasInvocation(member, _world)) {
184 addToWorkList(member); 181 addToWorkList(member);
185 return; 182 return;
186 } 183 }
187 if (universe.hasInvokedSetter(member, _world)) { 184 if (universe.hasInvokedSetter(member, _world)) {
188 addToWorkList(member); 185 addToWorkList(member);
189 return; 186 return;
190 } 187 }
191 // Native fields need to go into instanceMembersByName as they 188 // Native fields need to go into instanceMembersByName as they
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 message: "Class $superclass has not been " 261 message: "Class $superclass has not been "
265 "processed in resolution.")); 262 "processed in resolution."));
266 */ 263 */
267 264
268 _processedClasses.add(superclass); 265 _processedClasses.add(superclass);
269 recentClasses.add(superclass); 266 recentClasses.add(superclass);
270 superclass.implementation.forEachMember(processInstantiatedClassMember); 267 superclass.implementation.forEachMember(processInstantiatedClassMember);
271 // We only tell the backend once that [superclass] was instantiated, so 268 // We only tell the backend once that [superclass] was instantiated, so
272 // any additional dependencies must be treated as global 269 // any additional dependencies must be treated as global
273 // dependencies. 270 // dependencies.
274 backend.registerInstantiatedClass( 271 backend.registerInstantiatedClass(superclass, this, globalDependencies);
275 superclass, this, globalDependencies);
276 } 272 }
277 273
278 ClassElement superclass = cls; 274 ClassElement superclass = cls;
279 while (superclass != null) { 275 while (superclass != null) {
280 processClass(superclass); 276 processClass(superclass);
281 superclass = superclass.superclass; 277 superclass = superclass.superclass;
282 } 278 }
283 }); 279 });
284 } 280 }
285 281
(...skipping 14 matching lines...) Expand all
300 /// Enqeue the constructor [ctor] if it is required for reflection. 296 /// Enqeue the constructor [ctor] if it is required for reflection.
301 /// 297 ///
302 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 298 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
303 /// needed for reflection. 299 /// needed for reflection.
304 void enqueueReflectiveConstructor( 300 void enqueueReflectiveConstructor(
305 ConstructorElement ctor, bool enclosingWasIncluded) { 301 ConstructorElement ctor, bool enclosingWasIncluded) {
306 if (shouldIncludeElementDueToMirrors(ctor, 302 if (shouldIncludeElementDueToMirrors(ctor,
307 includedEnclosing: enclosingWasIncluded)) { 303 includedEnclosing: enclosingWasIncluded)) {
308 logEnqueueReflectiveAction(ctor); 304 logEnqueueReflectiveAction(ctor);
309 ClassElement cls = ctor.declaration.enclosingClass; 305 ClassElement cls = ctor.declaration.enclosingClass;
310 backend.registerInstantiatedType( 306 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies,
311 cls.rawType, this, mirrorDependencies,
312 mirrorUsage: true); 307 mirrorUsage: true);
313 registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); 308 registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
314 } 309 }
315 } 310 }
316 311
317 /// Enqeue the member [element] if it is required for reflection. 312 /// Enqeue the member [element] if it is required for reflection.
318 /// 313 ///
319 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 314 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
320 /// needed for reflection. 315 /// needed for reflection.
321 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { 316 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) {
(...skipping 27 matching lines...) Expand all
349 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 344 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
350 /// needed for reflection. 345 /// needed for reflection.
351 void enqueueReflectiveElementsInClass(ClassElement cls, 346 void enqueueReflectiveElementsInClass(ClassElement cls,
352 Iterable<ClassElement> recents, bool enclosingWasIncluded) { 347 Iterable<ClassElement> recents, bool enclosingWasIncluded) {
353 if (cls.library.isInternalLibrary || cls.isInjected) return; 348 if (cls.library.isInternalLibrary || cls.isInjected) return;
354 bool includeClass = shouldIncludeElementDueToMirrors(cls, 349 bool includeClass = shouldIncludeElementDueToMirrors(cls,
355 includedEnclosing: enclosingWasIncluded); 350 includedEnclosing: enclosingWasIncluded);
356 if (includeClass) { 351 if (includeClass) {
357 logEnqueueReflectiveAction(cls, "register"); 352 logEnqueueReflectiveAction(cls, "register");
358 ClassElement decl = cls.declaration; 353 ClassElement decl = cls.declaration;
359 backend.registerInstantiatedType( 354 backend.registerInstantiatedType(decl.rawType, this, mirrorDependencies,
360 decl.rawType, this, mirrorDependencies,
361 mirrorUsage: true); 355 mirrorUsage: true);
362 } 356 }
363 // If the class is never instantiated, we know nothing of it can possibly 357 // If the class is never instantiated, we know nothing of it can possibly
364 // be reflected upon. 358 // be reflected upon.
365 // TODO(herhut): Add a warning if a mirrors annotation cannot hit. 359 // TODO(herhut): Add a warning if a mirrors annotation cannot hit.
366 if (recents.contains(cls.declaration)) { 360 if (recents.contains(cls.declaration)) {
367 logEnqueueReflectiveAction(cls, "members"); 361 logEnqueueReflectiveAction(cls, "members");
368 cls.constructors.forEach((Element element) { 362 cls.constructors.forEach((Element element) {
369 enqueueReflectiveConstructor(element, includeClass); 363 enqueueReflectiveConstructor(element, includeClass);
370 }); 364 });
371 cls.forEachClassMember((Member member) { 365 cls.forEachClassMember((Member member) {
372 enqueueReflectiveMember(member.element, includeClass); 366 enqueueReflectiveMember(member.element, includeClass);
373 }); 367 });
374 } 368 }
375 } 369 }
376 370
377 /// Enqeue special classes that might not be visible by normal means or that 371 /// Enqeue special classes that might not be visible by normal means or that
378 /// would not normally be enqueued: 372 /// would not normally be enqueued:
379 /// 373 ///
380 /// [Closure] is treated specially as it is the superclass of all closures. 374 /// [Closure] is treated specially as it is the superclass of all closures.
381 /// Although it is in an internal library, we mark it as reflectable. Note 375 /// Although it is in an internal library, we mark it as reflectable. Note
382 /// that none of its methods are reflectable, unless reflectable by 376 /// that none of its methods are reflectable, unless reflectable by
383 /// inheritance. 377 /// inheritance.
384 void enqueueReflectiveSpecialClasses() { 378 void enqueueReflectiveSpecialClasses() {
385 Iterable<ClassElement> classes = 379 Iterable<ClassElement> classes = backend.classesRequiredForReflection;
386 backend.classesRequiredForReflection;
387 for (ClassElement cls in classes) { 380 for (ClassElement cls in classes) {
388 if (backend.referencedFromMirrorSystem(cls)) { 381 if (backend.referencedFromMirrorSystem(cls)) {
389 logEnqueueReflectiveAction(cls); 382 logEnqueueReflectiveAction(cls);
390 backend.registerInstantiatedType( 383 backend.registerInstantiatedType(cls.rawType, this, mirrorDependencies,
391 cls.rawType, this, mirrorDependencies,
392 mirrorUsage: true); 384 mirrorUsage: true);
393 } 385 }
394 } 386 }
395 } 387 }
396 388
397 /// Enqeue all local members of the library [lib] if they are required for 389 /// Enqeue all local members of the library [lib] if they are required for
398 /// reflection. 390 /// reflection.
399 void enqueueReflectiveElementsInLibrary( 391 void enqueueReflectiveElementsInLibrary(
400 LibraryElement lib, Iterable<ClassElement> recents) { 392 LibraryElement lib, Iterable<ClassElement> recents) {
401 bool includeLibrary = 393 bool includeLibrary =
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 @override 700 @override
709 void visitStaticUse(StaticUse staticUse) { 701 void visitStaticUse(StaticUse staticUse) {
710 enqueuer.registerStaticUse(staticUse); 702 enqueuer.registerStaticUse(staticUse);
711 } 703 }
712 704
713 @override 705 @override
714 void visitTypeUse(TypeUse typeUse) { 706 void visitTypeUse(TypeUse typeUse) {
715 enqueuer.registerTypeUse(typeUse); 707 enqueuer.registerTypeUse(typeUse);
716 } 708 }
717 } 709 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698