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 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 class EnqueueTask extends CompilerTask { | 7 class EnqueueTask extends CompilerTask { |
8 final ResolutionEnqueuer resolution; | 8 final ResolutionEnqueuer resolution; |
9 final CodegenEnqueuer codegen; | 9 final CodegenEnqueuer codegen; |
10 | 10 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 if (element.isForeign(compiler)) return; | 60 if (element.isForeign(compiler)) return; |
61 | 61 |
62 if (!addElementToWorkList(element, elements)) return; | 62 if (!addElementToWorkList(element, elements)) return; |
63 | 63 |
64 // Enable runtime type support if we discover a getter called runtimeType. | 64 // Enable runtime type support if we discover a getter called runtimeType. |
65 // We have to enable runtime type before hitting the codegen, so | 65 // We have to enable runtime type before hitting the codegen, so |
66 // that constructors know whether they need to generate code for | 66 // that constructors know whether they need to generate code for |
67 // runtime type. | 67 // runtime type. |
68 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { | 68 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { |
69 compiler.enabledRuntimeType = true; | 69 compiler.enabledRuntimeType = true; |
70 compiler.backend.registerRuntimeType(); | 70 // TODO(ahe): Record precise dependency here. |
| 71 compiler.backend.registerRuntimeType(compiler.globalDependencies); |
71 } else if (element == compiler.functionApplyMethod) { | 72 } else if (element == compiler.functionApplyMethod) { |
72 compiler.enabledFunctionApply = true; | 73 compiler.enabledFunctionApply = true; |
73 } else if (element == compiler.invokeOnMethod) { | 74 } else if (element == compiler.invokeOnMethod) { |
74 compiler.enabledInvokeOn = true; | 75 compiler.enabledInvokeOn = true; |
75 } | 76 } |
76 | 77 |
77 nativeEnqueuer.registerElement(element); | 78 nativeEnqueuer.registerElement(element); |
78 } | 79 } |
79 | 80 |
80 /** | 81 /** |
81 * Adds [element] to the work list if it has not already been processed. | 82 * Adds [element] to the work list if it has not already been processed. |
82 * | 83 * |
83 * Returns [:true:] if the [element] should be processed. | 84 * Returns [:true:] if the [element] should be processed. |
84 */ | 85 */ |
85 // TODO(johnniwinther): Change to 'Returns true if the element was added to | 86 // TODO(johnniwinther): Change to 'Returns true if the element was added to |
86 // the work list'? | 87 // the work list'? |
87 bool addElementToWorkList(Element element, [TreeElements elements]); | 88 bool addElementToWorkList(Element element, [TreeElements elements]); |
88 | 89 |
89 void registerInstantiatedType(InterfaceType type) { | 90 void registerInstantiatedType(InterfaceType type, TreeElements elements) { |
90 ClassElement cls = type.element; | 91 ClassElement cls = type.element; |
| 92 elements.registerDependency(cls); |
91 cls.ensureResolved(compiler); | 93 cls.ensureResolved(compiler); |
92 universe.instantiatedTypes.add(type); | 94 universe.instantiatedTypes.add(type); |
93 if (universe.instantiatedClasses.contains(cls)) return; | 95 if (universe.instantiatedClasses.contains(cls)) return; |
94 if (!cls.isAbstract(compiler)) { | 96 if (!cls.isAbstract(compiler)) { |
95 universe.instantiatedClasses.add(cls); | 97 universe.instantiatedClasses.add(cls); |
96 } | 98 } |
97 onRegisterInstantiatedClass(cls); | 99 onRegisterInstantiatedClass(cls); |
98 compiler.backend.registerInstantiatedClass(cls, this); | 100 // We only tell the backend once that [cls] was instantiated, so |
| 101 // any additional dependencies must be treated as global |
| 102 // dependencies. |
| 103 compiler.backend.registerInstantiatedClass( |
| 104 cls, this, compiler.globalDependencies); |
99 } | 105 } |
100 | 106 |
101 void registerInstantiatedClass(ClassElement cls) { | 107 void registerInstantiatedClass(ClassElement cls, TreeElements elements) { |
102 cls.ensureResolved(compiler); | 108 cls.ensureResolved(compiler); |
103 registerInstantiatedType(cls.rawType); | 109 registerInstantiatedType(cls.rawType, elements); |
104 } | 110 } |
105 | 111 |
106 bool checkNoEnqueuedInvokedInstanceMethods() { | 112 bool checkNoEnqueuedInvokedInstanceMethods() { |
107 task.measure(() { | 113 task.measure(() { |
108 // Run through the classes and see if we need to compile methods. | 114 // Run through the classes and see if we need to compile methods. |
109 for (ClassElement classElement in universe.instantiatedClasses) { | 115 for (ClassElement classElement in universe.instantiatedClasses) { |
110 for (ClassElement currentClass = classElement; | 116 for (ClassElement currentClass = classElement; |
111 currentClass != null; | 117 currentClass != null; |
112 currentClass = currentClass.superclass) { | 118 currentClass = currentClass.superclass) { |
113 processInstantiatedClass(currentClass); | 119 processInstantiatedClass(currentClass); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 } | 152 } |
147 if (universe.hasInvocation(member, compiler)) { | 153 if (universe.hasInvocation(member, compiler)) { |
148 return addToWorkList(member); | 154 return addToWorkList(member); |
149 } | 155 } |
150 // If there is a property access with the same name as a method we | 156 // If there is a property access with the same name as a method we |
151 // need to emit the method. | 157 // need to emit the method. |
152 if (universe.hasInvokedGetter(member, compiler)) { | 158 if (universe.hasInvokedGetter(member, compiler)) { |
153 // We will emit a closure, so make sure the closure class is | 159 // We will emit a closure, so make sure the closure class is |
154 // generated. | 160 // generated. |
155 compiler.closureClass.ensureResolved(compiler); | 161 compiler.closureClass.ensureResolved(compiler); |
156 registerInstantiatedClass(compiler.closureClass); | 162 registerInstantiatedClass(compiler.closureClass, |
| 163 // Precise dependency is not important here. |
| 164 compiler.globalDependencies); |
157 return addToWorkList(member); | 165 return addToWorkList(member); |
158 } | 166 } |
159 } else if (member.kind == ElementKind.GETTER) { | 167 } else if (member.kind == ElementKind.GETTER) { |
160 if (universe.hasInvokedGetter(member, compiler)) { | 168 if (universe.hasInvokedGetter(member, compiler)) { |
161 return addToWorkList(member); | 169 return addToWorkList(member); |
162 } | 170 } |
163 // We don't know what selectors the returned closure accepts. If | 171 // We don't know what selectors the returned closure accepts. If |
164 // the set contains any selector we have to assume that it matches. | 172 // the set contains any selector we have to assume that it matches. |
165 if (universe.hasInvocation(member, compiler)) { | 173 if (universe.hasInvocation(member, compiler)) { |
166 return addToWorkList(member); | 174 return addToWorkList(member); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 } | 369 } |
362 | 370 |
363 void registerFieldGetter(Element element) { | 371 void registerFieldGetter(Element element) { |
364 universe.fieldGetters.add(element); | 372 universe.fieldGetters.add(element); |
365 } | 373 } |
366 | 374 |
367 void registerFieldSetter(Element element) { | 375 void registerFieldSetter(Element element) { |
368 universe.fieldSetters.add(element); | 376 universe.fieldSetters.add(element); |
369 } | 377 } |
370 | 378 |
371 void registerIsCheck(DartType type) { | 379 void registerIsCheck(DartType type, TreeElements elements) { |
372 // Even in checked mode, type annotations for return type and argument | 380 // Even in checked mode, type annotations for return type and argument |
373 // types do not imply type checks, so there should never be a check | 381 // types do not imply type checks, so there should never be a check |
374 // against the type variable of a typedef. | 382 // against the type variable of a typedef. |
375 assert(type.kind != TypeKind.TYPE_VARIABLE || | 383 assert(type.kind != TypeKind.TYPE_VARIABLE || |
376 !type.element.enclosingElement.isTypedef()); | 384 !type.element.enclosingElement.isTypedef()); |
377 universe.isChecks.add(type); | 385 universe.isChecks.add(type); |
378 compiler.backend.registerIsCheck(type, this); | 386 compiler.backend.registerIsCheck(type, this, elements); |
379 } | 387 } |
380 | 388 |
381 void registerAsCheck(DartType type) { | 389 void registerAsCheck(DartType type, TreeElements elements) { |
382 registerIsCheck(type); | 390 registerIsCheck(type, elements); |
383 compiler.backend.registerAsCheck(type); | 391 compiler.backend.registerAsCheck(type, elements); |
384 } | 392 } |
385 | 393 |
386 void forEach(f(WorkItem work)); | 394 void forEach(f(WorkItem work)); |
387 | 395 |
388 void logSummary(log(message)) { | 396 void logSummary(log(message)) { |
389 _logSpecificSummary(log); | 397 _logSpecificSummary(log); |
390 nativeEnqueuer.logSummary(log); | 398 nativeEnqueuer.logSummary(log); |
391 } | 399 } |
392 | 400 |
393 /// Log summary specific to the concrete enqueuer. | 401 /// Log summary specific to the concrete enqueuer. |
(...skipping 24 matching lines...) Expand all Loading... |
418 | 426 |
419 bool isProcessed(Element member) => resolvedElements.containsKey(member); | 427 bool isProcessed(Element member) => resolvedElements.containsKey(member); |
420 | 428 |
421 TreeElements getCachedElements(Element element) { | 429 TreeElements getCachedElements(Element element) { |
422 // TODO(ngeoffray): Get rid of this check. | 430 // TODO(ngeoffray): Get rid of this check. |
423 if (element.enclosingElement.isClosure()) { | 431 if (element.enclosingElement.isClosure()) { |
424 closureMapping.ClosureClassElement cls = element.enclosingElement; | 432 closureMapping.ClosureClassElement cls = element.enclosingElement; |
425 element = cls.methodElement; | 433 element = cls.methodElement; |
426 } | 434 } |
427 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); | 435 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); |
| 436 if (owner == null) { |
| 437 owner = element; |
| 438 } |
428 return resolvedElements[owner.declaration]; | 439 return resolvedElements[owner.declaration]; |
429 } | 440 } |
430 | 441 |
431 /** | 442 /** |
432 * Sets the resolved elements of [element] to [elements], or if [elements] is | 443 * Sets the resolved elements of [element] to [elements], or if [elements] is |
433 * [:null:], to the elements found through [getCachedElements]. | 444 * [:null:], to the elements found through [getCachedElements]. |
434 * | 445 * |
435 * Returns the resolved elements. | 446 * Returns the resolved elements. |
436 */ | 447 */ |
437 TreeElements ensureCachedElements(Element element, TreeElements elements) { | 448 TreeElements ensureCachedElements(Element element, TreeElements elements) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 enableIsolateSupport(library); | 484 enableIsolateSupport(library); |
474 } | 485 } |
475 } | 486 } |
476 } | 487 } |
477 | 488 |
478 return true; | 489 return true; |
479 } | 490 } |
480 | 491 |
481 void enableIsolateSupport(LibraryElement element) { | 492 void enableIsolateSupport(LibraryElement element) { |
482 compiler.isolateLibrary = element.patch; | 493 compiler.isolateLibrary = element.patch; |
483 addToWorkList( | 494 var startRootIsolate = |
484 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); | 495 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); |
| 496 addToWorkList(startRootIsolate); |
| 497 compiler.globalDependencies.registerDependency(startRootIsolate); |
485 addToWorkList(compiler.isolateHelperLibrary.find( | 498 addToWorkList(compiler.isolateHelperLibrary.find( |
486 const SourceString('_currentIsolate'))); | 499 const SourceString('_currentIsolate'))); |
487 addToWorkList(compiler.isolateHelperLibrary.find( | 500 addToWorkList(compiler.isolateHelperLibrary.find( |
488 const SourceString('_callInIsolate'))); | 501 const SourceString('_callInIsolate'))); |
489 } | 502 } |
490 | 503 |
491 void enableNoSuchMethod(Element element) { | 504 void enableNoSuchMethod(Element element) { |
492 if (compiler.enabledNoSuchMethod) return; | 505 if (compiler.enabledNoSuchMethod) return; |
493 if (element.getEnclosingClass() == compiler.objectClass) return; | 506 if (element.getEnclosingClass() == compiler.objectClass) return; |
494 Selector selector = new Selector.noSuchMethod(); | 507 Selector selector = new Selector.noSuchMethod(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 while(!queue.isEmpty) { | 562 while(!queue.isEmpty) { |
550 // TODO(johnniwinther): Find an optimal process order for codegen. | 563 // TODO(johnniwinther): Find an optimal process order for codegen. |
551 f(queue.removeLast()); | 564 f(queue.removeLast()); |
552 } | 565 } |
553 } | 566 } |
554 | 567 |
555 void _logSpecificSummary(log(message)) { | 568 void _logSpecificSummary(log(message)) { |
556 log('Compiled ${generatedCode.length} methods.'); | 569 log('Compiled ${generatedCode.length} methods.'); |
557 } | 570 } |
558 } | 571 } |
OLD | NEW |