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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 1809533004: Support serialization of WorldImpact (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Rebased Created 4 years, 9 months 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
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 part of js_backend; 5 part of js_backend;
6 6
7 const VERBOSE_OPTIMIZER_HINTS = false; 7 const VERBOSE_OPTIMIZER_HINTS = false;
8 8
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { 9 class JavaScriptItemCompilationContext extends ItemCompilationContext {
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>();
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 JavaScriptConstantTask constantCompilerTask; 497 JavaScriptConstantTask constantCompilerTask;
498 498
499 JavaScriptImpactTransformer impactTransformer; 499 JavaScriptImpactTransformer impactTransformer;
500 500
501 PatchResolverTask patchResolverTask; 501 PatchResolverTask patchResolverTask;
502 502
503 bool enabledNoSuchMethod = false; 503 bool enabledNoSuchMethod = false;
504 504
505 SourceInformationStrategy sourceInformationStrategy; 505 SourceInformationStrategy sourceInformationStrategy;
506 506
507 JavaScriptBackendSerialization serialization;
508
509 final NativeData nativeData = new NativeData();
510
507 final BackendHelpers helpers; 511 final BackendHelpers helpers;
508 final BackendImpacts impacts; 512 final BackendImpacts impacts;
509 513
510 JavaScriptBackend(Compiler compiler, 514 JavaScriptBackend(Compiler compiler,
511 {bool generateSourceMap: true, 515 {bool generateSourceMap: true,
512 bool useStartupEmitter: false, 516 bool useStartupEmitter: false,
513 bool useNewSourceInfo: false}) 517 bool useNewSourceInfo: false})
514 : namer = determineNamer(compiler), 518 : namer = determineNamer(compiler),
515 oneShotInterceptors = new Map<jsAst.Name, Selector>(), 519 oneShotInterceptors = new Map<jsAst.Name, Selector>(),
516 interceptedElements = new Map<String, Set<Element>>(), 520 interceptedElements = new Map<String, Set<Element>>(),
(...skipping 18 matching lines...) Expand all
535 jsInteropAnalysis = new JsInteropAnalysis(this); 539 jsInteropAnalysis = new JsInteropAnalysis(this);
536 540
537 noSuchMethodRegistry = new NoSuchMethodRegistry(this); 541 noSuchMethodRegistry = new NoSuchMethodRegistry(this);
538 constantCompilerTask = new JavaScriptConstantTask(compiler); 542 constantCompilerTask = new JavaScriptConstantTask(compiler);
539 impactTransformer = new JavaScriptImpactTransformer(this); 543 impactTransformer = new JavaScriptImpactTransformer(this);
540 patchResolverTask = new PatchResolverTask(compiler); 544 patchResolverTask = new PatchResolverTask(compiler);
541 functionCompiler = compiler.options.useCpsIr 545 functionCompiler = compiler.options.useCpsIr
542 ? new CpsFunctionCompiler( 546 ? new CpsFunctionCompiler(
543 compiler, this, sourceInformationStrategy) 547 compiler, this, sourceInformationStrategy)
544 : new SsaFunctionCompiler(this, sourceInformationStrategy); 548 : new SsaFunctionCompiler(this, sourceInformationStrategy);
549 serialization = new JavaScriptBackendSerialization(this);
545 } 550 }
546 551
547 ConstantSystem get constantSystem => constants.constantSystem; 552 ConstantSystem get constantSystem => constants.constantSystem;
548 553
549 DiagnosticReporter get reporter => compiler.reporter; 554 DiagnosticReporter get reporter => compiler.reporter;
550 555
551 CoreClasses get coreClasses => compiler.coreClasses; 556 CoreClasses get coreClasses => compiler.coreClasses;
552 557
553 CoreTypes get coreTypes => compiler.coreTypes; 558 CoreTypes get coreTypes => compiler.coreTypes;
554 559
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 } 598 }
594 599
595 /// The backend must *always* call this method when enqueuing an 600 /// The backend must *always* call this method when enqueuing an
596 /// element. Calls done by the backend are not seen by global 601 /// element. Calls done by the backend are not seen by global
597 /// optimizations, so they would make these optimizations unsound. 602 /// optimizations, so they would make these optimizations unsound.
598 /// Therefore we need to collect the list of helpers the backend may 603 /// Therefore we need to collect the list of helpers the backend may
599 /// use. 604 /// use.
600 // TODO(johnniwinther): Replace this with a more precise modelling; type 605 // TODO(johnniwinther): Replace this with a more precise modelling; type
601 // inference of these elements is disabled. 606 // inference of these elements is disabled.
602 Element registerBackendUse(Element element) { 607 Element registerBackendUse(Element element) {
603 if (element != null) { 608 if (element == null) return null;
604 bool registerUse = false; 609 assert(invariant(element, _isValidBackendUse(element),
605 if (element == helpers.streamIteratorConstructor || 610 message: "Backend use of $element is not allowed."));
606 element == helpers.compiler.symbolConstructor || 611 helpersUsed.add(element.declaration);
607 element == helpers.compiler.symbolValidatedConstructor || 612 if (element.isClass && element.isPatched) {
608 element == helpers.syncCompleterConstructor || 613 // Both declaration and implementation may declare fields, so we
609 element == coreClasses.symbolClass || 614 // add both to the list of helpers.
610 element == helpers.objectNoSuchMethod) { 615 helpersUsed.add(element.implementation);
611 // TODO(johnniwinther): These are valid but we could be more precise.
612 registerUse = true;
613 } else if (element.implementationLibrary.isPatch ||
614 element.library == helpers.jsHelperLibrary ||
615 element.library == helpers.interceptorsLibrary ||
616 element.library == helpers.isolateHelperLibrary) {
617 // TODO(johnniwinther): We should be more precise about these.
618 registerUse = true;
619 } else if (element == coreClasses.listClass ||
620 element == helpers.mapLiteralClass ||
621 element == coreClasses.functionClass ||
622 element == coreClasses.stringClass) {
623 // TODO(johnniwinther): Avoid these.
624 registerUse = true;
625 }
626 if (!registerUse) {
627 assert(invariant(element, false,
628 message: "Backend use of $element is not allowed."));
629 return element;
630 }
631 helpersUsed.add(element.declaration);
632 if (element.isClass && element.isPatched) {
633 // Both declaration and implementation may declare fields, so we
634 // add both to the list of helpers.
635 helpersUsed.add(element.implementation);
636 }
637 } 616 }
638 return element; 617 return element;
639 } 618 }
640 619
620 bool _isValidBackendUse(Element element) {
621 assert(invariant(element, element.isDeclaration,
622 message: ""));
623 if (element == helpers.streamIteratorConstructor ||
624 element == helpers.compiler.symbolConstructor ||
625 element == helpers.compiler.symbolValidatedConstructor ||
626 element == helpers.syncCompleterConstructor ||
627 element == coreClasses.symbolClass ||
628 element == helpers.objectNoSuchMethod) {
629 // TODO(johnniwinther): These are valid but we could be more precise.
630 return true;
631 } else if (element.implementationLibrary.isPatch ||
632 // Needed to detect deserialized injected elements, that is
633 // element declared in patch files.
634 (element.library.isPlatformLibrary &&
635 element.sourcePosition.uri.path.contains(
636 '_internal/js_runtime/lib/')) ||
637 element.library == helpers.jsHelperLibrary ||
638 element.library == helpers.interceptorsLibrary ||
639 element.library == helpers.isolateHelperLibrary) {
640 // TODO(johnniwinther): We should be more precise about these.
641 return true;
642 } else if (element == coreClasses.listClass ||
643 element == helpers.mapLiteralClass ||
644 element == coreClasses.functionClass ||
645 element == coreClasses.stringClass) {
646 // TODO(johnniwinther): Avoid these.
647 return true;
648 }
649 return false;
650 }
651
641 bool usedByBackend(Element element) { 652 bool usedByBackend(Element element) {
642 if (element.isParameter 653 if (element.isParameter
643 || element.isInitializingFormal 654 || element.isInitializingFormal
644 || element.isField) { 655 || element.isField) {
645 if (usedByBackend(element.enclosingElement)) return true; 656 if (usedByBackend(element.enclosingElement)) return true;
646 } 657 }
647 return helpersUsed.contains(element.declaration); 658 return helpersUsed.contains(element.declaration);
648 } 659 }
649 660
650 bool invokedReflectively(Element element) { 661 bool invokedReflectively(Element element) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 return !selector.isGetter && !compiler.options.hasIncrementalSupport; 716 return !selector.isGetter && !compiler.options.hasIncrementalSupport;
706 } 717 }
707 718
708 /** 719 /**
709 * Returns `true` if [member] is called from a subclass via `super`. 720 * Returns `true` if [member] is called from a subclass via `super`.
710 */ 721 */
711 bool isAliasedSuperMember(FunctionElement member) { 722 bool isAliasedSuperMember(FunctionElement member) {
712 return aliasedSuperMembers.contains(member); 723 return aliasedSuperMembers.contains(member);
713 } 724 }
714 725
715 /// The JavaScript names for elements implemented via typed JavaScript
716 /// interop.
717 Map<Element, String> jsInteropNames = <Element, String>{};
718
719 /// The JavaScript names for native JavaScript elements implemented.
720 Map<Element, String> nativeMemberName = <Element, String>{};
721
722 /// Tag info for native JavaScript classes names. See
723 /// [setNativeClassTagInfo].
724 Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{};
725
726 /// Returns `true` if [element] is explicitly marked as part of JsInterop.
727 bool _isJsInterop(Element element) {
728 return jsInteropNames.containsKey(element.declaration);
729 }
730
731 /// Returns [element] as an explicit part of JsInterop. The js interop name is
732 /// expected to be computed later.
733 void markAsJsInterop(Element element) {
734 jsInteropNames[element.declaration] = null;
735 }
736
737 /// Sets the explicit js interop [name] for [element].
738 void setJsInteropName(Element element, String name) {
739 assert(invariant(element,
740 isJsInterop(element),
741 message:
742 'Element $element is not js interop but given a js interop name.'));
743 jsInteropNames[element.declaration] = name;
744 }
745
746 /// Returns the explicit js interop name for [element].
747 String getJsInteropName(Element element) {
748 return jsInteropNames[element.declaration];
749 }
750
751 /// Returns `true` if [element] is part of JsInterop. 726 /// Returns `true` if [element] is part of JsInterop.
752 @override 727 @override
753 bool isJsInterop(Element element) { 728 bool isJsInterop(Element element) => nativeData.isJsInterop(element);
754 // An function is part of JsInterop in the following cases:
755 // * It has a jsInteropName annotation
756 // * It is external member of a class or library tagged as JsInterop.
757 if (element.isFunction || element.isConstructor || element.isAccessor) {
758 FunctionElement function = element;
759 if (!function.isExternal) return false;
760
761 if (_isJsInterop(function)) return true;
762 if (function.isClassMember) return isJsInterop(function.contextClass);
763 if (function.isTopLevel) return isJsInterop(function.library);
764 return false;
765 } else {
766 return _isJsInterop(element);
767 }
768 }
769
770 /// Returns `true` if the name of [element] is fixed for the generated
771 /// JavaScript.
772 bool hasFixedBackendName(Element element) {
773 return isJsInterop(element) ||
774 nativeMemberName.containsKey(element.declaration);
775 }
776
777 String _jsNameHelper(Element element) {
778 String jsInteropName = jsInteropNames[element.declaration];
779 assert(invariant(element,
780 !(_isJsInterop(element) && jsInteropName == null),
781 message:
782 'Element $element is js interop but js interop name has not yet '
783 'been computed.'));
784 if (jsInteropName != null && jsInteropName.isNotEmpty) {
785 return jsInteropName;
786 }
787 return element.isLibrary ? 'self' : element.name;
788 }
789
790 /// Computes the name for [element] to use in the generated JavaScript. This
791 /// is either given through a native annotation or a js interop annotation.
792 String getFixedBackendName(Element element) {
793 String name = nativeMemberName[element.declaration];
794 if (name == null && isJsInterop(element)) {
795 // If an element isJsInterop but _isJsInterop is false that means it is
796 // considered interop as the parent class is interop.
797 name = _jsNameHelper(
798 element.isConstructor ? element.enclosingClass : element);
799 nativeMemberName[element.declaration] = name;
800 }
801 return name;
802 }
803 729
804 /// Whether [element] corresponds to a native JavaScript construct either 730 /// Whether [element] corresponds to a native JavaScript construct either
805 /// through the native mechanism (`@Native(...)` or the `native` pseudo 731 /// through the native mechanism (`@Native(...)` or the `native` pseudo
806 /// keyword) which is only allowed for internal libraries or via the typed 732 /// keyword) which is only allowed for internal libraries or via the typed
807 /// JavaScriptInterop mechanism which is allowed for user libraries. 733 /// JavaScriptInterop mechanism which is allowed for user libraries.
808 @override 734 @override
809 bool isNative(Element element) { 735 bool isNative(Element element) => nativeData.isNative(element);
810 if (isJsInterop(element)) return true;
811 if (element.isClass) {
812 return nativeClassTagInfo.containsKey(element.declaration);
813 } else {
814 return nativeMemberName.containsKey(element.declaration);
815 }
816 }
817
818 /// Sets the native [name] for the member [element]. This name is used for
819 /// [element] in the generated JavaScript.
820 void setNativeMemberName(MemberElement element, String name) {
821 // TODO(johnniwinther): Avoid setting this more than once. The enqueuer
822 // might enqueue [element] several times (before processing it) and computes
823 // name on each call to `internalAddToWorkList`.
824 assert(invariant(element,
825 nativeMemberName[element.declaration] == null ||
826 nativeMemberName[element.declaration] == name,
827 message:
828 "Native member name set inconsistently on $element: "
829 "Existing name '${nativeMemberName[element.declaration]}', "
830 "new name '$name'."));
831 nativeMemberName[element.declaration] = name;
832 }
833
834 /// Sets the native tag info for [cls].
835 ///
836 /// The tag info string contains comma-separated 'words' which are either
837 /// dispatch tags (having JavaScript identifier syntax) and directives that
838 /// begin with `!`.
839 void setNativeClassTagInfo(ClassElement cls, String tagInfo) {
840 // TODO(johnniwinther): Assert that this is only called once. The memory
841 // compiler copies pre-processed elements into a new compiler through
842 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this
843 // method.
844 assert(invariant(cls,
845 nativeClassTagInfo[cls.declaration] == null ||
846 nativeClassTagInfo[cls.declaration] == tagInfo,
847 message:
848 "Native tag info set inconsistently on $cls: "
849 "Existing tag info '${nativeClassTagInfo[cls.declaration]}', "
850 "new tag info '$tagInfo'."));
851 nativeClassTagInfo[cls.declaration] = tagInfo;
852 }
853
854 /// Returns the list of native tag words for [cls].
855 List<String> getNativeTagsOfClassRaw(ClassElement cls) {
856 String quotedName = nativeClassTagInfo[cls.declaration];
857 return quotedName.substring(1, quotedName.length - 1).split(',');
858 }
859
860 /// Returns the list of non-directive native tag words for [cls].
861 List<String> getNativeTagsOfClass(ClassElement cls) {
862 return getNativeTagsOfClassRaw(cls).where(
863 (s) => !s.startsWith('!')).toList();
864 }
865
866 /// Returns `true` if [cls] has a `!nonleaf` tag word.
867 bool hasNativeTagsForcedNonLeaf(ClassElement cls) {
868 return getNativeTagsOfClassRaw(cls).contains('!nonleaf');
869 }
870 736
871 bool isNativeOrExtendsNative(ClassElement element) { 737 bool isNativeOrExtendsNative(ClassElement element) {
872 if (element == null) return false; 738 if (element == null) return false;
873 if (isNative(element) || isJsInterop(element)) { 739 if (isNative(element) || isJsInterop(element)) {
874 return true; 740 return true;
875 } 741 }
876 assert(element.isResolved); 742 assert(element.isResolved);
877 return isNativeOrExtendsNative(element.superclass); 743 return isNativeOrExtendsNative(element.superclass);
878 } 744 }
879 745
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 868
1003 void validateInterceptorImplementsAllObjectMethods( 869 void validateInterceptorImplementsAllObjectMethods(
1004 ClassElement interceptorClass) { 870 ClassElement interceptorClass) {
1005 if (interceptorClass == null) return; 871 if (interceptorClass == null) return;
1006 interceptorClass.ensureResolved(resolution); 872 interceptorClass.ensureResolved(resolution);
1007 coreClasses.objectClass.forEachMember((_, Element member) { 873 coreClasses.objectClass.forEachMember((_, Element member) {
1008 if (member.isGenerativeConstructor) return; 874 if (member.isGenerativeConstructor) return;
1009 Element interceptorMember = interceptorClass.lookupMember(member.name); 875 Element interceptorMember = interceptorClass.lookupMember(member.name);
1010 // Interceptors must override all Object methods due to calling convention 876 // Interceptors must override all Object methods due to calling convention
1011 // differences. 877 // differences.
1012 assert(interceptorMember.enclosingClass == interceptorClass); 878 assert(invariant(
879 interceptorMember,
880 interceptorMember.enclosingClass == interceptorClass,
881 message:
882 "Member ${member.name} not overridden in ${interceptorClass}. "
883 "Found $interceptorMember from "
884 "${interceptorMember.enclosingClass}."));
1013 }); 885 });
1014 } 886 }
1015 887
1016 void addInterceptorsForNativeClassMembers( 888 void addInterceptorsForNativeClassMembers(
1017 ClassElement cls, Enqueuer enqueuer) { 889 ClassElement cls, Enqueuer enqueuer) {
1018 if (enqueuer.isResolutionQueue) { 890 if (enqueuer.isResolutionQueue) {
1019 cls.ensureResolved(resolution); 891 cls.ensureResolved(resolution);
1020 cls.forEachMember((ClassElement classElement, Element member) { 892 cls.forEachMember((ClassElement classElement, Element member) {
1021 if (member.name == Identifiers.call) { 893 if (member.name == Identifiers.call) {
1022 reporter.reportErrorMessage( 894 reporter.reportErrorMessage(
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 compiler.globalDependencies); 1074 compiler.globalDependencies);
1203 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); 1075 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
1204 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); 1076 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
1205 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); 1077 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
1206 } else if (cls == helpers.mapLiteralClass) { 1078 } else if (cls == helpers.mapLiteralClass) {
1207 // For map literals, the dependency between the implementation class 1079 // For map literals, the dependency between the implementation class
1208 // and [Map] is not visible, so we have to add it manually. 1080 // and [Map] is not visible, so we have to add it manually.
1209 Element getFactory(String name, int arity) { 1081 Element getFactory(String name, int arity) {
1210 // The constructor is on the patch class, but dart2js unit tests don't 1082 // The constructor is on the patch class, but dart2js unit tests don't
1211 // have a patch class. 1083 // have a patch class.
1212 ClassElement implementation = cls.patch != null ? cls.patch : cls; 1084 ClassElement implementation = cls.implementation;
1213 ConstructorElement ctor = implementation.lookupConstructor(name); 1085 ConstructorElement ctor = implementation.lookupConstructor(name);
1214 if (ctor == null || 1086 if (ctor == null ||
1215 (Name.isPrivateName(name) && 1087 (Name.isPrivateName(name) &&
1216 ctor.library != helpers.mapLiteralClass.library)) { 1088 ctor.library != helpers.mapLiteralClass.library)) {
1217 reporter.internalError( 1089 reporter.internalError(
1218 helpers.mapLiteralClass, 1090 helpers.mapLiteralClass,
1219 "Map literal class ${helpers.mapLiteralClass} missing " 1091 "Map literal class ${helpers.mapLiteralClass} missing "
1220 "'$name' constructor" 1092 "'$name' constructor"
1221 " ${helpers.mapLiteralClass.constructors}"); 1093 " ${helpers.mapLiteralClass.constructors}");
1222 } 1094 }
1223 return ctor; 1095 return ctor;
1224 } 1096 }
1225 Element getMember(String name) { 1097 Element getMember(String name) {
1226 // The constructor is on the patch class, but dart2js unit tests don't 1098 // The constructor is on the patch class, but dart2js unit tests don't
1227 // have a patch class. 1099 // have a patch class.
1228 ClassElement implementation = cls.patch != null ? cls.patch : cls; 1100 ClassElement implementation = cls.implementation;
1229 Element element = implementation.lookupLocalMember(name); 1101 Element element = implementation.lookupLocalMember(name);
1230 if (element == null || !element.isFunction || !element.isStatic) { 1102 if (element == null || !element.isFunction || !element.isStatic) {
1231 reporter.internalError(helpers.mapLiteralClass, 1103 reporter.internalError(helpers.mapLiteralClass,
1232 "Map literal class ${helpers.mapLiteralClass} missing " 1104 "Map literal class ${helpers.mapLiteralClass} missing "
1233 "'$name' static member function"); 1105 "'$name' static member function");
1234 } 1106 }
1235 return element; 1107 return element;
1236 } 1108 }
1237 helpers.mapLiteralConstructor = getFactory('_literal', 1); 1109 helpers.mapLiteralConstructor = getFactory('_literal', 1);
1238 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); 1110 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
(...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 @override 2537 @override
2666 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { 2538 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) {
2667 String patchLocation = _patchLocations[libraryName]; 2539 String patchLocation = _patchLocations[libraryName];
2668 if (patchLocation == null) return null; 2540 if (patchLocation == null) return null;
2669 return platformConfigUri.resolve(patchLocation); 2541 return platformConfigUri.resolve(patchLocation);
2670 } 2542 }
2671 2543
2672 @override 2544 @override
2673 ImpactStrategy createImpactStrategy( 2545 ImpactStrategy createImpactStrategy(
2674 {bool supportDeferredLoad: true, 2546 {bool supportDeferredLoad: true,
2675 bool supportDumpInfo: true}) { 2547 bool supportDumpInfo: true,
2548 bool supportSerialization: true}) {
2676 return new JavaScriptImpactStrategy( 2549 return new JavaScriptImpactStrategy(
2677 resolution, 2550 resolution,
2678 compiler.dumpInfoTask, 2551 compiler.dumpInfoTask,
2679 supportDeferredLoad: supportDeferredLoad, 2552 supportDeferredLoad: supportDeferredLoad,
2680 supportDumpInfo: supportDumpInfo); 2553 supportDumpInfo: supportDumpInfo,
2554 supportSerialization: supportSerialization);
2681 } 2555 }
2682 } 2556 }
2683 2557
2684 /// Handling of special annotations for tests. 2558 /// Handling of special annotations for tests.
2685 class Annotations { 2559 class Annotations {
2686 static final Uri PACKAGE_EXPECT = 2560 static final Uri PACKAGE_EXPECT =
2687 new Uri(scheme: 'package', path: 'expect/expect.dart'); 2561 new Uri(scheme: 'package', path: 'expect/expect.dart');
2688 2562
2689 final Compiler compiler; 2563 final Compiler compiler;
2690 2564
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
3146 final Element annotatedElement; 3020 final Element annotatedElement;
3147 3021
3148 const Dependency(this.constant, this.annotatedElement); 3022 const Dependency(this.constant, this.annotatedElement);
3149 } 3023 }
3150 3024
3151 class JavaScriptImpactStrategy extends ImpactStrategy { 3025 class JavaScriptImpactStrategy extends ImpactStrategy {
3152 final Resolution resolution; 3026 final Resolution resolution;
3153 final DumpInfoTask dumpInfoTask; 3027 final DumpInfoTask dumpInfoTask;
3154 final bool supportDeferredLoad; 3028 final bool supportDeferredLoad;
3155 final bool supportDumpInfo; 3029 final bool supportDumpInfo;
3030 final bool supportSerialization;
3156 3031
3157 JavaScriptImpactStrategy(this.resolution, 3032 JavaScriptImpactStrategy(this.resolution,
3158 this.dumpInfoTask, 3033 this.dumpInfoTask,
3159 {this.supportDeferredLoad, 3034 {this.supportDeferredLoad,
3160 this.supportDumpInfo}); 3035 this.supportDumpInfo,
3036 this.supportSerialization});
3161 3037
3162 @override 3038 @override
3163 void visitImpact(Element element, 3039 void visitImpact(Element element,
3164 WorldImpact impact, 3040 WorldImpact impact,
3165 WorldImpactVisitor visitor, 3041 WorldImpactVisitor visitor,
3166 ImpactUseCase impactUse) { 3042 ImpactUseCase impactUse) {
3167 // TODO(johnniwinther): Compute the application strategy once for each use. 3043 // TODO(johnniwinther): Compute the application strategy once for each use.
3168 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { 3044 if (impactUse == ResolutionEnqueuer.IMPACT_USE) {
3169 if (supportDeferredLoad) { 3045 if (supportDeferredLoad || supportSerialization) {
3170 impact.apply(visitor); 3046 impact.apply(visitor);
3171 } else { 3047 } else {
3172 impact.apply(visitor); 3048 impact.apply(visitor);
3173 resolution.uncacheWorldImpact(element); 3049 resolution.uncacheWorldImpact(element);
3174 } 3050 }
3175 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { 3051 } else if (impactUse == DeferredLoadTask.IMPACT_USE) {
3176 impact.apply(visitor); 3052 impact.apply(visitor);
3177 // Impacts are uncached globally in [onImpactUsed]. 3053 // Impacts are uncached globally in [onImpactUsed].
3178 } else if (impactUse == DumpInfoTask.IMPACT_USE) { 3054 } else if (impactUse == DumpInfoTask.IMPACT_USE) {
3179 impact.apply(visitor); 3055 impact.apply(visitor);
3180 dumpInfoTask.unregisterImpact(element); 3056 dumpInfoTask.unregisterImpact(element);
3181 } else { 3057 } else {
3182 impact.apply(visitor); 3058 impact.apply(visitor);
3183 } 3059 }
3184 } 3060 }
3185 3061
3186 @override 3062 @override
3187 void onImpactUsed(ImpactUseCase impactUse) { 3063 void onImpactUsed(ImpactUseCase impactUse) {
3188 if (impactUse == DeferredLoadTask.IMPACT_USE) { 3064 if (impactUse == DeferredLoadTask.IMPACT_USE &&
3065 !supportSerialization) {
3066 // TODO(johnniwinther): Allow emptying when serialization has been
3067 // performed.
3189 resolution.emptyCache(); 3068 resolution.emptyCache();
3190 } 3069 }
3191 } 3070 }
3192 } 3071 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart ('k') | pkg/compiler/lib/src/js_backend/backend_serialization.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698