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

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

Issue 1450843002: Revert "Limit interceptedElements to instantiated members only." (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 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 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 bool needToInitializeDispatchProperty = false; 338 bool needToInitializeDispatchProperty = false;
339 339
340 final Namer namer; 340 final Namer namer;
341 341
342 /** 342 /**
343 * A collection of selectors that must have a one shot interceptor 343 * A collection of selectors that must have a one shot interceptor
344 * generated. 344 * generated.
345 */ 345 */
346 final Map<jsAst.Name, Selector> oneShotInterceptors; 346 final Map<jsAst.Name, Selector> oneShotInterceptors;
347 347
348 /// All known intercepted members. Collected during resolution. 348 /**
349 final Map<String, Set<Element>> _interceptedElements = 349 * The members of instantiated interceptor classes: maps a member name to the
350 <String, Set<Element>>{}; 350 * list of members that have that name. This map is used by the codegen to
351 351 * know whether a send must be intercepted or not.
352 /// Cache for all instantiated intercepted members for [interceptedElements]. 352 */
353 Map<String, Set<Element>> _instantiatedInterceptedElements; 353 final Map<String, Set<Element>> interceptedElements;
354 354
355 /** 355 /**
356 * The members of mixin classes that are mixed into an instantiated 356 * The members of mixin classes that are mixed into an instantiated
357 * interceptor class. This is a cached subset of [interceptedElements]. 357 * interceptor class. This is a cached subset of [interceptedElements].
358 * 358 *
359 * Mixin methods are not specialized for the class they are mixed into. 359 * Mixin methods are not specialized for the class they are mixed into.
360 * Methods mixed into intercepted classes thus always make use of the explicit 360 * Methods mixed into intercepted classes thus always make use of the explicit
361 * receiver argument, even when mixed into non-interceptor classes. 361 * receiver argument, even when mixed into non-interceptor classes.
362 * 362 *
363 * These members must be invoked with a correct explicit receiver even when 363 * These members must be invoked with a correct explicit receiver even when
364 * the receiver is not an intercepted class. 364 * the receiver is not an intercepted class.
365 */ 365 */
366 final Map<String, Set<Element>> _interceptedMixinElements = 366 final Map<String, Set<Element>> interceptedMixinElements =
367 new Map<String, Set<Element>>(); 367 new Map<String, Set<Element>>();
368 368
369 /** 369 /**
370 * A map of specialized versions of the [getInterceptorMethod]. 370 * A map of specialized versions of the [getInterceptorMethod].
371 * Since [getInterceptorMethod] is a hot method at runtime, we're 371 * Since [getInterceptorMethod] is a hot method at runtime, we're
372 * always specializing it based on the incoming type. The keys in 372 * always specializing it based on the incoming type. The keys in
373 * the map are the names of these specialized versions. Note that 373 * the map are the names of these specialized versions. Note that
374 * the generic version that contains all possible type checks is 374 * the generic version that contains all possible type checks is
375 * also stored in this map. 375 * also stored in this map.
376 */ 376 */
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 final SourceInformationStrategy sourceInformationStrategy; 505 final SourceInformationStrategy sourceInformationStrategy;
506 506
507 final BackendHelpers helpers; 507 final BackendHelpers helpers;
508 final BackendImpacts impacts; 508 final BackendImpacts impacts;
509 509
510 JavaScriptBackend(Compiler compiler, 510 JavaScriptBackend(Compiler compiler,
511 {bool generateSourceMap: true, 511 {bool generateSourceMap: true,
512 bool useStartupEmitter: false}) 512 bool useStartupEmitter: false})
513 : namer = determineNamer(compiler), 513 : namer = determineNamer(compiler),
514 oneShotInterceptors = new Map<jsAst.Name, Selector>(), 514 oneShotInterceptors = new Map<jsAst.Name, Selector>(),
515 interceptedElements = new Map<String, Set<Element>>(),
515 rti = new _RuntimeTypes(compiler), 516 rti = new _RuntimeTypes(compiler),
516 rtiEncoder = new _RuntimeTypesEncoder(compiler), 517 rtiEncoder = new _RuntimeTypesEncoder(compiler),
517 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), 518 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(),
518 annotations = new Annotations(compiler), 519 annotations = new Annotations(compiler),
519 this.sourceInformationStrategy = 520 this.sourceInformationStrategy =
520 generateSourceMap 521 generateSourceMap
521 ? (useNewSourceInfo 522 ? (useNewSourceInfo
522 ? const PositionSourceInformationStrategy() 523 ? const PositionSourceInformationStrategy()
523 : const StartEndSourceInformationStrategy()) 524 : const StartEndSourceInformationStrategy())
524 : const JavaScriptSourceInformationStrategy(), 525 : const JavaScriptSourceInformationStrategy(),
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 } 839 }
839 840
840 bool isInterceptedName(String name) { 841 bool isInterceptedName(String name) {
841 return interceptedElements[name] != null; 842 return interceptedElements[name] != null;
842 } 843 }
843 844
844 bool isInterceptedSelector(Selector selector) { 845 bool isInterceptedSelector(Selector selector) {
845 return interceptedElements[selector.name] != null; 846 return interceptedElements[selector.name] != null;
846 } 847 }
847 848
848 /// The members of instantiated interceptor classes: maps a member name to the
849 /// list of members that have that name. This map is used by the codegen to
850 /// know whether a send must be intercepted or not.
851 Map<String, Set<Element>> get interceptedElements {
852 assert(compiler.enqueuer.resolution.queueIsClosed);
853 if (_instantiatedInterceptedElements == null) {
854 _instantiatedInterceptedElements = <String, Set<Element>>{};
855 _interceptedElements.forEach((String name, Set<Element> members) {
856 Set<Element> instantiatedMembers = new Set<Element>();
857 for (Element member in members) {
858 if (compiler.world.isInstantiated(member.enclosingClass)) {
859 instantiatedMembers.add(member);
860 }
861 }
862 if (instantiatedMembers.isNotEmpty) {
863 _instantiatedInterceptedElements[name] = instantiatedMembers;
864 }
865 });
866 }
867 return _instantiatedInterceptedElements;
868 }
869
870 /** 849 /**
871 * Returns `true` iff [selector] matches an element defined in a class mixed 850 * Returns `true` iff [selector] matches an element defined in a class mixed
872 * into an intercepted class. These selectors are not eligible for the 'dummy 851 * into an intercepted class. These selectors are not eligible for the 'dummy
873 * explicit receiver' optimization. 852 * explicit receiver' optimization.
874 */ 853 */
875 bool isInterceptedMixinSelector(Selector selector, TypeMask mask) { 854 bool isInterceptedMixinSelector(Selector selector, TypeMask mask) {
876 Set<Element> elements = _interceptedMixinElements.putIfAbsent( 855 Set<Element> elements = interceptedMixinElements.putIfAbsent(
877 selector.name, 856 selector.name,
878 () { 857 () {
879 Set<Element> elements = interceptedElements[selector.name]; 858 Set<Element> elements = interceptedElements[selector.name];
880 if (elements == null) return null; 859 if (elements == null) return null;
881 return elements 860 return elements
882 .where((element) => 861 .where((element) =>
883 classesMixedIntoInterceptedClasses.contains( 862 classesMixedIntoInterceptedClasses.contains(
884 element.enclosingClass)) 863 element.enclosingClass))
885 .toSet(); 864 .toSet();
886 }); 865 });
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 cls.forEachMember((ClassElement classElement, Element member) { 964 cls.forEachMember((ClassElement classElement, Element member) {
986 if (member.name == Identifiers.call) { 965 if (member.name == Identifiers.call) {
987 reporter.reportErrorMessage( 966 reporter.reportErrorMessage(
988 member, 967 member,
989 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS); 968 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS);
990 return; 969 return;
991 } 970 }
992 if (member.isSynthesized) return; 971 if (member.isSynthesized) return;
993 // All methods on [Object] are shadowed by [Interceptor]. 972 // All methods on [Object] are shadowed by [Interceptor].
994 if (classElement == coreClasses.objectClass) return; 973 if (classElement == coreClasses.objectClass) return;
995 Set<Element> set = _interceptedElements.putIfAbsent( 974 Set<Element> set = interceptedElements.putIfAbsent(
996 member.name, () => new Setlet<Element>()); 975 member.name, () => new Set<Element>());
997 set.add(member); 976 set.add(member);
998 }, 977 },
999 includeSuperAndInjectedMembers: true); 978 includeSuperAndInjectedMembers: true);
1000 979
1001 // Walk superclass chain to find mixins. 980 // Walk superclass chain to find mixins.
1002 for (; cls != null; cls = cls.superclass) { 981 for (; cls != null; cls = cls.superclass) {
1003 if (cls.isMixinApplication) { 982 if (cls.isMixinApplication) {
1004 MixinApplicationElement mixinApplication = cls; 983 MixinApplicationElement mixinApplication = cls;
1005 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); 984 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin);
1006 } 985 }
1007 } 986 }
1008 } 987 }
1009 } 988 }
1010 989
1011 void addInterceptors(ClassElement cls, 990 void addInterceptors(ClassElement cls,
1012 Enqueuer enqueuer, 991 Enqueuer enqueuer,
1013 Registry registry) { 992 Registry registry) {
1014 if (enqueuer.isResolutionQueue) { 993 if (enqueuer.isResolutionQueue) {
1015 _interceptedClasses.add(helpers.jsInterceptorClass); 994 _interceptedClasses.add(helpers.jsInterceptorClass);
1016 _interceptedClasses.add(cls); 995 _interceptedClasses.add(cls);
1017 cls.ensureResolved(resolution); 996 cls.ensureResolved(resolution);
1018 cls.forEachMember((ClassElement classElement, Element member) { 997 cls.forEachMember((ClassElement classElement, Element member) {
1019 // All methods on [Object] are shadowed by [Interceptor]. 998 // All methods on [Object] are shadowed by [Interceptor].
1020 if (classElement == coreClasses.objectClass) return; 999 if (classElement == coreClasses.objectClass) return;
1021 Set<Element> set = _interceptedElements.putIfAbsent( 1000 Set<Element> set = interceptedElements.putIfAbsent(
1022 member.name, () => new Setlet<Element>()); 1001 member.name, () => new Set<Element>());
1023 set.add(member); 1002 set.add(member);
1024 }, 1003 },
1025 includeSuperAndInjectedMembers: true); 1004 includeSuperAndInjectedMembers: true);
1026 } 1005 }
1027 enqueueClass(enqueuer, cls, registry); 1006 enqueueClass(enqueuer, cls, registry);
1028 } 1007 }
1029 1008
1030 Set<ClassElement> get interceptedClasses { 1009 Set<ClassElement> get interceptedClasses {
1031 assert(compiler.enqueuer.resolution.queueIsClosed); 1010 assert(compiler.enqueuer.resolution.queueIsClosed);
1032 return _interceptedClasses; 1011 return _interceptedClasses;
(...skipping 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after
3093 } 3072 }
3094 } 3073 }
3095 3074
3096 /// Records that [constant] is used by the element behind [registry]. 3075 /// Records that [constant] is used by the element behind [registry].
3097 class Dependency { 3076 class Dependency {
3098 final ConstantValue constant; 3077 final ConstantValue constant;
3099 final Element annotatedElement; 3078 final Element annotatedElement;
3100 3079
3101 const Dependency(this.constant, this.annotatedElement); 3080 const Dependency(this.constant, this.annotatedElement);
3102 } 3081 }
OLDNEW
« no previous file with comments | « no previous file | tests/compiler/dart2js_extra/dart2js_extra.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698