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

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

Issue 2693163002: Split backend implementation of EnqueuerListener (Closed)
Patch Set: Updated cf. comments Created 3 years, 10 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 library js_backend.backend; 5 library js_backend.backend;
6 6
7 import 'dart:async' show Future; 7 import 'dart:async' show Future;
8 8
9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
10 10
(...skipping 29 matching lines...) Expand all
40 import '../io/start_end_information.dart' 40 import '../io/start_end_information.dart'
41 show StartEndSourceInformationStrategy; 41 show StartEndSourceInformationStrategy;
42 import '../js/js.dart' as jsAst; 42 import '../js/js.dart' as jsAst;
43 import '../js/js.dart' show js; 43 import '../js/js.dart' show js;
44 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy; 44 import '../js/js_source_mapping.dart' show JavaScriptSourceInformationStrategy;
45 import '../js/rewrite_async.dart'; 45 import '../js/rewrite_async.dart';
46 import '../js_emitter/js_emitter.dart' show CodeEmitterTask; 46 import '../js_emitter/js_emitter.dart' show CodeEmitterTask;
47 import '../kernel/task.dart'; 47 import '../kernel/task.dart';
48 import '../library_loader.dart' show LibraryLoader, LoadedLibraries; 48 import '../library_loader.dart' show LibraryLoader, LoadedLibraries;
49 import '../native/native.dart' as native; 49 import '../native/native.dart' as native;
50 import '../options.dart' show CompilerOptions;
50 import '../patch_parser.dart' 51 import '../patch_parser.dart'
51 show checkNativeAnnotation, checkJsInteropAnnotation; 52 show checkNativeAnnotation, checkJsInteropAnnotation;
52 import '../ssa/ssa.dart' show SsaFunctionCompiler; 53 import '../ssa/ssa.dart' show SsaFunctionCompiler;
53 import '../tracer.dart'; 54 import '../tracer.dart';
54 import '../tree/tree.dart'; 55 import '../tree/tree.dart';
55 import '../universe/call_structure.dart' show CallStructure; 56 import '../universe/call_structure.dart' show CallStructure;
56 import '../universe/feature.dart'; 57 import '../universe/feature.dart';
57 import '../universe/selector.dart' show Selector; 58 import '../universe/selector.dart' show Selector;
58 import '../universe/world_builder.dart'; 59 import '../universe/world_builder.dart';
59 import '../universe/use.dart' 60 import '../universe/use.dart'
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 } 303 }
303 } 304 }
304 305
305 enum SyntheticConstantKind { 306 enum SyntheticConstantKind {
306 DUMMY_INTERCEPTOR, 307 DUMMY_INTERCEPTOR,
307 EMPTY_VALUE, 308 EMPTY_VALUE,
308 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data. 309 TYPEVARIABLE_REFERENCE, // Reference to a type in reflection data.
309 NAME 310 NAME
310 } 311 }
311 312
312 class JavaScriptBackend extends Target implements EnqueuerListener { 313 class JavaScriptBackend extends Target {
313 final Compiler compiler; 314 final Compiler compiler;
314 315
315 String get patchVersion => emitter.patchVersion; 316 String get patchVersion => emitter.patchVersion;
316 317
317 /// Returns true if the backend supports reflection. 318 /// Returns true if the backend supports reflection.
318 bool get supportsReflection => emitter.supportsReflection; 319 bool get supportsReflection => emitter.supportsReflection;
319 320
320 final Annotations annotations; 321 final Annotations annotations;
321 322
322 /// Set of classes that need to be considered for reflection although not 323 /// Set of classes that need to be considered for reflection although not
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 List<CompilerTask> result = functionCompiler.tasks; 372 List<CompilerTask> result = functionCompiler.tasks;
372 result.add(emitter); 373 result.add(emitter);
373 result.add(patchResolverTask); 374 result.add(patchResolverTask);
374 result.add(kernelTask); 375 result.add(kernelTask);
375 return result; 376 return result;
376 } 377 }
377 378
378 final RuntimeTypes rti; 379 final RuntimeTypes rti;
379 final RuntimeTypesEncoder rtiEncoder; 380 final RuntimeTypesEncoder rtiEncoder;
380 381
381 /// True if a call to preserveUris has been seen and the preserve-uris flag
382 /// is set.
383 bool mustPreserveUris = false;
384
385 /// True if a core-library function requires the preamble file to function.
386 bool requiresPreamble = false;
387
388 /// True if the html library has been loaded. 382 /// True if the html library has been loaded.
389 bool htmlLibraryIsLoaded = false; 383 bool htmlLibraryIsLoaded = false;
390 384
391 /// True when we enqueue the loadLibrary code.
392 bool isLoadLibraryFunctionResolved = false;
393
394 /// `true` if access to [BackendHelpers.invokeOnMethod] is supported.
395 bool hasInvokeOnSupport = false;
396
397 /// `true` of `Object.runtimeType` is supported.
398 bool hasRuntimeTypeSupport = false;
399
400 /// `true` of use of the `dart:isolate` library is supported.
401 bool hasIsolateSupport = false;
402
403 /// `true` of `Function.apply` is supported.
404 bool hasFunctionApplySupport = false;
405
406 /// List of constants from metadata. If metadata must be preserved, 385 /// List of constants from metadata. If metadata must be preserved,
407 /// these constants must be registered. 386 /// these constants must be registered.
408 final List<Dependency> metadataConstants = <Dependency>[]; 387 final List<Dependency> metadataConstants = <Dependency>[];
409 388
410 /// Set of elements for which metadata has been registered as dependencies. 389 /// Set of elements for which metadata has been registered as dependencies.
411 final Set<Element> _registeredMetadata = new Set<Element>(); 390 final Set<Element> _registeredMetadata = new Set<Element>();
412 391
413 TypeVariableHandler typeVariableHandler; 392 TypeVariableHandler typeVariableHandler;
414 393
415 /// Number of methods compiled before considering reflection. 394 /// Number of methods compiled before considering reflection.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 437
459 StagedWorldImpactBuilder constantImpactsForCodegen = 438 StagedWorldImpactBuilder constantImpactsForCodegen =
460 new StagedWorldImpactBuilder(); 439 new StagedWorldImpactBuilder();
461 440
462 final NativeData nativeData = new NativeData(); 441 final NativeData nativeData = new NativeData();
463 InterceptorData _interceptorData; 442 InterceptorData _interceptorData;
464 BackendUsageImpl _backendUsage; 443 BackendUsageImpl _backendUsage;
465 final MirrorsData mirrorsData; 444 final MirrorsData mirrorsData;
466 CheckedModeHelpers _checkedModeHelpers; 445 CheckedModeHelpers _checkedModeHelpers;
467 446
447 ResolutionEnqueuerListener _resolutionEnqueuerListener;
448 CodegenEnqueuerListener _codegenEnqueuerListener;
449
468 BackendHelpers helpers; 450 BackendHelpers helpers;
469 final BackendImpacts impacts; 451 final BackendImpacts impacts;
470 452
471 /// Common classes used by the backend. 453 /// Common classes used by the backend.
472 BackendClasses backendClasses; 454 BackendClasses backendClasses;
473 455
474 /// Backend access to the front-end. 456 /// Backend access to the front-end.
475 final JSFrontendAccess frontend; 457 final JSFrontendAccess frontend;
476 458
477 Tracer tracer; 459 Tracer tracer;
(...skipping 30 matching lines...) Expand all
508 kernelTask = new KernelTask(compiler); 490 kernelTask = new KernelTask(compiler);
509 constantCompilerTask = new JavaScriptConstantTask(compiler); 491 constantCompilerTask = new JavaScriptConstantTask(compiler);
510 impactTransformer = new JavaScriptImpactTransformer(this); 492 impactTransformer = new JavaScriptImpactTransformer(this);
511 patchResolverTask = new PatchResolverTask(compiler); 493 patchResolverTask = new PatchResolverTask(compiler);
512 functionCompiler = 494 functionCompiler =
513 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); 495 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel);
514 serialization = new JavaScriptBackendSerialization(this); 496 serialization = new JavaScriptBackendSerialization(this);
515 _interceptorData = new InterceptorData(nativeData, helpers, commonElements); 497 _interceptorData = new InterceptorData(nativeData, helpers, commonElements);
516 backendClasses = new JavaScriptBackendClasses( 498 backendClasses = new JavaScriptBackendClasses(
517 compiler.elementEnvironment, helpers, nativeData, _interceptorData); 499 compiler.elementEnvironment, helpers, nativeData, _interceptorData);
500 _resolutionEnqueuerListener = new ResolutionEnqueuerListener(this);
501 _codegenEnqueuerListener = new CodegenEnqueuerListener(this);
518 } 502 }
519 503
520 /// The [ConstantSystem] used to interpret compile-time constants for this 504 /// The [ConstantSystem] used to interpret compile-time constants for this
521 /// backend. 505 /// backend.
522 ConstantSystem get constantSystem => constants.constantSystem; 506 ConstantSystem get constantSystem => constants.constantSystem;
523 507
524 DiagnosticReporter get reporter => compiler.reporter; 508 DiagnosticReporter get reporter => compiler.reporter;
525 509
526 CommonElements get commonElements => compiler.commonElements; 510 CommonElements get commonElements => compiler.commonElements;
527 511
528 Resolution get resolution => compiler.resolution; 512 Resolution get resolution => compiler.resolution;
529 513
530 InterceptorData get interceptorData => _interceptorData; 514 InterceptorData get interceptorData => _interceptorData;
531 515
532 BackendUsage get backendUsage => _backendUsage; 516 BackendUsage get backendUsage => _backendUsage;
533 517
534 BackendUsageBuilder get backendUsageBuilder => _backendUsage; 518 BackendUsageBuilder get backendUsageBuilder => _backendUsage;
535 519
536 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers; 520 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers;
537 521
522 EnqueuerListener get resolutionEnqueuerListener =>
523 _resolutionEnqueuerListener;
524
525 EnqueuerListener get codegenEnqueuerListener => _codegenEnqueuerListener;
526
538 /// Returns constant environment for the JavaScript interpretation of the 527 /// Returns constant environment for the JavaScript interpretation of the
539 /// constants. 528 /// constants.
540 JavaScriptConstantCompiler get constants { 529 JavaScriptConstantCompiler get constants {
541 return constantCompilerTask.jsConstantCompiler; 530 return constantCompilerTask.jsConstantCompiler;
542 } 531 }
543 532
544 @override 533 @override
545 bool isDefaultNoSuchMethod(MethodElement element) { 534 bool isDefaultNoSuchMethod(MethodElement element) {
546 return noSuchMethodRegistry.isDefaultNoSuchMethodImplementation(element); 535 return noSuchMethodRegistry.isDefaultNoSuchMethodImplementation(element);
547 } 536 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 // differences. 693 // differences.
705 assert(invariant(interceptorMember, 694 assert(invariant(interceptorMember,
706 interceptorMember.enclosingClass == interceptorClass, 695 interceptorMember.enclosingClass == interceptorClass,
707 message: 696 message:
708 "Member ${member.name} not overridden in ${interceptorClass}. " 697 "Member ${member.name} not overridden in ${interceptorClass}. "
709 "Found $interceptorMember from " 698 "Found $interceptorMember from "
710 "${interceptorMember.enclosingClass}.")); 699 "${interceptorMember.enclosingClass}."));
711 }); 700 });
712 } 701 }
713 702
714 void addInterceptorsForNativeClassMembers(ClassElement cls,
715 {bool forResolution}) {
716 if (forResolution) {
717 cls.ensureResolved(resolution);
718 interceptorData.addInterceptorsForNativeClassMembers(cls);
719 }
720 }
721
722 void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder,
723 {bool forResolution}) {
724 if (forResolution) {
725 cls.ensureResolved(resolution);
726 interceptorData.addInterceptors(cls);
727 }
728 backendUsageBuilder.registerBackendInstantiation(impactBuilder, cls);
729 }
730
731 /// Called during codegen when [constant] has been used. 703 /// Called during codegen when [constant] has been used.
732 void computeImpactForCompileTimeConstant(ConstantValue constant, 704 void computeImpactForCompileTimeConstant(ConstantValue constant,
733 WorldImpactBuilder impactBuilder, bool isForResolution) { 705 WorldImpactBuilder impactBuilder, bool isForResolution) {
734 computeImpactForCompileTimeConstantInternal( 706 computeImpactForCompileTimeConstantInternal(
735 constant, impactBuilder, isForResolution); 707 constant, impactBuilder, isForResolution);
736 708
737 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { 709 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) {
738 // Note: internally, this registration will temporarily remove the 710 // Note: internally, this registration will temporarily remove the
739 // constant dependencies and add them later on-demand. 711 // constant dependencies and add them later on-demand.
740 lookupMapAnalysis.registerLookupMapReference(constant); 712 lookupMapAnalysis.registerLookupMapReference(constant);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 // constant emitter will generate a call to the createRuntimeType 766 // constant emitter will generate a call to the createRuntimeType
795 // helper so we register a use of that. 767 // helper so we register a use of that.
796 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( 768 impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
797 // TODO(johnniwinther): Find the right [CallStructure]. 769 // TODO(johnniwinther): Find the right [CallStructure].
798 helpers.createRuntimeType, 770 helpers.createRuntimeType,
799 null)); 771 null));
800 } 772 }
801 } 773 }
802 } 774 }
803 775
804 WorldImpact registerInstantiatedClass(ClassElement cls, 776 // TODO(johnniwinther): Avoid the need for this.
805 {bool forResolution}) { 777 WorldImpact computeHelpersImpact() =>
806 return _processClass(cls, forResolution: forResolution); 778 _resolutionEnqueuerListener.computeHelpersImpact();
807 }
808
809 WorldImpact registerImplementedClass(ClassElement cls, {bool forResolution}) {
810 return _processClass(cls, forResolution: forResolution);
811 }
812
813 WorldImpact _processClass(ClassElement cls, {bool forResolution}) {
814 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
815 if (!cls.typeVariables.isEmpty) {
816 typeVariableHandler.registerClassWithTypeVariables(cls,
817 forResolution: forResolution);
818 }
819
820 // Register any helper that will be needed by the backend.
821 if (forResolution) {
822 if (cls == commonElements.intClass ||
823 cls == commonElements.doubleClass ||
824 cls == commonElements.numClass) {
825 backendUsageBuilder.registerBackendImpact(
826 impactBuilder, impacts.numClasses);
827 } else if (cls == commonElements.listClass ||
828 cls == commonElements.stringClass) {
829 backendUsageBuilder.registerBackendImpact(
830 impactBuilder, impacts.listOrStringClasses);
831 } else if (cls == commonElements.functionClass) {
832 backendUsageBuilder.registerBackendImpact(
833 impactBuilder, impacts.functionClass);
834 } else if (cls == commonElements.mapClass) {
835 backendUsageBuilder.registerBackendImpact(
836 impactBuilder, impacts.mapClass);
837 // For map literals, the dependency between the implementation class
838 // and [Map] is not visible, so we have to add it manually.
839 rti.registerRtiDependency(helpers.mapLiteralClass, cls);
840 } else if (cls == helpers.boundClosureClass) {
841 backendUsageBuilder.registerBackendImpact(
842 impactBuilder, impacts.boundClosureClass);
843 } else if (nativeData.isNativeOrExtendsNative(cls)) {
844 backendUsageBuilder.registerBackendImpact(
845 impactBuilder, impacts.nativeOrExtendsClass);
846 } else if (cls == helpers.mapLiteralClass) {
847 backendUsageBuilder.registerBackendImpact(
848 impactBuilder, impacts.mapLiteralClass);
849 }
850 }
851 if (cls == helpers.closureClass) {
852 backendUsageBuilder.registerBackendImpact(
853 impactBuilder, impacts.closureClass);
854 }
855 if (cls == commonElements.stringClass || cls == helpers.jsStringClass) {
856 addInterceptors(helpers.jsStringClass, impactBuilder,
857 forResolution: forResolution);
858 } else if (cls == commonElements.listClass ||
859 cls == helpers.jsArrayClass ||
860 cls == helpers.jsFixedArrayClass ||
861 cls == helpers.jsExtendableArrayClass ||
862 cls == helpers.jsUnmodifiableArrayClass) {
863 addInterceptors(helpers.jsArrayClass, impactBuilder,
864 forResolution: forResolution);
865 addInterceptors(helpers.jsMutableArrayClass, impactBuilder,
866 forResolution: forResolution);
867 addInterceptors(helpers.jsFixedArrayClass, impactBuilder,
868 forResolution: forResolution);
869 addInterceptors(helpers.jsExtendableArrayClass, impactBuilder,
870 forResolution: forResolution);
871 addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder,
872 forResolution: forResolution);
873 if (forResolution) {
874 backendUsageBuilder.registerBackendImpact(
875 impactBuilder, impacts.listClasses);
876 }
877 } else if (cls == commonElements.intClass || cls == helpers.jsIntClass) {
878 addInterceptors(helpers.jsIntClass, impactBuilder,
879 forResolution: forResolution);
880 addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
881 forResolution: forResolution);
882 addInterceptors(helpers.jsUInt32Class, impactBuilder,
883 forResolution: forResolution);
884 addInterceptors(helpers.jsUInt31Class, impactBuilder,
885 forResolution: forResolution);
886 addInterceptors(helpers.jsNumberClass, impactBuilder,
887 forResolution: forResolution);
888 } else if (cls == commonElements.doubleClass ||
889 cls == helpers.jsDoubleClass) {
890 addInterceptors(helpers.jsDoubleClass, impactBuilder,
891 forResolution: forResolution);
892 addInterceptors(helpers.jsNumberClass, impactBuilder,
893 forResolution: forResolution);
894 } else if (cls == commonElements.boolClass || cls == helpers.jsBoolClass) {
895 addInterceptors(helpers.jsBoolClass, impactBuilder,
896 forResolution: forResolution);
897 } else if (cls == commonElements.nullClass || cls == helpers.jsNullClass) {
898 addInterceptors(helpers.jsNullClass, impactBuilder,
899 forResolution: forResolution);
900 } else if (cls == commonElements.numClass || cls == helpers.jsNumberClass) {
901 addInterceptors(helpers.jsIntClass, impactBuilder,
902 forResolution: forResolution);
903 addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
904 forResolution: forResolution);
905 addInterceptors(helpers.jsUInt32Class, impactBuilder,
906 forResolution: forResolution);
907 addInterceptors(helpers.jsUInt31Class, impactBuilder,
908 forResolution: forResolution);
909 addInterceptors(helpers.jsDoubleClass, impactBuilder,
910 forResolution: forResolution);
911 addInterceptors(helpers.jsNumberClass, impactBuilder,
912 forResolution: forResolution);
913 } else if (cls == helpers.jsJavaScriptObjectClass) {
914 addInterceptors(helpers.jsJavaScriptObjectClass, impactBuilder,
915 forResolution: forResolution);
916 } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
917 addInterceptors(helpers.jsPlainJavaScriptObjectClass, impactBuilder,
918 forResolution: forResolution);
919 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
920 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder,
921 forResolution: forResolution);
922 } else if (cls == helpers.jsJavaScriptFunctionClass) {
923 addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder,
924 forResolution: forResolution);
925 } else if (nativeData.isNativeOrExtendsNative(cls)) {
926 addInterceptorsForNativeClassMembers(cls, forResolution: forResolution);
927 } else if (cls == helpers.jsIndexingBehaviorInterface) {
928 backendUsageBuilder.registerBackendImpact(
929 impactBuilder, impacts.jsIndexingBehavior);
930 }
931
932 customElementsAnalysis.registerInstantiatedClass(cls,
933 forResolution: forResolution);
934 if (!forResolution) {
935 lookupMapAnalysis.registerInstantiatedClass(cls);
936 }
937
938 return impactBuilder;
939 }
940
941 void registerInstantiatedType(ResolutionInterfaceType type,
942 {bool isGlobal: false}) {
943 if (isGlobal) {
944 backendUsageBuilder.registerGlobalDependency(type.element);
945 }
946 lookupMapAnalysis.registerInstantiatedType(type);
947 }
948
949 /// Compute the [WorldImpact] for backend helper methods.
950 WorldImpact computeHelpersImpact() {
951 assert(helpers.interceptorsLibrary != null);
952 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
953 // TODO(ngeoffray): Not enqueuing those two classes currently make
954 // the compiler potentially crash. However, any reasonable program
955 // will instantiate those two classes.
956 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true);
957 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true);
958 if (compiler.options.enableTypeAssertions) {
959 backendUsageBuilder.registerBackendImpact(
960 impactBuilder, impacts.enableTypeAssertions);
961 }
962
963 if (TRACE_CALLS) {
964 backendUsageBuilder.registerBackendImpact(
965 impactBuilder, impacts.traceHelper);
966 }
967 backendUsageBuilder.registerBackendImpact(
968 impactBuilder, impacts.assertUnreachable);
969 _registerCheckedModeHelpers(impactBuilder);
970 return impactBuilder;
971 }
972 779
973 void onResolutionComplete( 780 void onResolutionComplete(
974 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { 781 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) {
975 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { 782 for (Entity entity in compiler.enqueuer.resolution.processedEntities) {
976 processAnnotations(entity, closedWorldRefiner); 783 processAnnotations(entity, closedWorldRefiner);
977 } 784 }
978 mirrorsData.computeMembersNeededForReflection(closedWorld); 785 mirrorsData.computeMembersNeededForReflection(closedWorld);
979 rti.computeClassesNeedingRti( 786 rti.computeClassesNeedingRti(
980 compiler.enqueuer.resolution.worldBuilder, closedWorld); 787 compiler.enqueuer.resolution.worldBuilder, closedWorld);
981 _registeredMetadata.clear(); 788 _registeredMetadata.clear();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 backendUsageBuilder.registerBackendImpact( 907 backendUsageBuilder.registerBackendImpact(
1101 impactBuilder, impacts.isolateSupport); 908 impactBuilder, impacts.isolateSupport);
1102 if (forResolution) { 909 if (forResolution) {
1103 backendUsageBuilder.registerBackendImpact( 910 backendUsageBuilder.registerBackendImpact(
1104 impactBuilder, impacts.isolateSupportForResolution); 911 impactBuilder, impacts.isolateSupportForResolution);
1105 } 912 }
1106 return impactBuilder; 913 return impactBuilder;
1107 } 914 }
1108 915
1109 bool classNeedsRti(ClassElement cls) { 916 bool classNeedsRti(ClassElement cls) {
1110 if (hasRuntimeTypeSupport) return true; 917 if (backendUsage.isRuntimeTypeUsed) return true;
1111 return rti.classesNeedingRti.contains(cls.declaration); 918 return rti.classesNeedingRti.contains(cls.declaration);
1112 } 919 }
1113 920
1114 bool classNeedsRtiField(ClassElement cls) { 921 bool classNeedsRtiField(ClassElement cls) {
1115 if (cls.rawType.typeArguments.isEmpty) return false; 922 if (cls.rawType.typeArguments.isEmpty) return false;
1116 if (hasRuntimeTypeSupport) return true; 923 if (backendUsage.isRuntimeTypeUsed) return true;
1117 return rti.classesNeedingRti.contains(cls.declaration); 924 return rti.classesNeedingRti.contains(cls.declaration);
1118 } 925 }
1119 926
1120 bool isComplexNoSuchMethod(FunctionElement element) => 927 bool isComplexNoSuchMethod(FunctionElement element) =>
1121 noSuchMethodRegistry.isComplex(element); 928 noSuchMethodRegistry.isComplex(element);
1122 929
1123 bool methodNeedsRti(FunctionElement function) { 930 bool methodNeedsRti(FunctionElement function) {
1124 return rti.methodsNeedingRti.contains(function) || hasRuntimeTypeSupport; 931 return rti.methodsNeedingRti.contains(function) ||
932 backendUsage.isRuntimeTypeUsed;
1125 } 933 }
1126 934
1127 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; 935 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen;
1128 936
1129 /// Creates an [Enqueuer] for code generation specific to this backend. 937 /// Creates an [Enqueuer] for code generation specific to this backend.
1130 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { 938 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) {
1131 return new CodegenEnqueuer( 939 return new CodegenEnqueuer(
1132 task, this, compiler.options, const TreeShakingEnqueuerStrategy()); 940 task, this, compiler.options, const TreeShakingEnqueuerStrategy());
1133 } 941 }
1134 942
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 1077
1270 Element getDartClass(Element element) { 1078 Element getDartClass(Element element) {
1271 for (ClassElement dartClass in implementationClasses.keys) { 1079 for (ClassElement dartClass in implementationClasses.keys) {
1272 if (element == implementationClasses[dartClass]) { 1080 if (element == implementationClasses[dartClass]) {
1273 return dartClass; 1081 return dartClass;
1274 } 1082 }
1275 } 1083 }
1276 return element; 1084 return element;
1277 } 1085 }
1278 1086
1279 void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) {
1280 // We register all the helpers in the resolution queue.
1281 // TODO(13155): Find a way to register fewer helpers.
1282 List<Element> staticUses = <Element>[];
1283 for (CheckedModeHelper helper in CheckedModeHelpers.helpers) {
1284 staticUses.add(helper.getStaticUse(helpers).element);
1285 }
1286 backendUsageBuilder.registerBackendImpact(
1287 impactBuilder, new BackendImpact(globalUses: staticUses));
1288 }
1289
1290 /** 1087 /**
1291 * Returns [:true:] if the checking of [type] is performed directly on the 1088 * Returns [:true:] if the checking of [type] is performed directly on the
1292 * object and not on an interceptor. 1089 * object and not on an interceptor.
1293 */ 1090 */
1294 bool hasDirectCheckFor(ResolutionDartType type) { 1091 bool hasDirectCheckFor(ResolutionDartType type) {
1295 Element element = type.element; 1092 Element element = type.element;
1296 return element == commonElements.stringClass || 1093 return element == commonElements.stringClass ||
1297 element == commonElements.boolClass || 1094 element == commonElements.boolClass ||
1298 element == commonElements.numClass || 1095 element == commonElements.numClass ||
1299 element == commonElements.intClass || 1096 element == commonElements.intClass ||
1300 element == commonElements.doubleClass || 1097 element == commonElements.doubleClass ||
1301 element == helpers.jsArrayClass || 1098 element == helpers.jsArrayClass ||
1302 element == helpers.jsMutableArrayClass || 1099 element == helpers.jsMutableArrayClass ||
1303 element == helpers.jsExtendableArrayClass || 1100 element == helpers.jsExtendableArrayClass ||
1304 element == helpers.jsFixedArrayClass || 1101 element == helpers.jsFixedArrayClass ||
1305 element == helpers.jsUnmodifiableArrayClass; 1102 element == helpers.jsUnmodifiableArrayClass;
1306 } 1103 }
1307 1104
1308 bool mayGenerateInstanceofCheck(ResolutionDartType type) { 1105 bool mayGenerateInstanceofCheck(ResolutionDartType type) {
1309 // We can use an instanceof check for raw types that have no subclass that 1106 // We can use an instanceof check for raw types that have no subclass that
1310 // is mixed-in or in an implements clause. 1107 // is mixed-in or in an implements clause.
1311 1108
1312 if (!type.isRaw) return false; 1109 if (!type.isRaw) return false;
1313 ClassElement classElement = type.element; 1110 ClassElement classElement = type.element;
1314 if (interceptorData.isInterceptorClass(classElement)) return false; 1111 if (interceptorData.isInterceptorClass(classElement)) return false;
1315 return _closedWorld.hasOnlySubclasses(classElement); 1112 return _closedWorld.hasOnlySubclasses(classElement);
1316 } 1113 }
1317 1114
1318 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) {
1319 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
1320 backendUsageBuilder.registerUsedMember(element);
1321 if (element == helpers.disableTreeShakingMarker) {
1322 mirrorsData.isTreeShakingDisabled = true;
1323 } else if (element == helpers.preserveNamesMarker) {
1324 mirrorsData.mustPreserveNames = true;
1325 } else if (element == helpers.preserveMetadataMarker) {
1326 mirrorsData.mustRetainMetadata = true;
1327 } else if (element == helpers.preserveUrisMarker) {
1328 if (compiler.options.preserveUris) mustPreserveUris = true;
1329 } else if (element == helpers.preserveLibraryNamesMarker) {
1330 mirrorsData.mustRetainLibraryNames = true;
1331 } else if (element.isDeferredLoaderGetter) {
1332 // TODO(sigurdm): Create a function registerLoadLibraryAccess.
1333 if (!isLoadLibraryFunctionResolved) {
1334 isLoadLibraryFunctionResolved = true;
1335 if (forResolution) {
1336 backendUsageBuilder.registerBackendImpact(
1337 worldImpact, impacts.loadLibrary);
1338 }
1339 }
1340 } else if (element == helpers.requiresPreambleMarker) {
1341 requiresPreamble = true;
1342 } else if (element == helpers.invokeOnMethod && forResolution) {
1343 hasInvokeOnSupport = true;
1344 }
1345 customElementsAnalysis.registerStaticUse(element,
1346 forResolution: forResolution);
1347
1348 if (element.isFunction && element.isInstanceMember) {
1349 MemberElement function = element;
1350 ClassElement cls = function.enclosingClass;
1351 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
1352 worldImpact.addImpact(registerCallMethodWithFreeTypeVariables(function,
1353 forResolution: forResolution));
1354 }
1355 }
1356 if (forResolution) {
1357 // Enable isolate support if we start using something from the isolate
1358 // library, or timers for the async library. We exclude constant fields,
1359 // which are ending here because their initializing expression is
1360 // compiled.
1361 LibraryElement library = element.library;
1362 if (!hasIsolateSupport && !(element.isField && element.isConst)) {
1363 Uri uri = library.canonicalUri;
1364 if (uri == Uris.dart_isolate) {
1365 hasIsolateSupport = true;
1366 worldImpact
1367 .addImpact(enableIsolateSupport(forResolution: forResolution));
1368 } else if (uri == Uris.dart_async) {
1369 if (element.name == '_createTimer' ||
1370 element.name == '_createPeriodicTimer') {
1371 // The [:Timer:] class uses the event queue of the isolate
1372 // library, so we make sure that event queue is generated.
1373 hasIsolateSupport = true;
1374 worldImpact
1375 .addImpact(enableIsolateSupport(forResolution: forResolution));
1376 }
1377 }
1378 }
1379
1380 if (element.isGetter && element.name == Identifiers.runtimeType_) {
1381 // Enable runtime type support if we discover a getter called
1382 // runtimeType. We have to enable runtime type before hitting the
1383 // codegen, so that constructors know whether they need to generate code
1384 // for runtime type.
1385 hasRuntimeTypeSupport = true;
1386 // TODO(ahe): Record precise dependency here.
1387 worldImpact.addImpact(registerRuntimeType());
1388 } else if (compiler.commonElements.isFunctionApplyMethod(element)) {
1389 hasFunctionApplySupport = true;
1390 }
1391 } else {
1392 // TODO(sigmund): add other missing dependencies (internals, selectors
1393 // enqueued after allocations).
1394 compiler.dumpInfoTask.registerDependency(element);
1395 }
1396 return worldImpact;
1397 }
1398
1399 /// This method is called immediately after the [library] and its parts have 1115 /// This method is called immediately after the [library] and its parts have
1400 /// been scanned. 1116 /// been scanned.
1401 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { 1117 Future onLibraryScanned(LibraryElement library, LibraryLoader loader) {
1402 if (!compiler.serialization.isDeserialized(library)) { 1118 if (!compiler.serialization.isDeserialized(library)) {
1403 if (canLibraryUseNative(library)) { 1119 if (canLibraryUseNative(library)) {
1404 library.forEachLocalMember((Element element) { 1120 library.forEachLocalMember((Element element) {
1405 if (element.isClass) { 1121 if (element.isClass) {
1406 checkNativeAnnotation(compiler, element); 1122 checkNativeAnnotation(compiler, element);
1407 } 1123 }
1408 }); 1124 });
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 if (target == null) continue; 1229 if (target == null) continue;
1514 if (target.isField) { 1230 if (target.isField) {
1515 staticFields.add(target); 1231 staticFields.add(target);
1516 } else if (target.isLibrary || target.isClass) { 1232 } else if (target.isLibrary || target.isClass) {
1517 addFieldsInContainer(target); 1233 addFieldsInContainer(target);
1518 } 1234 }
1519 } 1235 }
1520 return staticFields; 1236 return staticFields;
1521 } 1237 }
1522 1238
1523 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) { 1239 // TODO(johnniwinther): Split this into [ResolutionEnqueuerListener]
1240 // and [CodegenEnqueuerListener].
1241 bool _onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
1524 // Add elements used synthetically, that is, through features rather than 1242 // Add elements used synthetically, that is, through features rather than
1525 // syntax, for instance custom elements. 1243 // syntax, for instance custom elements.
1526 // 1244 //
1527 // Return early if any elements are added to avoid counting the elements as 1245 // Return early if any elements are added to avoid counting the elements as
1528 // due to mirrors. 1246 // due to mirrors.
1529 enqueuer.applyImpact(customElementsAnalysis.flush( 1247 enqueuer.applyImpact(customElementsAnalysis.flush(
1530 forResolution: enqueuer.isResolutionQueue)); 1248 forResolution: enqueuer.isResolutionQueue));
1531 enqueuer.applyImpact( 1249 enqueuer.applyImpact(
1532 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue)); 1250 lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue));
1533 enqueuer.applyImpact( 1251 enqueuer.applyImpact(
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 } 1399 }
1682 1400
1683 /// Called when the compiler starts running the codegen enqueuer. The 1401 /// Called when the compiler starts running the codegen enqueuer. The
1684 /// [WorldImpact] of enabled backend features is returned. 1402 /// [WorldImpact] of enabled backend features is returned.
1685 WorldImpact onCodegenStart(ClosedWorld closedWorld) { 1403 WorldImpact onCodegenStart(ClosedWorld closedWorld) {
1686 _closedWorld = closedWorld; 1404 _closedWorld = closedWorld;
1687 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder); 1405 _namer = determineNamer(_closedWorld, compiler.codegenWorldBuilder);
1688 tracer = new Tracer(_closedWorld, namer, compiler.outputProvider); 1406 tracer = new Tracer(_closedWorld, namer, compiler.outputProvider);
1689 emitter.createEmitter(_namer, _closedWorld); 1407 emitter.createEmitter(_namer, _closedWorld);
1690 lookupMapAnalysis.onCodegenStart(); 1408 lookupMapAnalysis.onCodegenStart();
1691 if (hasIsolateSupport) { 1409 if (backendUsage.isIsolateInUse) {
1692 return enableIsolateSupport(forResolution: false); 1410 return enableIsolateSupport(forResolution: false);
1693 } 1411 }
1694 return const WorldImpact(); 1412 return const WorldImpact();
1695 } 1413 }
1696 1414
1697 /// Called when code generation has been completed. 1415 /// Called when code generation has been completed.
1698 void onCodegenEnd() { 1416 void onCodegenEnd() {
1699 sourceInformationStrategy.onComplete(); 1417 sourceInformationStrategy.onComplete();
1700 tracer.close(); 1418 tracer.close();
1701 } 1419 }
(...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
2573 } 2291 }
2574 2292
2575 @override 2293 @override
2576 FieldEntity get symbolField => helpers.symbolImplementationField; 2294 FieldEntity get symbolField => helpers.symbolImplementationField;
2577 2295
2578 @override 2296 @override
2579 InterfaceType get symbolType { 2297 InterfaceType get symbolType {
2580 return _env.getRawType(helpers.symbolImplementationClass); 2298 return _env.getRawType(helpers.symbolImplementationClass);
2581 } 2299 }
2582 } 2300 }
2301
2302 abstract class EnqueuerListenerBase implements EnqueuerListener {
2303 // TODO(johnniwinther): Avoid the need for accessing through [_backend].
2304 JavaScriptBackend _backend;
2305
2306 EnqueuerListenerBase(this._backend);
2307
2308 // TODO(johnniwinther): Change these to final fields.
2309 CommonElements get commonElements => _backend.commonElements;
2310 BackendHelpers get helpers => _backend.helpers;
2311 BackendImpacts get impacts => _backend.impacts;
2312 BackendUsageBuilder get backendUsage => _backend.backendUsageBuilder;
2313 CustomElementsAnalysis get customElementsAnalysis =>
2314 _backend.customElementsAnalysis;
2315 NativeData get nativeData => _backend.nativeData;
2316 InterceptorData get interceptorData => _backend.interceptorData;
2317 RuntimeTypes get rti => _backend.rti;
2318 TypeVariableHandler get typeVariableHandler => _backend.typeVariableHandler;
2319 Resolution get resolution => _backend.resolution;
2320 MirrorsData get mirrorsData => _backend.mirrorsData;
2321 CompilerOptions get options => _backend.compiler.options;
2322
2323 WorldImpact registerBoundClosure() {
2324 return backendUsage.createImpactFor(impacts.memberClosure);
2325 }
2326
2327 WorldImpact registerGetOfStaticFunction() {
2328 return backendUsage.createImpactFor(impacts.staticClosure);
2329 }
2330
2331 WorldImpact _registerComputeSignature() {
2332 return backendUsage.createImpactFor(impacts.computeSignature);
2333 }
2334
2335 /// Called to register that an instantiated generic class has a call method.
2336 /// Any backend specific [WorldImpact] of this is returned.
2337 ///
2338 /// Note: The [callMethod] is registered even thought it doesn't reference
2339 /// the type variables.
2340 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod);
2341
2342 WorldImpact _processClass(ClassElement cls, {bool forResolution}) {
2343 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
2344 if (!cls.typeVariables.isEmpty) {
2345 typeVariableHandler.registerClassWithTypeVariables(cls,
2346 forResolution: forResolution);
2347 }
2348
2349 // Register any helper that will be needed by the backend.
2350 if (forResolution) {
2351 if (cls == commonElements.intClass ||
2352 cls == commonElements.doubleClass ||
2353 cls == commonElements.numClass) {
2354 backendUsage.registerBackendImpact(impactBuilder, impacts.numClasses);
2355 } else if (cls == commonElements.listClass ||
2356 cls == commonElements.stringClass) {
2357 backendUsage.registerBackendImpact(
2358 impactBuilder, impacts.listOrStringClasses);
2359 } else if (cls == commonElements.functionClass) {
2360 backendUsage.registerBackendImpact(
2361 impactBuilder, impacts.functionClass);
2362 } else if (cls == commonElements.mapClass) {
2363 backendUsage.registerBackendImpact(impactBuilder, impacts.mapClass);
2364 // For map literals, the dependency between the implementation class
2365 // and [Map] is not visible, so we have to add it manually.
2366 rti.registerRtiDependency(helpers.mapLiteralClass, cls);
2367 } else if (cls == helpers.boundClosureClass) {
2368 backendUsage.registerBackendImpact(
2369 impactBuilder, impacts.boundClosureClass);
2370 } else if (nativeData.isNativeOrExtendsNative(cls)) {
2371 backendUsage.registerBackendImpact(
2372 impactBuilder, impacts.nativeOrExtendsClass);
2373 } else if (cls == helpers.mapLiteralClass) {
2374 backendUsage.registerBackendImpact(
2375 impactBuilder, impacts.mapLiteralClass);
2376 }
2377 }
2378 if (cls == helpers.closureClass) {
2379 backendUsage.registerBackendImpact(impactBuilder, impacts.closureClass);
2380 }
2381 if (cls == commonElements.stringClass || cls == helpers.jsStringClass) {
2382 addInterceptors(helpers.jsStringClass, impactBuilder,
2383 forResolution: forResolution);
2384 } else if (cls == commonElements.listClass ||
2385 cls == helpers.jsArrayClass ||
2386 cls == helpers.jsFixedArrayClass ||
2387 cls == helpers.jsExtendableArrayClass ||
2388 cls == helpers.jsUnmodifiableArrayClass) {
2389 addInterceptors(helpers.jsArrayClass, impactBuilder,
2390 forResolution: forResolution);
2391 addInterceptors(helpers.jsMutableArrayClass, impactBuilder,
2392 forResolution: forResolution);
2393 addInterceptors(helpers.jsFixedArrayClass, impactBuilder,
2394 forResolution: forResolution);
2395 addInterceptors(helpers.jsExtendableArrayClass, impactBuilder,
2396 forResolution: forResolution);
2397 addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder,
2398 forResolution: forResolution);
2399 if (forResolution) {
2400 backendUsage.registerBackendImpact(impactBuilder, impacts.listClasses);
2401 }
2402 } else if (cls == commonElements.intClass || cls == helpers.jsIntClass) {
2403 addInterceptors(helpers.jsIntClass, impactBuilder,
2404 forResolution: forResolution);
2405 addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
2406 forResolution: forResolution);
2407 addInterceptors(helpers.jsUInt32Class, impactBuilder,
2408 forResolution: forResolution);
2409 addInterceptors(helpers.jsUInt31Class, impactBuilder,
2410 forResolution: forResolution);
2411 addInterceptors(helpers.jsNumberClass, impactBuilder,
2412 forResolution: forResolution);
2413 } else if (cls == commonElements.doubleClass ||
2414 cls == helpers.jsDoubleClass) {
2415 addInterceptors(helpers.jsDoubleClass, impactBuilder,
2416 forResolution: forResolution);
2417 addInterceptors(helpers.jsNumberClass, impactBuilder,
2418 forResolution: forResolution);
2419 } else if (cls == commonElements.boolClass || cls == helpers.jsBoolClass) {
2420 addInterceptors(helpers.jsBoolClass, impactBuilder,
2421 forResolution: forResolution);
2422 } else if (cls == commonElements.nullClass || cls == helpers.jsNullClass) {
2423 addInterceptors(helpers.jsNullClass, impactBuilder,
2424 forResolution: forResolution);
2425 } else if (cls == commonElements.numClass || cls == helpers.jsNumberClass) {
2426 addInterceptors(helpers.jsIntClass, impactBuilder,
2427 forResolution: forResolution);
2428 addInterceptors(helpers.jsPositiveIntClass, impactBuilder,
2429 forResolution: forResolution);
2430 addInterceptors(helpers.jsUInt32Class, impactBuilder,
2431 forResolution: forResolution);
2432 addInterceptors(helpers.jsUInt31Class, impactBuilder,
2433 forResolution: forResolution);
2434 addInterceptors(helpers.jsDoubleClass, impactBuilder,
2435 forResolution: forResolution);
2436 addInterceptors(helpers.jsNumberClass, impactBuilder,
2437 forResolution: forResolution);
2438 } else if (cls == helpers.jsJavaScriptObjectClass) {
2439 addInterceptors(helpers.jsJavaScriptObjectClass, impactBuilder,
2440 forResolution: forResolution);
2441 } else if (cls == helpers.jsPlainJavaScriptObjectClass) {
2442 addInterceptors(helpers.jsPlainJavaScriptObjectClass, impactBuilder,
2443 forResolution: forResolution);
2444 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) {
2445 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder,
2446 forResolution: forResolution);
2447 } else if (cls == helpers.jsJavaScriptFunctionClass) {
2448 addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder,
2449 forResolution: forResolution);
2450 } else if (nativeData.isNativeOrExtendsNative(cls)) {
2451 addInterceptorsForNativeClassMembers(cls, forResolution: forResolution);
2452 } else if (cls == helpers.jsIndexingBehaviorInterface) {
2453 backendUsage.registerBackendImpact(
2454 impactBuilder, impacts.jsIndexingBehavior);
2455 }
2456
2457 customElementsAnalysis.registerInstantiatedClass(cls,
2458 forResolution: forResolution);
2459
2460 return impactBuilder;
2461 }
2462
2463 void addInterceptorsForNativeClassMembers(ClassElement cls,
2464 {bool forResolution}) {
2465 if (forResolution) {
2466 cls.ensureResolved(resolution);
2467 interceptorData.addInterceptorsForNativeClassMembers(cls);
2468 }
2469 }
2470
2471 void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder,
2472 {bool forResolution}) {
2473 if (forResolution) {
2474 cls.ensureResolved(resolution);
2475 interceptorData.addInterceptors(cls);
2476 }
2477 backendUsage.registerBackendInstantiation(impactBuilder, cls);
2478 }
2479
2480 void _registerUsedElement(
2481 WorldImpactBuilderImpl worldImpact, MemberElement element,
2482 {bool forResolution}) {
2483 backendUsage.registerUsedMember(element);
2484 mirrorsData.registerUsedMember(element);
2485 customElementsAnalysis.registerStaticUse(element,
2486 forResolution: forResolution);
2487
2488 if (element.isFunction && element.isInstanceMember) {
2489 MemberElement function = element;
2490 ClassElement cls = function.enclosingClass;
2491 if (function.name == Identifiers.call && !cls.typeVariables.isEmpty) {
2492 worldImpact
2493 .addImpact(registerCallMethodWithFreeTypeVariables(function));
2494 }
2495 }
2496 }
2497 }
2498
2499 class ResolutionEnqueuerListener extends EnqueuerListenerBase {
2500 ResolutionEnqueuerListener(JavaScriptBackend backend) : super(backend);
2501
2502 // TODO(johnniwinther): Change this to a final field.
2503 NoSuchMethodRegistry get noSuchMethodRegistry =>
2504 _backend.noSuchMethodRegistry;
2505
2506 /// True when we enqueue the loadLibrary code.
2507 bool _isLoadLibraryFunctionResolved = false;
2508
2509 @override
2510 void registerInstantiatedType(ResolutionInterfaceType type,
2511 {bool isGlobal: false}) {
2512 if (isGlobal) {
2513 backendUsage.registerGlobalDependency(type.element);
2514 }
2515 }
2516
2517 @override
2518 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
2519 return _backend._onQueueEmpty(enqueuer, recentClasses);
2520 }
2521
2522 @override
2523 WorldImpact registerUsedElement(MemberElement member) {
2524 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
2525 _registerUsedElement(worldImpact, member, forResolution: true);
2526
2527 if (member.isDeferredLoaderGetter) {
2528 // TODO(sigurdm): Create a function registerLoadLibraryAccess.
2529 if (!_isLoadLibraryFunctionResolved) {
2530 _isLoadLibraryFunctionResolved = true;
2531 backendUsage.registerBackendImpact(worldImpact, impacts.loadLibrary);
2532 }
2533 }
2534
2535 // Enable isolate support if we start using something from the isolate
2536 // library, or timers for the async library. We exclude constant fields,
2537 // which are ending here because their initializing expression is
2538 // compiled.
2539 LibraryElement library = member.library;
2540 if (!backendUsage.isIsolateInUse && !(member.isField && member.isConst)) {
2541 Uri uri = library.canonicalUri;
2542 if (uri == Uris.dart_isolate) {
2543 backendUsage.isIsolateInUse = true;
2544 worldImpact.addImpact(enableIsolateSupport());
2545 } else if (uri == Uris.dart_async) {
2546 if (member.name == '_createTimer' ||
2547 member.name == '_createPeriodicTimer') {
2548 // The [:Timer:] class uses the event queue of the isolate
2549 // library, so we make sure that event queue is generated.
2550 backendUsage.isIsolateInUse = true;
2551 worldImpact.addImpact(enableIsolateSupport());
2552 }
2553 }
2554 }
2555
2556 if (member.isGetter && member.name == Identifiers.runtimeType_) {
2557 // Enable runtime type support if we discover a getter called
2558 // runtimeType. We have to enable runtime type before hitting the
2559 // codegen, so that constructors know whether they need to generate code
2560 // for runtime type.
2561 backendUsage.isRuntimeTypeUsed = true;
2562 // TODO(ahe): Record precise dependency here.
2563 worldImpact.addImpact(registerRuntimeType());
2564 }
2565
2566 return worldImpact;
2567 }
2568
2569 WorldImpact enableIsolateSupport() =>
2570 _backend.enableIsolateSupport(forResolution: true);
2571
2572 /// Called to register that the `runtimeType` property has been accessed. Any
2573 /// backend specific [WorldImpact] of this is returned.
2574 WorldImpact registerRuntimeType() {
2575 return backendUsage.createImpactFor(impacts.runtimeTypeSupport);
2576 }
2577
2578 WorldImpact registerClosureWithFreeTypeVariables(MethodElement closure) {
2579 return _registerComputeSignature();
2580 }
2581
2582 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod,
2583 {bool forResolution}) {
2584 return _registerComputeSignature();
2585 }
2586
2587 @override
2588 WorldImpact registerImplementedClass(ClassEntity cls) {
2589 return _processClass(cls, forResolution: true);
2590 }
2591
2592 @override
2593 WorldImpact registerInstantiatedClass(ClassEntity cls) {
2594 return _processClass(cls, forResolution: true);
2595 }
2596
2597 /// Compute the [WorldImpact] for backend helper methods.
2598 WorldImpact computeHelpersImpact() {
2599 assert(helpers.interceptorsLibrary != null);
2600 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
2601 // TODO(ngeoffray): Not enqueuing those two classes currently make
2602 // the compiler potentially crash. However, any reasonable program
2603 // will instantiate those two classes.
2604 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true);
2605 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true);
2606 if (options.enableTypeAssertions) {
2607 backendUsage.registerBackendImpact(
2608 impactBuilder, impacts.enableTypeAssertions);
2609 }
2610
2611 if (JavaScriptBackend.TRACE_CALLS) {
2612 backendUsage.registerBackendImpact(impactBuilder, impacts.traceHelper);
2613 }
2614 backendUsage.registerBackendImpact(
2615 impactBuilder, impacts.assertUnreachable);
2616 _registerCheckedModeHelpers(impactBuilder);
2617 return impactBuilder;
2618 }
2619
2620 /// Called to register a `noSuchMethod` implementation.
2621 void registerNoSuchMethod(MethodElement noSuchMethod) {
2622 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod);
2623 }
2624
2625 void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) {
2626 // We register all the helpers in the resolution queue.
2627 // TODO(13155): Find a way to register fewer helpers.
2628 List<Element> staticUses = <Element>[];
2629 for (CheckedModeHelper helper in CheckedModeHelpers.helpers) {
2630 staticUses.add(helper.getStaticUse(helpers).element);
2631 }
2632 backendUsage.registerBackendImpact(
2633 impactBuilder, new BackendImpact(globalUses: staticUses));
2634 }
2635 }
2636
2637 class CodegenEnqueuerListener extends EnqueuerListenerBase {
2638 CodegenEnqueuerListener(JavaScriptBackend backend) : super(backend);
2639
2640 // TODO(johnniwinther): Change these to final fields.
2641 LookupMapAnalysis get lookupMapAnalysis => _backend.lookupMapAnalysis;
2642 DumpInfoTask get dumpInfoTask => _backend.compiler.dumpInfoTask;
2643
2644 @override
2645 void registerInstantiatedType(ResolutionInterfaceType type,
2646 {bool isGlobal: false}) {
2647 lookupMapAnalysis.registerInstantiatedType(type);
2648 }
2649
2650 @override
2651 bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {
2652 // TODO(johnniwinther): Avoid the need for accessing [_backend].
2653 return _backend._onQueueEmpty(enqueuer, recentClasses);
2654 }
2655
2656 @override
2657 WorldImpact registerUsedElement(MemberElement member) {
2658 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl();
2659 _registerUsedElement(worldImpact, member, forResolution: false);
2660
2661 // TODO(sigmund): add other missing dependencies (internals, selectors
2662 // enqueued after allocations).
2663 dumpInfoTask.registerDependency(member);
2664
2665 return worldImpact;
2666 }
2667
2668 WorldImpact registerClosureWithFreeTypeVariables(MethodElement closure) {
2669 if (methodNeedsRti(closure)) {
2670 return _registerComputeSignature();
2671 }
2672 return const WorldImpact();
2673 }
2674
2675 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod) {
2676 if (methodNeedsRti(callMethod)) {
2677 return _registerComputeSignature();
2678 }
2679 return const WorldImpact();
2680 }
2681
2682 @override
2683 WorldImpact registerImplementedClass(ClassEntity cls) {
2684 WorldImpact worldImpact = _processClass(cls, forResolution: false);
2685 lookupMapAnalysis.registerInstantiatedClass(cls);
2686 return worldImpact;
2687 }
2688
2689 @override
2690 WorldImpact registerInstantiatedClass(ClassEntity cls) {
2691 WorldImpact worldImpact = _processClass(cls, forResolution: false);
2692 lookupMapAnalysis.registerInstantiatedClass(cls);
2693 return worldImpact;
2694 }
2695
2696 // TODO(johnniwinther): Avoid the need for accessing [_backend].
2697 bool methodNeedsRti(FunctionElement function) =>
2698 _backend.methodNeedsRti(function);
2699 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/type_graph_nodes.dart ('k') | pkg/compiler/lib/src/js_backend/backend_usage.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698