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 universe.instantiatedTypes.add(type); | 91 universe.instantiatedTypes.add(type); |
91 registerInstantiatedClass(type.element); | 92 registerInstantiatedClass(type.element, elements); |
92 } | 93 } |
93 | 94 |
94 void registerInstantiatedClass(ClassElement cls) { | 95 void registerInstantiatedClass(ClassElement cls, TreeElements elements) { |
95 if (universe.instantiatedClasses.contains(cls)) return; | 96 if (universe.instantiatedClasses.contains(cls)) return; |
96 if (!cls.isAbstract(compiler)) { | 97 if (!cls.isAbstract(compiler)) { |
97 universe.instantiatedClasses.add(cls); | 98 universe.instantiatedClasses.add(cls); |
98 } | 99 } |
99 onRegisterInstantiatedClass(cls); | 100 onRegisterInstantiatedClass(cls); |
100 compiler.backend.registerInstantiatedClass(cls, this); | 101 compiler.backend.registerInstantiatedClass(cls, this, elements); |
101 } | 102 } |
102 | 103 |
103 bool checkNoEnqueuedInvokedInstanceMethods() { | 104 bool checkNoEnqueuedInvokedInstanceMethods() { |
104 task.measure(() { | 105 task.measure(() { |
105 // Run through the classes and see if we need to compile methods. | 106 // Run through the classes and see if we need to compile methods. |
106 for (ClassElement classElement in universe.instantiatedClasses) { | 107 for (ClassElement classElement in universe.instantiatedClasses) { |
107 for (ClassElement currentClass = classElement; | 108 for (ClassElement currentClass = classElement; |
108 currentClass != null; | 109 currentClass != null; |
109 currentClass = currentClass.superclass) { | 110 currentClass = currentClass.superclass) { |
110 processInstantiatedClass(currentClass); | 111 processInstantiatedClass(currentClass); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 } | 144 } |
144 if (universe.hasInvocation(member, compiler)) { | 145 if (universe.hasInvocation(member, compiler)) { |
145 return addToWorkList(member); | 146 return addToWorkList(member); |
146 } | 147 } |
147 // If there is a property access with the same name as a method we | 148 // If there is a property access with the same name as a method we |
148 // need to emit the method. | 149 // need to emit the method. |
149 if (universe.hasInvokedGetter(member, compiler)) { | 150 if (universe.hasInvokedGetter(member, compiler)) { |
150 // We will emit a closure, so make sure the closure class is | 151 // We will emit a closure, so make sure the closure class is |
151 // generated. | 152 // generated. |
152 compiler.closureClass.ensureResolved(compiler); | 153 compiler.closureClass.ensureResolved(compiler); |
153 registerInstantiatedClass(compiler.closureClass); | 154 registerInstantiatedClass(compiler.closureClass, |
155 // Precise dependency is not important here. | |
156 compiler.globalDependencies); | |
154 return addToWorkList(member); | 157 return addToWorkList(member); |
155 } | 158 } |
156 } else if (member.kind == ElementKind.GETTER) { | 159 } else if (member.kind == ElementKind.GETTER) { |
157 if (universe.hasInvokedGetter(member, compiler)) { | 160 if (universe.hasInvokedGetter(member, compiler)) { |
158 return addToWorkList(member); | 161 return addToWorkList(member); |
159 } | 162 } |
160 // We don't know what selectors the returned closure accepts. If | 163 // We don't know what selectors the returned closure accepts. If |
161 // the set contains any selector we have to assume that it matches. | 164 // the set contains any selector we have to assume that it matches. |
162 if (universe.hasInvocation(member, compiler)) { | 165 if (universe.hasInvocation(member, compiler)) { |
163 return addToWorkList(member); | 166 return addToWorkList(member); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 } | 351 } |
349 | 352 |
350 void registerFieldGetter(Element element) { | 353 void registerFieldGetter(Element element) { |
351 universe.fieldGetters.add(element); | 354 universe.fieldGetters.add(element); |
352 } | 355 } |
353 | 356 |
354 void registerFieldSetter(Element element) { | 357 void registerFieldSetter(Element element) { |
355 universe.fieldSetters.add(element); | 358 universe.fieldSetters.add(element); |
356 } | 359 } |
357 | 360 |
358 void registerIsCheck(DartType type) { | 361 void registerIsCheck(DartType type, TreeElements elements) { |
359 // Even in checked mode, type annotations for return type and argument | 362 // Even in checked mode, type annotations for return type and argument |
360 // types do not imply type checks, so there should never be a check | 363 // types do not imply type checks, so there should never be a check |
361 // against the type variable of a typedef. | 364 // against the type variable of a typedef. |
362 assert(type.kind != TypeKind.TYPE_VARIABLE || | 365 assert(type.kind != TypeKind.TYPE_VARIABLE || |
363 !type.element.enclosingElement.isTypedef()); | 366 !type.element.enclosingElement.isTypedef()); |
364 universe.isChecks.add(type); | 367 universe.isChecks.add(type); |
365 compiler.backend.registerIsCheck(type, this); | 368 compiler.backend.registerIsCheck(type, this, elements); |
366 } | 369 } |
367 | 370 |
368 void registerAsCheck(DartType type) { | 371 void registerAsCheck(DartType type, TreeElements elements) { |
369 registerIsCheck(type); | 372 registerIsCheck(type, elements); |
370 compiler.backend.registerAsCheck(type); | 373 compiler.backend.registerAsCheck(type, elements); |
371 } | 374 } |
372 | 375 |
373 void forEach(f(WorkItem work)); | 376 void forEach(f(WorkItem work)); |
374 | 377 |
375 void logSummary(log(message)) { | 378 void logSummary(log(message)) { |
376 _logSpecificSummary(log); | 379 _logSpecificSummary(log); |
377 nativeEnqueuer.logSummary(log); | 380 nativeEnqueuer.logSummary(log); |
378 } | 381 } |
379 | 382 |
380 /// Log summary specific to the concrete enqueuer. | 383 /// Log summary specific to the concrete enqueuer. |
(...skipping 24 matching lines...) Expand all Loading... | |
405 | 408 |
406 bool isProcessed(Element member) => resolvedElements.containsKey(member); | 409 bool isProcessed(Element member) => resolvedElements.containsKey(member); |
407 | 410 |
408 TreeElements getCachedElements(Element element) { | 411 TreeElements getCachedElements(Element element) { |
409 // TODO(ngeoffray): Get rid of this check. | 412 // TODO(ngeoffray): Get rid of this check. |
410 if (element.enclosingElement.isClosure()) { | 413 if (element.enclosingElement.isClosure()) { |
411 closureMapping.ClosureClassElement cls = element.enclosingElement; | 414 closureMapping.ClosureClassElement cls = element.enclosingElement; |
412 element = cls.methodElement; | 415 element = cls.methodElement; |
413 } | 416 } |
414 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); | 417 Element owner = element.getOutermostEnclosingMemberOrTopLevel(); |
418 if (owner == null) { | |
419 owner = element; | |
420 } | |
415 return resolvedElements[owner.declaration]; | 421 return resolvedElements[owner.declaration]; |
416 } | 422 } |
417 | 423 |
418 /** | 424 /** |
419 * Sets the resolved elements of [element] to [elements], or if [elements] is | 425 * Sets the resolved elements of [element] to [elements], or if [elements] is |
420 * [:null:], to the elements found through [getCachedElements]. | 426 * [:null:], to the elements found through [getCachedElements]. |
421 * | 427 * |
422 * Returns the resolved elements. | 428 * Returns the resolved elements. |
423 */ | 429 */ |
424 TreeElements ensureCachedElements(Element element, TreeElements elements) { | 430 TreeElements ensureCachedElements(Element element, TreeElements elements) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
460 enableIsolateSupport(library); | 466 enableIsolateSupport(library); |
461 } | 467 } |
462 } | 468 } |
463 } | 469 } |
464 | 470 |
465 return true; | 471 return true; |
466 } | 472 } |
467 | 473 |
468 void enableIsolateSupport(LibraryElement element) { | 474 void enableIsolateSupport(LibraryElement element) { |
469 compiler.isolateLibrary = element.patch; | 475 compiler.isolateLibrary = element.patch; |
470 addToWorkList( | 476 var startRootIsolate = |
471 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE)); | 477 compiler.isolateHelperLibrary.find(Compiler.START_ROOT_ISOLATE); |
478 addToWorkList(startRootIsolate); | |
479 // TODO(ahe): This doesn't seem to be necessary. Why is that? | |
ahe
2013/03/07 10:24:13
It is necessary, but right now the implementation
| |
480 compiler.globalDependencies.registerBackendDependency(startRootIsolate); | |
472 addToWorkList(compiler.isolateHelperLibrary.find( | 481 addToWorkList(compiler.isolateHelperLibrary.find( |
473 const SourceString('_currentIsolate'))); | 482 const SourceString('_currentIsolate'))); |
474 addToWorkList(compiler.isolateHelperLibrary.find( | 483 addToWorkList(compiler.isolateHelperLibrary.find( |
475 const SourceString('_callInIsolate'))); | 484 const SourceString('_callInIsolate'))); |
476 } | 485 } |
477 | 486 |
478 void enableNoSuchMethod(Element element) { | 487 void enableNoSuchMethod(Element element) { |
479 if (compiler.enabledNoSuchMethod) return; | 488 if (compiler.enabledNoSuchMethod) return; |
480 if (element.getEnclosingClass() == compiler.objectClass) return; | 489 if (element.getEnclosingClass() == compiler.objectClass) return; |
481 Selector selector = new Selector.noSuchMethod(); | 490 Selector selector = new Selector.noSuchMethod(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
536 while(!queue.isEmpty) { | 545 while(!queue.isEmpty) { |
537 // TODO(johnniwinther): Find an optimal process order for codegen. | 546 // TODO(johnniwinther): Find an optimal process order for codegen. |
538 f(queue.removeLast()); | 547 f(queue.removeLast()); |
539 } | 548 } |
540 } | 549 } |
541 | 550 |
542 void _logSpecificSummary(log(message)) { | 551 void _logSpecificSummary(log(message)) { |
543 log('Compiled ${generatedCode.length} methods.'); | 552 log('Compiled ${generatedCode.length} methods.'); |
544 } | 553 } |
545 } | 554 } |
OLD | NEW |