| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 allElementsByName[name] = allElementsByName.putIfAbsent( | 55 allElementsByName[name] = allElementsByName.putIfAbsent( |
| 56 name, () => const Link<Element>()).prepend(element); | 56 name, () => const Link<Element>()).prepend(element); |
| 57 for (var link = members; !link.isEmpty; link = link.tail) { | 57 for (var link = members; !link.isEmpty; link = link.tail) { |
| 58 addMemberByName(link.head); | 58 addMemberByName(link.head); |
| 59 } | 59 } |
| 60 } | 60 } |
| 61 | 61 |
| 62 compiler.libraries.values.forEach(addMemberByName); | 62 compiler.libraries.values.forEach(addMemberByName); |
| 63 } | 63 } |
| 64 | 64 |
| 65 | |
| 66 String get name => 'Enqueue'; | 65 String get name => 'Enqueue'; |
| 67 | 66 |
| 68 EnqueueTask(Compiler compiler) | 67 EnqueueTask(Compiler compiler) |
| 69 : resolution = new ResolutionEnqueuer( | 68 : resolution = new ResolutionEnqueuer( |
| 70 compiler, compiler.backend.createItemCompilationContext), | 69 compiler, compiler.backend.createItemCompilationContext), |
| 71 codegen = new CodegenEnqueuer( | 70 codegen = new CodegenEnqueuer( |
| 72 compiler, compiler.backend.createItemCompilationContext), | 71 compiler, compiler.backend.createItemCompilationContext), |
| 73 super(compiler) { | 72 super(compiler) { |
| 74 codegen.task = this; | 73 codegen.task = this; |
| 75 resolution.task = this; | 74 resolution.task = this; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 88 = new Map<String, Link<Element>>(); | 87 = new Map<String, Link<Element>>(); |
| 89 final Map<String, Link<Element>> instanceFunctionsByName | 88 final Map<String, Link<Element>> instanceFunctionsByName |
| 90 = new Map<String, Link<Element>>(); | 89 = new Map<String, Link<Element>>(); |
| 91 final Set<ClassElement> seenClasses = new Set<ClassElement>(); | 90 final Set<ClassElement> seenClasses = new Set<ClassElement>(); |
| 92 final Universe universe = new Universe(); | 91 final Universe universe = new Universe(); |
| 93 | 92 |
| 94 bool queueIsClosed = false; | 93 bool queueIsClosed = false; |
| 95 EnqueueTask task; | 94 EnqueueTask task; |
| 96 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 95 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
| 97 | 96 |
| 97 bool hasEnqueuedEverything = false; |
| 98 |
| 98 Enqueuer(this.name, this.compiler, | 99 Enqueuer(this.name, this.compiler, |
| 99 ItemCompilationContext itemCompilationContextCreator()) | 100 ItemCompilationContext itemCompilationContextCreator()) |
| 100 : this.itemCompilationContextCreator = itemCompilationContextCreator; | 101 : this.itemCompilationContextCreator = itemCompilationContextCreator; |
| 101 | 102 |
| 102 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 103 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 103 bool get isResolutionQueue => false; | 104 bool get isResolutionQueue => false; |
| 104 | 105 |
| 105 /// Returns [:true:] if [member] has been processed by this enqueuer. | 106 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 106 bool isProcessed(Element member); | 107 bool isProcessed(Element member); |
| 107 | 108 |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 // If dart:mirrors is loaded, a const symbol may be used to call a | 336 // If dart:mirrors is loaded, a const symbol may be used to call a |
| 336 // static/top-level method or accessor, instantiate a class, call | 337 // static/top-level method or accessor, instantiate a class, call |
| 337 // an instance method or accessor with the given name. | 338 // an instance method or accessor with the given name. |
| 338 if (!compiler.mirrorsEnabled) return; | 339 if (!compiler.mirrorsEnabled) return; |
| 339 | 340 |
| 340 task.ensureAllElementsByName(); | 341 task.ensureAllElementsByName(); |
| 341 | 342 |
| 342 for (var link = task.allElementsByName[name]; | 343 for (var link = task.allElementsByName[name]; |
| 343 link != null && !link.isEmpty; | 344 link != null && !link.isEmpty; |
| 344 link = link.tail) { | 345 link = link.tail) { |
| 345 Element element = link.head; | 346 pretendElementWasUsed(link.head, elements); |
| 346 if (Elements.isUnresolved(element)) { | 347 } |
| 347 // Ignore. | 348 } |
| 348 } else if (element.isConstructor()) { | 349 |
| 349 ClassElement cls = element.declaration.getEnclosingClass(); | 350 void pretendElementWasUsed(Element element, TreeElements elements) { |
| 350 registerInstantiatedType(cls.rawType, elements); | 351 if (Elements.isUnresolved(element)) { |
| 351 registerStaticUse(element.declaration); | 352 // Ignore. |
| 352 } else if (element.impliesType()) { | 353 } else if (element.isConstructor()) { |
| 353 // Don't enqueue classes, typedefs, and type variables. | 354 ClassElement cls = element.declaration.getEnclosingClass(); |
| 354 } else if (Elements.isStaticOrTopLevel(element)) { | 355 registerInstantiatedType(cls.rawType, elements); |
| 355 registerStaticUse(element.declaration); | 356 registerStaticUse(element.declaration); |
| 356 } else if (element.isInstanceMember()) { | 357 } else if (element.impliesType()) { |
| 357 if (element.isFunction()) { | 358 // Don't enqueue classes, typedefs, and type variables. |
| 358 int arity = | 359 } else if (Elements.isStaticOrTopLevel(element)) { |
| 359 element.asFunctionElement().requiredParameterCount(compiler); | 360 registerStaticUse(element.declaration); |
| 360 Selector selector = | 361 } else if (element.isInstanceMember()) { |
| 361 new Selector.call(element.name, element.getLibrary(), arity); | 362 if (element.isFunction()) { |
| 362 registerInvocation(element.name, selector); | 363 int arity = |
| 363 } else if (element.isSetter()) { | 364 element.asFunctionElement().requiredParameterCount(compiler); |
| 364 Selector selector = | 365 Selector selector = |
| 365 new Selector.setter(element.name, element.getLibrary()); | 366 new Selector.call(element.name, element.getLibrary(), arity); |
| 366 registerInvokedSetter(element.name, selector); | 367 registerInvocation(element.name, selector); |
| 367 } else if (element.isGetter()) { | 368 } else if (element.isSetter()) { |
| 368 Selector selector = | 369 Selector selector = |
| 369 new Selector.getter(element.name, element.getLibrary()); | 370 new Selector.setter(element.name, element.getLibrary()); |
| 370 registerInvokedGetter(element.name, selector); | 371 registerInvokedSetter(element.name, selector); |
| 371 } else if (element.isField()) { | 372 } else if (element.isGetter()) { |
| 372 Selector selector = | 373 Selector selector = |
| 373 new Selector.setter(element.name, element.getLibrary()); | 374 new Selector.getter(element.name, element.getLibrary()); |
| 374 registerInvokedSetter(element.name, selector); | 375 registerInvokedGetter(element.name, selector); |
| 375 selector = | 376 } else if (element.isField()) { |
| 376 new Selector.getter(element.name, element.getLibrary()); | 377 Selector selector = |
| 377 registerInvokedGetter(element.name, selector); | 378 new Selector.setter(element.name, element.getLibrary()); |
| 378 } | 379 registerInvokedSetter(element.name, selector); |
| 380 selector = new Selector.getter(element.name, element.getLibrary()); |
| 381 registerInvokedGetter(element.name, selector); |
| 379 } | 382 } |
| 380 } | 383 } |
| 381 } | 384 } |
| 382 | 385 |
| 383 /// Called when [:new Symbol(...):] is seen. | 386 /// Called when [:new Symbol(...):] is seen. |
| 384 void registerNewSymbol(TreeElements elements) { | 387 void registerNewSymbol(TreeElements elements) { |
| 385 } | 388 } |
| 386 | 389 |
| 390 void enqueueEverything() { |
| 391 if (hasEnqueuedEverything) return; |
| 392 compiler.log('Enqueuing everything'); |
| 393 task.ensureAllElementsByName(); |
| 394 for (Link link in task.allElementsByName.values) { |
| 395 for (Element element in link) { |
| 396 pretendElementWasUsed(element, compiler.globalDependencies); |
| 397 } |
| 398 } |
| 399 hasEnqueuedEverything = true; |
| 400 } |
| 401 |
| 387 processLink(Map<String, Link<Element>> map, | 402 processLink(Map<String, Link<Element>> map, |
| 388 SourceString n, | 403 SourceString n, |
| 389 bool f(Element e)) { | 404 bool f(Element e)) { |
| 390 String memberName = n.slowToString(); | 405 String memberName = n.slowToString(); |
| 391 Link<Element> members = map[memberName]; | 406 Link<Element> members = map[memberName]; |
| 392 if (members != null) { | 407 if (members != null) { |
| 393 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); | 408 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); |
| 394 for (; !members.isEmpty; members = members.tail) { | 409 for (; !members.isEmpty; members = members.tail) { |
| 395 if (!f(members.head)) remaining.addLast(members.head); | 410 if (!f(members.head)) remaining.addLast(members.head); |
| 396 } | 411 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 | 464 |
| 450 /** | 465 /** |
| 451 * Documentation wanted -- johnniwinther | 466 * Documentation wanted -- johnniwinther |
| 452 * | 467 * |
| 453 * Invariant: [element] must be a declaration element. | 468 * Invariant: [element] must be a declaration element. |
| 454 */ | 469 */ |
| 455 void registerStaticUse(Element element) { | 470 void registerStaticUse(Element element) { |
| 456 if (element == null) return; | 471 if (element == null) return; |
| 457 assert(invariant(element, element.isDeclaration)); | 472 assert(invariant(element, element.isDeclaration)); |
| 458 addToWorkList(element); | 473 addToWorkList(element); |
| 474 compiler.backend.registerStaticUse(element, this); |
| 459 } | 475 } |
| 460 | 476 |
| 461 void registerGetOfStaticFunction(FunctionElement element) { | 477 void registerGetOfStaticFunction(FunctionElement element) { |
| 462 registerStaticUse(element); | 478 registerStaticUse(element); |
| 463 registerInstantiatedClass(compiler.closureClass, | 479 registerInstantiatedClass(compiler.closureClass, |
| 464 compiler.globalDependencies); | 480 compiler.globalDependencies); |
| 465 universe.staticFunctionsNeedingGetter.add(element); | 481 universe.staticFunctionsNeedingGetter.add(element); |
| 466 } | 482 } |
| 467 | 483 |
| 468 void registerDynamicInvocation(SourceString methodName, Selector selector) { | 484 void registerDynamicInvocation(SourceString methodName, Selector selector) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 while(!queue.isEmpty) { | 756 while(!queue.isEmpty) { |
| 741 // TODO(johnniwinther): Find an optimal process order for codegen. | 757 // TODO(johnniwinther): Find an optimal process order for codegen. |
| 742 f(queue.removeLast()); | 758 f(queue.removeLast()); |
| 743 } | 759 } |
| 744 } | 760 } |
| 745 | 761 |
| 746 void _logSpecificSummary(log(message)) { | 762 void _logSpecificSummary(log(message)) { |
| 747 log('Compiled ${generatedCode.length} methods.'); | 763 log('Compiled ${generatedCode.length} methods.'); |
| 748 } | 764 } |
| 749 } | 765 } |
| OLD | NEW |