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

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

Issue 1418643008: 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 /** 348 /// All known intercepted members. Collected during resolution.
349 * The members of instantiated interceptor classes: maps a member name to the 349 final Map<String, Set<Element>> _interceptedElements =
350 * list of members that have that name. This map is used by the codegen to 350 <String, Set<Element>>{};
351 * know whether a send must be intercepted or not. 351
352 */ 352 /// Cache for all instantiated intercepted members for [interceptedElements].
353 final Map<String, Set<Element>> interceptedElements; 353 Map<String, Set<Element>> _instantiatedInterceptedElements;
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>>(),
516 rti = new _RuntimeTypes(compiler), 515 rti = new _RuntimeTypes(compiler),
517 rtiEncoder = new _RuntimeTypesEncoder(compiler), 516 rtiEncoder = new _RuntimeTypesEncoder(compiler),
518 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), 517 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(),
519 annotations = new Annotations(compiler), 518 annotations = new Annotations(compiler),
520 this.sourceInformationStrategy = 519 this.sourceInformationStrategy =
521 generateSourceMap 520 generateSourceMap
522 ? (useNewSourceInfo 521 ? (useNewSourceInfo
523 ? const PositionSourceInformationStrategy() 522 ? const PositionSourceInformationStrategy()
524 : const StartEndSourceInformationStrategy()) 523 : const StartEndSourceInformationStrategy())
525 : const JavaScriptSourceInformationStrategy(), 524 : const JavaScriptSourceInformationStrategy(),
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 } 838 }
840 839
841 bool isInterceptedName(String name) { 840 bool isInterceptedName(String name) {
842 return interceptedElements[name] != null; 841 return interceptedElements[name] != null;
843 } 842 }
844 843
845 bool isInterceptedSelector(Selector selector) { 844 bool isInterceptedSelector(Selector selector) {
846 return interceptedElements[selector.name] != null; 845 return interceptedElements[selector.name] != null;
847 } 846 }
848 847
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
849 /** 870 /**
850 * Returns `true` iff [selector] matches an element defined in a class mixed 871 * Returns `true` iff [selector] matches an element defined in a class mixed
851 * into an intercepted class. These selectors are not eligible for the 'dummy 872 * into an intercepted class. These selectors are not eligible for the 'dummy
852 * explicit receiver' optimization. 873 * explicit receiver' optimization.
853 */ 874 */
854 bool isInterceptedMixinSelector(Selector selector, TypeMask mask) { 875 bool isInterceptedMixinSelector(Selector selector, TypeMask mask) {
855 Set<Element> elements = interceptedMixinElements.putIfAbsent( 876 Set<Element> elements = _interceptedMixinElements.putIfAbsent(
856 selector.name, 877 selector.name,
857 () { 878 () {
858 Set<Element> elements = interceptedElements[selector.name]; 879 Set<Element> elements = interceptedElements[selector.name];
859 if (elements == null) return null; 880 if (elements == null) return null;
860 return elements 881 return elements
861 .where((element) => 882 .where((element) =>
862 classesMixedIntoInterceptedClasses.contains( 883 classesMixedIntoInterceptedClasses.contains(
863 element.enclosingClass)) 884 element.enclosingClass))
864 .toSet(); 885 .toSet();
865 }); 886 });
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 cls.forEachMember((ClassElement classElement, Element member) { 985 cls.forEachMember((ClassElement classElement, Element member) {
965 if (member.name == Identifiers.call) { 986 if (member.name == Identifiers.call) {
966 reporter.reportErrorMessage( 987 reporter.reportErrorMessage(
967 member, 988 member,
968 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS); 989 MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS);
969 return; 990 return;
970 } 991 }
971 if (member.isSynthesized) return; 992 if (member.isSynthesized) return;
972 // All methods on [Object] are shadowed by [Interceptor]. 993 // All methods on [Object] are shadowed by [Interceptor].
973 if (classElement == coreClasses.objectClass) return; 994 if (classElement == coreClasses.objectClass) return;
974 Set<Element> set = interceptedElements.putIfAbsent( 995 Set<Element> set = _interceptedElements.putIfAbsent(
975 member.name, () => new Set<Element>()); 996 member.name, () => new Setlet<Element>());
976 set.add(member); 997 set.add(member);
977 }, 998 },
978 includeSuperAndInjectedMembers: true); 999 includeSuperAndInjectedMembers: true);
979 1000
980 // Walk superclass chain to find mixins. 1001 // Walk superclass chain to find mixins.
981 for (; cls != null; cls = cls.superclass) { 1002 for (; cls != null; cls = cls.superclass) {
982 if (cls.isMixinApplication) { 1003 if (cls.isMixinApplication) {
983 MixinApplicationElement mixinApplication = cls; 1004 MixinApplicationElement mixinApplication = cls;
984 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); 1005 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin);
985 } 1006 }
986 } 1007 }
987 } 1008 }
988 } 1009 }
989 1010
990 void addInterceptors(ClassElement cls, 1011 void addInterceptors(ClassElement cls,
991 Enqueuer enqueuer, 1012 Enqueuer enqueuer,
992 Registry registry) { 1013 Registry registry) {
993 if (enqueuer.isResolutionQueue) { 1014 if (enqueuer.isResolutionQueue) {
994 _interceptedClasses.add(helpers.jsInterceptorClass); 1015 _interceptedClasses.add(helpers.jsInterceptorClass);
995 _interceptedClasses.add(cls); 1016 _interceptedClasses.add(cls);
996 cls.ensureResolved(resolution); 1017 cls.ensureResolved(resolution);
997 cls.forEachMember((ClassElement classElement, Element member) { 1018 cls.forEachMember((ClassElement classElement, Element member) {
998 // All methods on [Object] are shadowed by [Interceptor]. 1019 // All methods on [Object] are shadowed by [Interceptor].
999 if (classElement == coreClasses.objectClass) return; 1020 if (classElement == coreClasses.objectClass) return;
1000 Set<Element> set = interceptedElements.putIfAbsent( 1021 Set<Element> set = _interceptedElements.putIfAbsent(
1001 member.name, () => new Set<Element>()); 1022 member.name, () => new Setlet<Element>());
1002 set.add(member); 1023 set.add(member);
1003 }, 1024 },
1004 includeSuperAndInjectedMembers: true); 1025 includeSuperAndInjectedMembers: true);
1005 } 1026 }
1006 enqueueClass(enqueuer, cls, registry); 1027 enqueueClass(enqueuer, cls, registry);
1007 } 1028 }
1008 1029
1009 Set<ClassElement> get interceptedClasses { 1030 Set<ClassElement> get interceptedClasses {
1010 assert(compiler.enqueuer.resolution.queueIsClosed); 1031 assert(compiler.enqueuer.resolution.queueIsClosed);
1011 return _interceptedClasses; 1032 return _interceptedClasses;
(...skipping 2029 matching lines...) Expand 10 before | Expand all | Expand 10 after
3041 } 3062 }
3042 } 3063 }
3043 3064
3044 /// Records that [constant] is used by the element behind [registry]. 3065 /// Records that [constant] is used by the element behind [registry].
3045 class Dependency { 3066 class Dependency {
3046 final ConstantValue constant; 3067 final ConstantValue constant;
3047 final Element annotatedElement; 3068 final Element annotatedElement;
3048 3069
3049 const Dependency(this.constant, this.annotatedElement); 3070 const Dependency(this.constant, this.annotatedElement);
3050 } 3071 }
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