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

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: 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.useCpsIr 545 functionCompiler = compiler.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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 bool registerUse = false; 609 bool registerUse = false;
605 if (element == helpers.streamIteratorConstructor || 610 if (element == helpers.streamIteratorConstructor ||
606 element == helpers.compiler.symbolConstructor || 611 element == helpers.compiler.symbolConstructor ||
607 element == helpers.compiler.symbolValidatedConstructor || 612 element == helpers.compiler.symbolValidatedConstructor ||
608 element == helpers.syncCompleterConstructor || 613 element == helpers.syncCompleterConstructor ||
609 element == coreClasses.symbolClass || 614 element == coreClasses.symbolClass ||
610 element == helpers.objectNoSuchMethod) { 615 element == helpers.objectNoSuchMethod) {
611 // TODO(johnniwinther): These are valid but we could be more precise. 616 // TODO(johnniwinther): These are valid but we could be more precise.
612 registerUse = true; 617 registerUse = true;
613 } else if (element.implementationLibrary.isPatch || 618 } else if (element.implementationLibrary.isPatch ||
619 // Needed to detect deserialized patch elements.
620 (element.library.isPlatformLibrary &&
621 element.sourcePosition.uri.path.contains('_internal/js_runtime /lib/')) ||
Siggi Cherem (dart-lang) 2016/03/16 23:40:14 nit: 80 (same below)
Siggi Cherem (dart-lang) 2016/03/16 23:40:14 do we have guarantees that the uri will contain th
Johnni Winther 2016/03/17 10:49:37 Done.
Johnni Winther 2016/03/17 10:49:37 This is not for patch elements (we must register t
614 element.library == helpers.jsHelperLibrary || 622 element.library == helpers.jsHelperLibrary ||
615 element.library == helpers.interceptorsLibrary || 623 element.library == helpers.interceptorsLibrary ||
616 element.library == helpers.isolateHelperLibrary) { 624 element.library == helpers.isolateHelperLibrary) {
617 // TODO(johnniwinther): We should be more precise about these. 625 // TODO(johnniwinther): We should be more precise about these.
618 registerUse = true; 626 registerUse = true;
619 } else if (element == coreClasses.listClass || 627 } else if (element == coreClasses.listClass ||
620 element == helpers.mapLiteralClass || 628 element == helpers.mapLiteralClass ||
621 element == coreClasses.functionClass || 629 element == coreClasses.functionClass ||
622 element == coreClasses.stringClass) { 630 element == coreClasses.stringClass) {
623 // TODO(johnniwinther): Avoid these. 631 // TODO(johnniwinther): Avoid these.
624 registerUse = true; 632 registerUse = true;
625 } 633 }
626 if (!registerUse) { 634 if (!registerUse) {
627 assert(invariant(element, false, 635 assert(invariant(element, false,
Siggi Cherem (dart-lang) 2016/03/16 23:40:14 Seems like the `registerUse` logic is mainly for t
Johnni Winther 2016/03/17 10:49:37 Good point. Done.
628 message: "Backend use of $element is not allowed.")); 636 message: "Backend use of $element is not allowed ${element.sourcePos ition}."));
629 return element; 637 return element;
630 } 638 }
631 helpersUsed.add(element.declaration); 639 helpersUsed.add(element.declaration);
632 if (element.isClass && element.isPatched) { 640 if (element.isClass && element.isPatched) {
633 // Both declaration and implementation may declare fields, so we 641 // Both declaration and implementation may declare fields, so we
634 // add both to the list of helpers. 642 // add both to the list of helpers.
635 helpersUsed.add(element.implementation); 643 helpersUsed.add(element.implementation);
636 } 644 }
637 } 645 }
638 return element; 646 return element;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 return !selector.isGetter && !compiler.hasIncrementalSupport; 713 return !selector.isGetter && !compiler.hasIncrementalSupport;
706 } 714 }
707 715
708 /** 716 /**
709 * Returns `true` if [member] is called from a subclass via `super`. 717 * Returns `true` if [member] is called from a subclass via `super`.
710 */ 718 */
711 bool isAliasedSuperMember(FunctionElement member) { 719 bool isAliasedSuperMember(FunctionElement member) {
712 return aliasedSuperMembers.contains(member); 720 return aliasedSuperMembers.contains(member);
713 } 721 }
714 722
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. 723 /// Returns `true` if [element] is part of JsInterop.
752 @override 724 @override
753 bool isJsInterop(Element element) { 725 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 726
804 /// Whether [element] corresponds to a native JavaScript construct either 727 /// Whether [element] corresponds to a native JavaScript construct either
805 /// through the native mechanism (`@Native(...)` or the `native` pseudo 728 /// through the native mechanism (`@Native(...)` or the `native` pseudo
806 /// keyword) which is only allowed for internal libraries or via the typed 729 /// keyword) which is only allowed for internal libraries or via the typed
807 /// JavaScriptInterop mechanism which is allowed for user libraries. 730 /// JavaScriptInterop mechanism which is allowed for user libraries.
808 @override 731 @override
809 bool isNative(Element element) { 732 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 733
871 bool isNativeOrExtendsNative(ClassElement element) { 734 bool isNativeOrExtendsNative(ClassElement element) {
872 if (element == null) return false; 735 if (element == null) return false;
873 if (isNative(element) || isJsInterop(element)) { 736 if (isNative(element) || isJsInterop(element)) {
874 return true; 737 return true;
875 } 738 }
876 assert(element.isResolved); 739 assert(element.isResolved);
877 return isNativeOrExtendsNative(element.superclass); 740 return isNativeOrExtendsNative(element.superclass);
878 } 741 }
879 742
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 865
1003 void validateInterceptorImplementsAllObjectMethods( 866 void validateInterceptorImplementsAllObjectMethods(
1004 ClassElement interceptorClass) { 867 ClassElement interceptorClass) {
1005 if (interceptorClass == null) return; 868 if (interceptorClass == null) return;
1006 interceptorClass.ensureResolved(resolution); 869 interceptorClass.ensureResolved(resolution);
1007 coreClasses.objectClass.forEachMember((_, Element member) { 870 coreClasses.objectClass.forEachMember((_, Element member) {
1008 if (member.isGenerativeConstructor) return; 871 if (member.isGenerativeConstructor) return;
1009 Element interceptorMember = interceptorClass.lookupMember(member.name); 872 Element interceptorMember = interceptorClass.lookupMember(member.name);
1010 // Interceptors must override all Object methods due to calling convention 873 // Interceptors must override all Object methods due to calling convention
1011 // differences. 874 // differences.
1012 assert(interceptorMember.enclosingClass == interceptorClass); 875 assert(invariant(
876 interceptorMember,
877 interceptorMember.enclosingClass == interceptorClass,
878 message:
879 "Member ${member.name} not overridden in ${interceptorClass}. "
880 "Found $interceptorMember from "
881 "${interceptorMember.enclosingClass}."));
1013 }); 882 });
1014 } 883 }
1015 884
1016 void addInterceptorsForNativeClassMembers( 885 void addInterceptorsForNativeClassMembers(
1017 ClassElement cls, Enqueuer enqueuer) { 886 ClassElement cls, Enqueuer enqueuer) {
1018 if (enqueuer.isResolutionQueue) { 887 if (enqueuer.isResolutionQueue) {
1019 cls.ensureResolved(resolution); 888 cls.ensureResolved(resolution);
1020 cls.forEachMember((ClassElement classElement, Element member) { 889 cls.forEachMember((ClassElement classElement, Element member) {
1021 if (member.name == Identifiers.call) { 890 if (member.name == Identifiers.call) {
1022 reporter.reportErrorMessage( 891 reporter.reportErrorMessage(
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 compiler.globalDependencies); 1071 compiler.globalDependencies);
1203 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); 1072 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
1204 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); 1073 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
1205 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); 1074 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
1206 } else if (cls == helpers.mapLiteralClass) { 1075 } else if (cls == helpers.mapLiteralClass) {
1207 // For map literals, the dependency between the implementation class 1076 // For map literals, the dependency between the implementation class
1208 // and [Map] is not visible, so we have to add it manually. 1077 // and [Map] is not visible, so we have to add it manually.
1209 Element getFactory(String name, int arity) { 1078 Element getFactory(String name, int arity) {
1210 // The constructor is on the patch class, but dart2js unit tests don't 1079 // The constructor is on the patch class, but dart2js unit tests don't
1211 // have a patch class. 1080 // have a patch class.
1212 ClassElement implementation = cls.patch != null ? cls.patch : cls; 1081 ClassElement implementation = cls.implementation;
1213 ConstructorElement ctor = implementation.lookupConstructor(name); 1082 ConstructorElement ctor = implementation.lookupConstructor(name);
1214 if (ctor == null || 1083 if (ctor == null ||
1215 (Name.isPrivateName(name) && 1084 (Name.isPrivateName(name) &&
1216 ctor.library != helpers.mapLiteralClass.library)) { 1085 ctor.library != helpers.mapLiteralClass.library)) {
1217 reporter.internalError( 1086 reporter.internalError(
1218 helpers.mapLiteralClass, 1087 helpers.mapLiteralClass,
1219 "Map literal class ${helpers.mapLiteralClass} missing " 1088 "Map literal class ${helpers.mapLiteralClass} missing "
1220 "'$name' constructor" 1089 "'$name' constructor"
1221 " ${helpers.mapLiteralClass.constructors}"); 1090 " ${helpers.mapLiteralClass.constructors}");
1222 } 1091 }
1223 return ctor; 1092 return ctor;
1224 } 1093 }
1225 Element getMember(String name) { 1094 Element getMember(String name) {
1226 // The constructor is on the patch class, but dart2js unit tests don't 1095 // The constructor is on the patch class, but dart2js unit tests don't
1227 // have a patch class. 1096 // have a patch class.
1228 ClassElement implementation = cls.patch != null ? cls.patch : cls; 1097 ClassElement implementation = cls.implementation;
1229 Element element = implementation.lookupLocalMember(name); 1098 Element element = implementation.lookupLocalMember(name);
1230 if (element == null || !element.isFunction || !element.isStatic) { 1099 if (element == null || !element.isFunction || !element.isStatic) {
1231 reporter.internalError(helpers.mapLiteralClass, 1100 reporter.internalError(helpers.mapLiteralClass,
1232 "Map literal class ${helpers.mapLiteralClass} missing " 1101 "Map literal class ${helpers.mapLiteralClass} missing "
1233 "'$name' static member function"); 1102 "'$name' static member function");
1234 } 1103 }
1235 return element; 1104 return element;
1236 } 1105 }
1237 helpers.mapLiteralConstructor = getFactory('_literal', 1); 1106 helpers.mapLiteralConstructor = getFactory('_literal', 1);
1238 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); 1107 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0);
(...skipping 1427 matching lines...) Expand 10 before | Expand all | Expand 10 after
2666 @override 2535 @override
2667 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) { 2536 Uri resolvePatchUri(String libraryName, Uri platformConfigUri) {
2668 String patchLocation = _patchLocations[libraryName]; 2537 String patchLocation = _patchLocations[libraryName];
2669 if (patchLocation == null) return null; 2538 if (patchLocation == null) return null;
2670 return platformConfigUri.resolve(patchLocation); 2539 return platformConfigUri.resolve(patchLocation);
2671 } 2540 }
2672 2541
2673 @override 2542 @override
2674 ImpactStrategy createImpactStrategy( 2543 ImpactStrategy createImpactStrategy(
2675 {bool supportDeferredLoad: true, 2544 {bool supportDeferredLoad: true,
2676 bool supportDumpInfo: true}) { 2545 bool supportDumpInfo: true,
2546 bool supportSerialization: true}) {
2677 return new JavaScriptImpactStrategy( 2547 return new JavaScriptImpactStrategy(
2678 resolution, 2548 resolution,
2679 compiler.dumpInfoTask, 2549 compiler.dumpInfoTask,
2680 supportDeferredLoad: supportDeferredLoad, 2550 supportDeferredLoad: supportDeferredLoad,
2681 supportDumpInfo: supportDumpInfo); 2551 supportDumpInfo: supportDumpInfo,
2552 supportSerialization: supportSerialization);
2682 } 2553 }
2683 } 2554 }
2684 2555
2685 /// Handling of special annotations for tests. 2556 /// Handling of special annotations for tests.
2686 class Annotations { 2557 class Annotations {
2687 static final Uri PACKAGE_EXPECT = 2558 static final Uri PACKAGE_EXPECT =
2688 new Uri(scheme: 'package', path: 'expect/expect.dart'); 2559 new Uri(scheme: 'package', path: 'expect/expect.dart');
2689 2560
2690 final Compiler compiler; 2561 final Compiler compiler;
2691 2562
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
3147 final Element annotatedElement; 3018 final Element annotatedElement;
3148 3019
3149 const Dependency(this.constant, this.annotatedElement); 3020 const Dependency(this.constant, this.annotatedElement);
3150 } 3021 }
3151 3022
3152 class JavaScriptImpactStrategy extends ImpactStrategy { 3023 class JavaScriptImpactStrategy extends ImpactStrategy {
3153 final Resolution resolution; 3024 final Resolution resolution;
3154 final DumpInfoTask dumpInfoTask; 3025 final DumpInfoTask dumpInfoTask;
3155 final bool supportDeferredLoad; 3026 final bool supportDeferredLoad;
3156 final bool supportDumpInfo; 3027 final bool supportDumpInfo;
3028 final bool supportSerialization;
3157 3029
3158 JavaScriptImpactStrategy(this.resolution, 3030 JavaScriptImpactStrategy(this.resolution,
3159 this.dumpInfoTask, 3031 this.dumpInfoTask,
3160 {this.supportDeferredLoad, 3032 {this.supportDeferredLoad,
3161 this.supportDumpInfo}); 3033 this.supportDumpInfo,
3034 this.supportSerialization});
3162 3035
3163 @override 3036 @override
3164 void visitImpact(Element element, 3037 void visitImpact(Element element,
3165 WorldImpact impact, 3038 WorldImpact impact,
3166 WorldImpactVisitor visitor, 3039 WorldImpactVisitor visitor,
3167 ImpactUseCase impactUse) { 3040 ImpactUseCase impactUse) {
3168 // TODO(johnniwinther): Compute the application strategy once for each use. 3041 // TODO(johnniwinther): Compute the application strategy once for each use.
3169 if (impactUse == ResolutionEnqueuer.IMPACT_USE) { 3042 if (impactUse == ResolutionEnqueuer.IMPACT_USE) {
3170 if (supportDeferredLoad) { 3043 if (supportDeferredLoad || supportSerialization) {
3171 impact.apply(visitor); 3044 impact.apply(visitor);
3172 } else { 3045 } else {
3173 impact.apply(visitor); 3046 impact.apply(visitor);
3174 resolution.uncacheWorldImpact(element); 3047 resolution.uncacheWorldImpact(element);
3175 } 3048 }
3176 } else if (impactUse == DeferredLoadTask.IMPACT_USE) { 3049 } else if (impactUse == DeferredLoadTask.IMPACT_USE) {
3177 impact.apply(visitor); 3050 impact.apply(visitor);
3178 // Impacts are uncached globally in [onImpactUsed]. 3051 // Impacts are uncached globally in [onImpactUsed].
3179 } else if (impactUse == DumpInfoTask.IMPACT_USE) { 3052 } else if (impactUse == DumpInfoTask.IMPACT_USE) {
3180 impact.apply(visitor); 3053 impact.apply(visitor);
3181 dumpInfoTask.unregisterImpact(element); 3054 dumpInfoTask.unregisterImpact(element);
3182 } else { 3055 } else {
3183 impact.apply(visitor); 3056 impact.apply(visitor);
3184 } 3057 }
3185 } 3058 }
3186 3059
3187 @override 3060 @override
3188 void onImpactUsed(ImpactUseCase impactUse) { 3061 void onImpactUsed(ImpactUseCase impactUse) {
3189 if (impactUse == DeferredLoadTask.IMPACT_USE) { 3062 if (impactUse == DeferredLoadTask.IMPACT_USE &&
3063 !supportSerialization) {
3190 resolution.emptyCache(); 3064 resolution.emptyCache();
3191 } 3065 }
3192 } 3066 }
3193 } 3067 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698