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 |