Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Side by Side Diff: pkg/compiler/lib/src/enqueue.dart

Issue 1424923004: Add StaticUse for more precise registration of statically known element use. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/deferred_load.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 library dart2js.enqueue; 5 library dart2js.enqueue;
6 6
7 import 'dart:collection' show 7 import 'dart:collection' show
8 Queue; 8 Queue;
9 9
10 import 'common.dart'; 10 import 'common.dart';
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 Name, 44 Name,
45 TypedElement, 45 TypedElement,
46 TypedefElement; 46 TypedefElement;
47 import 'js/js.dart' as js; 47 import 'js/js.dart' as js;
48 import 'native/native.dart' as native; 48 import 'native/native.dart' as native;
49 import 'types/types.dart' show 49 import 'types/types.dart' show
50 TypeMaskStrategy; 50 TypeMaskStrategy;
51 import 'universe/selector.dart' show 51 import 'universe/selector.dart' show
52 Selector; 52 Selector;
53 import 'universe/universe.dart'; 53 import 'universe/universe.dart';
54 import 'universe/use.dart' show
55 StaticUse,
56 StaticUseKind;
54 import 'universe/world_impact.dart' show 57 import 'universe/world_impact.dart' show
55 WorldImpact; 58 WorldImpact;
56 import 'util/util.dart' show 59 import 'util/util.dart' show
57 Link, 60 Link,
58 Setlet; 61 Setlet;
59 62
60 typedef ItemCompilationContext ItemCompilationContextCreator(); 63 typedef ItemCompilationContext ItemCompilationContextCreator();
61 64
62 class EnqueueTask extends CompilerTask { 65 class EnqueueTask extends CompilerTask {
63 final ResolutionEnqueuer resolution; 66 final ResolutionEnqueuer resolution;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 /** 157 /**
155 * Adds [element] to the work list if it has not already been processed. 158 * Adds [element] to the work list if it has not already been processed.
156 * 159 *
157 * Returns [true] if the element was actually added to the queue. 160 * Returns [true] if the element was actually added to the queue.
158 */ 161 */
159 bool internalAddToWorkList(Element element); 162 bool internalAddToWorkList(Element element);
160 163
161 /// Apply the [worldImpact] of processing [element] to this enqueuer. 164 /// Apply the [worldImpact] of processing [element] to this enqueuer.
162 void applyImpact(Element element, WorldImpact worldImpact) { 165 void applyImpact(Element element, WorldImpact worldImpact) {
163 // TODO(johnniwinther): Optimize the application of the world impact. 166 // TODO(johnniwinther): Optimize the application of the world impact.
164 worldImpact.dynamicInvocations.forEach(registerDynamicInvocation); 167 worldImpact.dynamicUses.forEach(registerDynamicUse);
165 worldImpact.dynamicGetters.forEach(registerDynamicGetter);
166 worldImpact.dynamicSetters.forEach(registerDynamicSetter);
167 worldImpact.staticUses.forEach(registerStaticUse); 168 worldImpact.staticUses.forEach(registerStaticUse);
168 worldImpact.instantiatedTypes.forEach(registerInstantiatedType); 169 worldImpact.instantiatedTypes.forEach(registerInstantiatedType);
169 worldImpact.isChecks.forEach(registerIsCheck); 170 worldImpact.isChecks.forEach(registerIsCheck);
170 worldImpact.asCasts.forEach(registerIsCheck); 171 worldImpact.asCasts.forEach(registerIsCheck);
171 if (compiler.enableTypeAssertions) { 172 if (compiler.enableTypeAssertions) {
172 worldImpact.checkedModeChecks.forEach(registerIsCheck); 173 worldImpact.checkedModeChecks.forEach(registerIsCheck);
173 } 174 }
174 worldImpact.onCatchTypes.forEach(registerIsCheck); 175 worldImpact.onCatchTypes.forEach(registerIsCheck);
175 worldImpact.closurizedFunctions.forEach(registerGetOfStaticFunction);
176 worldImpact.closures.forEach(registerClosure); 176 worldImpact.closures.forEach(registerClosure);
177 } 177 }
178 178
179 // TODO(johnniwinther): Remove the need for passing the [registry].
180 void registerInstantiatedType(InterfaceType type, 179 void registerInstantiatedType(InterfaceType type,
181 {bool mirrorUsage: false}) { 180 {bool mirrorUsage: false}) {
182 task.measure(() { 181 task.measure(() {
183 ClassElement cls = type.element; 182 ClassElement cls = type.element;
184 cls.ensureResolved(resolution); 183 cls.ensureResolved(resolution);
185 universe.registerTypeInstantiation( 184 universe.registerTypeInstantiation(
186 type, 185 type,
187 isNative: compiler.backend.isNative(cls), 186 isNative: compiler.backend.isNative(cls),
188 byMirrors: mirrorUsage, 187 byMirrors: mirrorUsage,
189 onImplemented: (ClassElement cls) { 188 onImplemented: (ClassElement cls) {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 superclass, this, compiler.globalDependencies); 338 superclass, this, compiler.globalDependencies);
340 } 339 }
341 340
342 while (cls != null) { 341 while (cls != null) {
343 processClass(cls); 342 processClass(cls);
344 cls = cls.superclass; 343 cls = cls.superclass;
345 } 344 }
346 }); 345 });
347 } 346 }
348 347
349 void registerInvocation(UniverseSelector selector) { 348 void registerDynamicUse(UniverseSelector selector) {
350 task.measure(() { 349 task.measure(() {
351 if (universe.registerInvocation(selector)) { 350 if (universe.registerDynamicUse(selector)) {
352 handleUnseenSelector(selector); 351 handleUnseenSelector(selector);
353 } 352 }
354 }); 353 });
355 }
356
357 void registerInvokedGetter(UniverseSelector selector) {
358 task.measure(() {
359 if (universe.registerInvokedGetter(selector)) {
360 handleUnseenSelector(selector);
361 }
362 });
363 }
364
365 void registerInvokedSetter(UniverseSelector selector) {
366 task.measure(() {
367 if (universe.registerInvokedSetter(selector)) {
368 handleUnseenSelector(selector);
369 }
370 });
371 } 354 }
372 355
373 /** 356 /**
374 * Decides whether an element should be included to satisfy requirements 357 * Decides whether an element should be included to satisfy requirements
375 * of the mirror system. [includedEnclosing] provides a hint whether the 358 * of the mirror system. [includedEnclosing] provides a hint whether the
376 * enclosing element was included. 359 * enclosing element was included.
377 * 360 *
378 * The actual implementation depends on the current compiler phase. 361 * The actual implementation depends on the current compiler phase.
379 */ 362 */
380 bool shouldIncludeElementDueToMirrors(Element element, 363 bool shouldIncludeElementDueToMirrors(Element element,
(...skipping 13 matching lines...) Expand all
394 bool enclosingWasIncluded) { 377 bool enclosingWasIncluded) {
395 if (shouldIncludeElementDueToMirrors(ctor, 378 if (shouldIncludeElementDueToMirrors(ctor,
396 includedEnclosing: enclosingWasIncluded)) { 379 includedEnclosing: enclosingWasIncluded)) {
397 logEnqueueReflectiveAction(ctor); 380 logEnqueueReflectiveAction(ctor);
398 ClassElement cls = ctor.declaration.enclosingClass; 381 ClassElement cls = ctor.declaration.enclosingClass;
399 compiler.backend.registerInstantiatedType( 382 compiler.backend.registerInstantiatedType(
400 cls.rawType, 383 cls.rawType,
401 this, 384 this,
402 compiler.mirrorDependencies, 385 compiler.mirrorDependencies,
403 mirrorUsage: true); 386 mirrorUsage: true);
404 registerStaticUse(ctor.declaration); 387 registerStaticUse(new StaticUse.foreignUse(ctor.declaration));
405 } 388 }
406 } 389 }
407 390
408 /// Enqeue the member [element] if it is required for reflection. 391 /// Enqeue the member [element] if it is required for reflection.
409 /// 392 ///
410 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 393 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
411 /// needed for reflection. 394 /// needed for reflection.
412 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { 395 void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) {
413 if (shouldIncludeElementDueToMirrors(element, 396 if (shouldIncludeElementDueToMirrors(element,
414 includedEnclosing: enclosingWasIncluded)) { 397 includedEnclosing: enclosingWasIncluded)) {
415 logEnqueueReflectiveAction(element); 398 logEnqueueReflectiveAction(element);
416 if (element.isTypedef) { 399 if (element.isTypedef) {
417 TypedefElement typedef = element; 400 TypedefElement typedef = element;
418 typedef.ensureResolved(resolution); 401 typedef.ensureResolved(resolution);
419 compiler.world.allTypedefs.add(element); 402 compiler.world.allTypedefs.add(element);
420 } else if (Elements.isStaticOrTopLevel(element)) { 403 } else if (Elements.isStaticOrTopLevel(element)) {
421 registerStaticUse(element.declaration); 404 registerStaticUse(new StaticUse.foreignUse(element.declaration));
422 } else if (element.isInstanceMember) { 405 } else if (element.isInstanceMember) {
423 // We need to enqueue all members matching this one in subclasses, as 406 // We need to enqueue all members matching this one in subclasses, as
424 // well. 407 // well.
425 // TODO(herhut): Use TypedSelector.subtype for enqueueing 408 // TODO(herhut): Use TypedSelector.subtype for enqueueing
426 UniverseSelector selector = new UniverseSelector( 409 UniverseSelector selector = new UniverseSelector(
427 new Selector.fromElement(element), null); 410 new Selector.fromElement(element), null);
428 registerSelectorUse(selector); 411 registerDynamicUse(selector);
429 if (element.isField) { 412 if (element.isField) {
430 UniverseSelector selector = new UniverseSelector( 413 UniverseSelector selector = new UniverseSelector(
431 new Selector.setter(new Name( 414 new Selector.setter(new Name(
432 element.name, element.library, isSetter: true)), null); 415 element.name, element.library, isSetter: true)), null);
433 registerInvokedSetter(selector); 416 registerDynamicUse(selector);
434 } 417 }
435 } 418 }
436 } 419 }
437 } 420 }
438 421
439 /// Enqeue the member [element] if it is required for reflection. 422 /// Enqeue the member [element] if it is required for reflection.
440 /// 423 ///
441 /// [enclosingWasIncluded] provides a hint whether the enclosing element was 424 /// [enclosingWasIncluded] provides a hint whether the enclosing element was
442 /// needed for reflection. 425 /// needed for reflection.
443 void enqueueReflectiveElementsInClass(ClassElement cls, 426 void enqueueReflectiveElementsInClass(ClassElement cls,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 552
570 processInstanceMembers(String n, bool f(Element e)) { 553 processInstanceMembers(String n, bool f(Element e)) {
571 processSet(instanceMembersByName, n, f); 554 processSet(instanceMembersByName, n, f);
572 } 555 }
573 556
574 processInstanceFunctions(String n, bool f(Element e)) { 557 processInstanceFunctions(String n, bool f(Element e)) {
575 processSet(instanceFunctionsByName, n, f); 558 processSet(instanceFunctionsByName, n, f);
576 } 559 }
577 560
578 void handleUnseenSelector(UniverseSelector universeSelector) { 561 void handleUnseenSelector(UniverseSelector universeSelector) {
579 strategy.processSelector(this, universeSelector); 562 strategy.processDynamicUse(this, universeSelector);
580 } 563 }
581 564
582 void handleUnseenSelectorInternal(UniverseSelector universeSelector) { 565 void handleUnseenSelectorInternal(UniverseSelector universeSelector) {
583 Selector selector = universeSelector.selector; 566 Selector selector = universeSelector.selector;
584 String methodName = selector.name; 567 String methodName = selector.name;
585 processInstanceMembers(methodName, (Element member) { 568 processInstanceMembers(methodName, (Element member) {
586 if (universeSelector.appliesUnnamed(member, compiler.world)) { 569 if (universeSelector.appliesUnnamed(member, compiler.world)) {
587 if (member.isFunction && selector.isGetter) { 570 if (member.isFunction && selector.isGetter) {
588 registerClosurizedMember(member); 571 registerClosurizedMember(member);
589 } 572 }
(...skipping 29 matching lines...) Expand all
619 return false; 602 return false;
620 }); 603 });
621 } 604 }
622 } 605 }
623 606
624 /** 607 /**
625 * Documentation wanted -- johnniwinther 608 * Documentation wanted -- johnniwinther
626 * 609 *
627 * Invariant: [element] must be a declaration element. 610 * Invariant: [element] must be a declaration element.
628 */ 611 */
629 void registerStaticUse(Element element) { 612 void registerStaticUse(StaticUse staticUse) {
630 if (element == null) return; 613 strategy.processStaticUse(this, staticUse);
631 strategy.processStaticUse(this, element);
632 } 614 }
633 615
634 void registerStaticUseInternal(Element element) { 616 void registerStaticUseInternal(StaticUse staticUse) {
617 Element element = staticUse.element;
635 assert(invariant(element, element.isDeclaration, 618 assert(invariant(element, element.isDeclaration,
636 message: "Element ${element} is not the declaration.")); 619 message: "Element ${element} is not the declaration."));
637 if (Elements.isStaticOrTopLevel(element) && element.isField) { 620 universe.registerStaticUse(staticUse);
638 universe.registerStaticFieldUse(element); 621 compiler.backend.registerStaticUse(element, this);
622 bool addElement = true;
623 switch (staticUse.kind) {
624 case StaticUseKind.STATIC_TEAR_OFF:
625 compiler.backend.registerGetOfStaticFunction(this);
626 break;
627 case StaticUseKind.FIELD_GET:
628 case StaticUseKind.FIELD_SET:
629 // TODO(johnniwinther): Avoid this. Currently [FIELD_GET] and
630 // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue.
631 addElement = false;
632 break;
633 case StaticUseKind.SUPER_TEAR_OFF:
634 case StaticUseKind.GENERAL:
635 break;
639 } 636 }
640 addToWorkList(element); 637 if (addElement) {
641 compiler.backend.registerStaticUse(element, this); 638 addToWorkList(element);
642 }
643
644 void registerGetOfStaticFunction(FunctionElement element) {
645 registerStaticUse(element);
646 compiler.backend.registerGetOfStaticFunction(this);
647 universe.staticFunctionsNeedingGetter.add(element);
648 }
649
650 void registerDynamicInvocation(UniverseSelector selector) {
651 assert(selector != null);
652 registerInvocation(selector);
653 }
654
655 void registerSelectorUse(UniverseSelector universeSelector) {
656 if (universeSelector.selector.isGetter) {
657 registerInvokedGetter(universeSelector);
658 } else if (universeSelector.selector.isSetter) {
659 registerInvokedSetter(universeSelector);
660 } else {
661 registerInvocation(universeSelector);
662 } 639 }
663 } 640 }
664 641
665 void registerDynamicGetter(UniverseSelector selector) {
666 registerInvokedGetter(selector);
667 }
668
669 void registerDynamicSetter(UniverseSelector selector) {
670 registerInvokedSetter(selector);
671 }
672
673 void registerGetterForSuperMethod(Element element) {
674 universe.methodsNeedingSuperGetter.add(element);
675 }
676
677 void registerFieldGetter(Element element) {
678 universe.fieldGetters.add(element);
679 }
680
681 void registerFieldSetter(Element element) {
682 universe.fieldSetters.add(element);
683 }
684
685 void registerIsCheck(DartType type) { 642 void registerIsCheck(DartType type) {
686 type = universe.registerIsCheck(type, compiler); 643 type = universe.registerIsCheck(type, compiler);
687 // Even in checked mode, type annotations for return type and argument 644 // Even in checked mode, type annotations for return type and argument
688 // types do not imply type checks, so there should never be a check 645 // types do not imply type checks, so there should never be a check
689 // against the type variable of a typedef. 646 // against the type variable of a typedef.
690 assert(!type.isTypeVariable || 647 assert(!type.isTypeVariable ||
691 !type.element.enclosingElement.isTypedef); 648 !type.element.enclosingElement.isTypedef);
692 } 649 }
693 650
694 void registerCallMethodWithFreeTypeVariables(Element element) { 651 void registerCallMethodWithFreeTypeVariables(Element element) {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 } 986 }
1030 987
1031 /// Strategy used by the enqueuer to populate the world. 988 /// Strategy used by the enqueuer to populate the world.
1032 // TODO(johnniwinther): Merge this interface with [QueueFilter]. 989 // TODO(johnniwinther): Merge this interface with [QueueFilter].
1033 class EnqueuerStrategy { 990 class EnqueuerStrategy {
1034 const EnqueuerStrategy(); 991 const EnqueuerStrategy();
1035 992
1036 /// Process a class instantiated in live code. 993 /// Process a class instantiated in live code.
1037 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {} 994 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {}
1038 995
1039 /// Process an element statically accessed in live code. 996 /// Process a static use of and element in live code.
1040 void processStaticUse(Enqueuer enqueuer, Element element) {} 997 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {}
1041 998
1042 /// Process a selector for a call site in live code. 999 /// Process a selector for a call site in live code.
1043 void processSelector(Enqueuer enqueuer, UniverseSelector selector) {} 1000 void processDynamicUse(Enqueuer enqueuer, UniverseSelector dynamicUse) {}
1044 } 1001 }
1045 1002
1046 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy { 1003 class TreeShakingEnqueuerStrategy implements EnqueuerStrategy {
1047 const TreeShakingEnqueuerStrategy(); 1004 const TreeShakingEnqueuerStrategy();
1048 1005
1049 @override 1006 @override
1050 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) { 1007 void processInstantiatedClass(Enqueuer enqueuer, ClassElement cls) {
1051 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember); 1008 cls.implementation.forEachMember(enqueuer.processInstantiatedClassMember);
1052 } 1009 }
1053 1010
1054 @override 1011 @override
1055 void processStaticUse(Enqueuer enqueuer, Element element) { 1012 void processStaticUse(Enqueuer enqueuer, StaticUse staticUse) {
1056 enqueuer.registerStaticUseInternal(element); 1013 enqueuer.registerStaticUseInternal(staticUse);
1057 } 1014 }
1058 1015
1059 @override 1016 @override
1060 void processSelector(Enqueuer enqueuer, UniverseSelector selector) { 1017 void processDynamicUse(Enqueuer enqueuer, UniverseSelector dynamicUse) {
1061 enqueuer.handleUnseenSelectorInternal(selector); 1018 enqueuer.handleUnseenSelectorInternal(dynamicUse);
1062 } 1019 }
1063 } 1020 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/deferred_load.dart ('k') | pkg/compiler/lib/src/js_backend/backend.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698