| 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 13 matching lines...) Expand all Loading... |
| 24 compiler.backend.nativeResolutionEnqueuer(resolution); | 24 compiler.backend.nativeResolutionEnqueuer(resolution); |
| 25 } | 25 } |
| 26 } | 26 } |
| 27 | 27 |
| 28 abstract class Enqueuer { | 28 abstract class Enqueuer { |
| 29 final String name; | 29 final String name; |
| 30 final Compiler compiler; // TODO(ahe): Remove this dependency. | 30 final Compiler compiler; // TODO(ahe): Remove this dependency. |
| 31 final Function itemCompilationContextCreator; | 31 final Function itemCompilationContextCreator; |
| 32 final Map<String, Link<Element>> instanceMembersByName; | 32 final Map<String, Link<Element>> instanceMembersByName; |
| 33 final Set<ClassElement> seenClasses; | 33 final Set<ClassElement> seenClasses; |
| 34 final Universe universe; |
| 34 | 35 |
| 35 bool queueIsClosed = false; | 36 bool queueIsClosed = false; |
| 36 EnqueueTask task; | 37 EnqueueTask task; |
| 37 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask | 38 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask |
| 38 | 39 |
| 39 Enqueuer(this.name, this.compiler, | 40 Enqueuer(this.name, this.compiler, |
| 40 ItemCompilationContext itemCompilationContextCreator()) | 41 ItemCompilationContext itemCompilationContextCreator()) |
| 41 : this.itemCompilationContextCreator = itemCompilationContextCreator, | 42 : this.itemCompilationContextCreator = itemCompilationContextCreator, |
| 42 instanceMembersByName = new Map<String, Link<Element>>(), | 43 instanceMembersByName = new Map<String, Link<Element>>(), |
| 44 universe = new Universe(), |
| 43 seenClasses = new Set<ClassElement>(); | 45 seenClasses = new Set<ClassElement>(); |
| 44 | 46 |
| 45 Universe get universe; | |
| 46 | |
| 47 /// Returns [:true:] if this enqueuer is the resolution enqueuer. | 47 /// Returns [:true:] if this enqueuer is the resolution enqueuer. |
| 48 bool get isResolutionQueue => false; | 48 bool get isResolutionQueue => false; |
| 49 | 49 |
| 50 /// Returns [:true:] if [member] has been processed by this enqueuer. | 50 /// Returns [:true:] if [member] has been processed by this enqueuer. |
| 51 bool isProcessed(Element member); | 51 bool isProcessed(Element member); |
| 52 | 52 |
| 53 /** | 53 /** |
| 54 * Documentation wanted -- johnniwinther | 54 * Documentation wanted -- johnniwinther |
| 55 * | 55 * |
| 56 * Invariant: [element] must be a declaration element. | 56 * Invariant: [element] must be a declaration element. |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 } | 342 } |
| 343 | 343 |
| 344 void registerDynamicGetter(SourceString methodName, Selector selector) { | 344 void registerDynamicGetter(SourceString methodName, Selector selector) { |
| 345 registerInvokedGetter(methodName, selector); | 345 registerInvokedGetter(methodName, selector); |
| 346 } | 346 } |
| 347 | 347 |
| 348 void registerDynamicSetter(SourceString methodName, Selector selector) { | 348 void registerDynamicSetter(SourceString methodName, Selector selector) { |
| 349 registerInvokedSetter(methodName, selector); | 349 registerInvokedSetter(methodName, selector); |
| 350 } | 350 } |
| 351 | 351 |
| 352 void registerFieldGetter(SourceString getterName, |
| 353 LibraryElement library, |
| 354 DartType type) { |
| 355 task.measure(() { |
| 356 Selector getter = new Selector.getter(getterName, library); |
| 357 registerNewSelector(getterName, |
| 358 new TypedSelector(type, getter), |
| 359 universe.fieldGetters); |
| 360 }); |
| 361 } |
| 362 |
| 363 void registerFieldSetter(SourceString setterName, |
| 364 LibraryElement library, |
| 365 DartType type) { |
| 366 task.measure(() { |
| 367 Selector setter = new Selector.setter(setterName, library); |
| 368 registerNewSelector(setterName, |
| 369 new TypedSelector(type, setter), |
| 370 universe.fieldSetters); |
| 371 }); |
| 372 } |
| 373 |
| 352 void registerIsCheck(DartType type) { | 374 void registerIsCheck(DartType type) { |
| 353 universe.isChecks.add(type); | 375 universe.isChecks.add(type); |
| 354 } | 376 } |
| 355 | 377 |
| 356 void forEach(f(WorkItem work)); | 378 void forEach(f(WorkItem work)); |
| 357 | 379 |
| 358 void logSummary(log(message)) { | 380 void logSummary(log(message)) { |
| 359 _logSpecificSummary(log); | 381 _logSpecificSummary(log); |
| 360 nativeEnqueuer.logSummary(log); | 382 nativeEnqueuer.logSummary(log); |
| 361 } | 383 } |
| 362 | 384 |
| 363 /// Log summary specific to the concrete enqueuer. | 385 /// Log summary specific to the concrete enqueuer. |
| 364 void _logSpecificSummary(log(message)); | 386 void _logSpecificSummary(log(message)); |
| 365 | 387 |
| 366 String toString() => 'Enqueuer($name)'; | 388 String toString() => 'Enqueuer($name)'; |
| 367 } | 389 } |
| 368 | 390 |
| 369 /// [Enqueuer] which is specific to resolution. | 391 /// [Enqueuer] which is specific to resolution. |
| 370 class ResolutionEnqueuer extends Enqueuer { | 392 class ResolutionEnqueuer extends Enqueuer { |
| 371 final ResolutionUniverse universe; | |
| 372 | |
| 373 /** | 393 /** |
| 374 * Map from declaration elements to the [TreeElements] object holding the | 394 * Map from declaration elements to the [TreeElements] object holding the |
| 375 * resolution mapping for the element implementation. | 395 * resolution mapping for the element implementation. |
| 376 * | 396 * |
| 377 * Invariant: Key elements are declaration elements. | 397 * Invariant: Key elements are declaration elements. |
| 378 */ | 398 */ |
| 379 final Map<Element, TreeElements> resolvedElements; | 399 final Map<Element, TreeElements> resolvedElements; |
| 380 | 400 |
| 381 final Queue<ResolutionWorkItem> queue; | 401 final Queue<ResolutionWorkItem> queue; |
| 382 | 402 |
| 383 ResolutionEnqueuer(Compiler compiler, | 403 ResolutionEnqueuer(Compiler compiler, |
| 384 ItemCompilationContext itemCompilationContextCreator()) | 404 ItemCompilationContext itemCompilationContextCreator()) |
| 385 : super('resolution enqueuer', compiler, itemCompilationContextCreator), | 405 : super('resolution enqueuer', compiler, itemCompilationContextCreator), |
| 386 resolvedElements = new Map<Element, TreeElements>(), | 406 resolvedElements = new Map<Element, TreeElements>(), |
| 387 universe = new ResolutionUniverse(), | |
| 388 queue = new Queue<ResolutionWorkItem>(); | 407 queue = new Queue<ResolutionWorkItem>(); |
| 389 | 408 |
| 390 bool get isResolutionQueue => true; | 409 bool get isResolutionQueue => true; |
| 391 | 410 |
| 392 bool isProcessed(Element member) => resolvedElements.containsKey(member); | 411 bool isProcessed(Element member) => resolvedElements.containsKey(member); |
| 393 | 412 |
| 394 TreeElements getCachedElements(Element element) { | 413 TreeElements getCachedElements(Element element) { |
| 395 // TODO(ngeoffray): Get rid of this check. | 414 // TODO(ngeoffray): Get rid of this check. |
| 396 if (element.enclosingElement.isClosure()) { | 415 if (element.enclosingElement.isClosure()) { |
| 397 closureMapping.ClosureClassElement cls = element.enclosingElement; | 416 closureMapping.ClosureClassElement cls = element.enclosingElement; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 nativeEnqueuer.registerJsCall(node, resolver); | 506 nativeEnqueuer.registerJsCall(node, resolver); |
| 488 } | 507 } |
| 489 | 508 |
| 490 void _logSpecificSummary(log(message)) { | 509 void _logSpecificSummary(log(message)) { |
| 491 log('Resolved ${resolvedElements.length} elements.'); | 510 log('Resolved ${resolvedElements.length} elements.'); |
| 492 } | 511 } |
| 493 } | 512 } |
| 494 | 513 |
| 495 /// [Enqueuer] which is specific to code generation. | 514 /// [Enqueuer] which is specific to code generation. |
| 496 class CodegenEnqueuer extends Enqueuer { | 515 class CodegenEnqueuer extends Enqueuer { |
| 497 final CodegenUniverse universe; | |
| 498 | |
| 499 final Queue<CodegenWorkItem> queue; | 516 final Queue<CodegenWorkItem> queue; |
| 517 final Map<Element, js.Expression> generatedCode = |
| 518 new Map<Element, js.Expression>(); |
| 500 | 519 |
| 501 CodegenEnqueuer(Compiler compiler, | 520 CodegenEnqueuer(Compiler compiler, |
| 502 ItemCompilationContext itemCompilationContextCreator()) | 521 ItemCompilationContext itemCompilationContextCreator()) |
| 503 : super('codegen enqueuer', compiler, itemCompilationContextCreator), | 522 : super('codegen enqueuer', compiler, itemCompilationContextCreator), |
| 504 universe = new CodegenUniverse(), | |
| 505 queue = new Queue<CodegenWorkItem>(); | 523 queue = new Queue<CodegenWorkItem>(); |
| 506 | 524 |
| 507 bool isProcessed(Element member) => | 525 bool isProcessed(Element member) => generatedCode.containsKey(member); |
| 508 universe.generatedCode.containsKey(member); | |
| 509 | |
| 510 /** | |
| 511 * Unit test hook that returns code of an element as a String. | |
| 512 * | |
| 513 * Invariant: [element] must be a declaration element. | |
| 514 */ | |
| 515 String assembleCode(Element element) { | |
| 516 assert(invariant(element, element.isDeclaration)); | |
| 517 return js.prettyPrint(universe.generatedCode[element], compiler).getText(); | |
| 518 } | |
| 519 | |
| 520 /** | |
| 521 * Documentation wanted -- johnniwinther | |
| 522 * | |
| 523 * Invariant: [element] must be a declaration element. | |
| 524 */ | |
| 525 void eagerRecompile(Element element) { | |
| 526 assert(invariant(element, element.isDeclaration)); | |
| 527 universe.generatedCode.remove(element); | |
| 528 universe.generatedBailoutCode.remove(element); | |
| 529 addToWorkList(element); | |
| 530 } | |
| 531 | 526 |
| 532 bool addElementToWorkList(Element element, [TreeElements elements]) { | 527 bool addElementToWorkList(Element element, [TreeElements elements]) { |
| 533 if (queueIsClosed) { | 528 if (queueIsClosed) { |
| 534 throw new SpannableAssertionFailure(element, | 529 throw new SpannableAssertionFailure(element, |
| 535 "Codegen work list is closed."); | 530 "Codegen work list is closed."); |
| 536 } | 531 } |
| 537 elements = | 532 elements = |
| 538 compiler.enqueuer.resolution.ensureCachedElements(element, elements); | 533 compiler.enqueuer.resolution.ensureCachedElements(element, elements); |
| 539 | 534 |
| 540 CodegenWorkItem workItem = new CodegenWorkItem( | 535 CodegenWorkItem workItem = new CodegenWorkItem( |
| 541 element, elements, itemCompilationContextCreator()); | 536 element, elements, itemCompilationContextCreator()); |
| 542 queue.add(workItem); | 537 queue.add(workItem); |
| 543 | 538 |
| 544 return true; | 539 return true; |
| 545 } | 540 } |
| 546 | 541 |
| 547 void registerFieldGetter(SourceString getterName, | |
| 548 LibraryElement library, | |
| 549 DartType type) { | |
| 550 task.measure(() { | |
| 551 Selector getter = new Selector.getter(getterName, library); | |
| 552 registerNewSelector(getterName, | |
| 553 new TypedSelector(type, getter), | |
| 554 universe.fieldGetters); | |
| 555 }); | |
| 556 } | |
| 557 | |
| 558 void registerFieldSetter(SourceString setterName, | |
| 559 LibraryElement library, | |
| 560 DartType type) { | |
| 561 task.measure(() { | |
| 562 Selector setter = new Selector.setter(setterName, library); | |
| 563 registerNewSelector(setterName, | |
| 564 new TypedSelector(type, setter), | |
| 565 universe.fieldSetters); | |
| 566 }); | |
| 567 } | |
| 568 | |
| 569 void forEach(f(WorkItem work)) { | 542 void forEach(f(WorkItem work)) { |
| 570 while(!queue.isEmpty) { | 543 while(!queue.isEmpty) { |
| 571 // TODO(johnniwinther): Find an optimal process order for codegen. | 544 // TODO(johnniwinther): Find an optimal process order for codegen. |
| 572 f(queue.removeLast()); | 545 f(queue.removeLast()); |
| 573 } | 546 } |
| 574 } | 547 } |
| 575 | 548 |
| 576 void _logSpecificSummary(log(message)) { | 549 void _logSpecificSummary(log(message)) { |
| 577 log('Compiled ${universe.generatedCode.length} methods.'); | 550 log('Compiled ${generatedCode.length} methods.'); |
| 578 } | 551 } |
| 579 } | 552 } |
| OLD | NEW |