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

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

Issue 2814453005: Merge CommonElements and BackendHelpers! (Closed)
Patch Set: comments and re-merge, take two Created 3 years, 8 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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.interceptor_data; 5 library js_backend.interceptor_data;
6 6
7 import '../common/names.dart' show Identifiers; 7 import '../common/names.dart' show Identifiers;
8 import '../common_elements.dart' show CommonElements, ElementEnvironment; 8 import '../common_elements.dart' show CommonElements, ElementEnvironment;
9 import '../elements/elements.dart' show MemberElement; 9 import '../elements/elements.dart' show MemberElement;
10 import '../elements/entities.dart'; 10 import '../elements/entities.dart';
11 import '../elements/types.dart'; 11 import '../elements/types.dart';
12 import '../js/js.dart' as jsAst; 12 import '../js/js.dart' as jsAst;
13 import '../types/types.dart' show TypeMask; 13 import '../types/types.dart' show TypeMask;
14 import '../universe/selector.dart'; 14 import '../universe/selector.dart';
15 import '../world.dart' show ClosedWorld; 15 import '../world.dart' show ClosedWorld;
16 import 'backend_helpers.dart';
17 import 'namer.dart'; 16 import 'namer.dart';
18 import 'native_data.dart'; 17 import 'native_data.dart';
19 18
20 abstract class InterceptorData { 19 abstract class InterceptorData {
21 /// Returns `true` if [cls] is an intercepted class. 20 /// Returns `true` if [cls] is an intercepted class.
22 bool isInterceptedClass(ClassEntity element); 21 bool isInterceptedClass(ClassEntity element);
23 22
24 bool isInterceptedMethod(MemberEntity element); 23 bool isInterceptedMethod(MemberEntity element);
25 bool fieldHasInterceptedGetter(FieldEntity element); 24 bool fieldHasInterceptedGetter(FieldEntity element);
26 bool fieldHasInterceptedSetter(FieldEntity element); 25 bool fieldHasInterceptedSetter(FieldEntity element);
(...skipping 15 matching lines...) Expand all
42 } 41 }
43 42
44 abstract class InterceptorDataBuilder { 43 abstract class InterceptorDataBuilder {
45 void addInterceptors(ClassEntity cls); 44 void addInterceptors(ClassEntity cls);
46 void addInterceptorsForNativeClassMembers(ClassEntity cls); 45 void addInterceptorsForNativeClassMembers(ClassEntity cls);
47 InterceptorData onResolutionComplete(ClosedWorld closedWorld); 46 InterceptorData onResolutionComplete(ClosedWorld closedWorld);
48 } 47 }
49 48
50 class InterceptorDataImpl implements InterceptorData { 49 class InterceptorDataImpl implements InterceptorData {
51 final NativeBasicData _nativeData; 50 final NativeBasicData _nativeData;
52 final BackendHelpers _helpers; 51 final CommonElements _commonElements;
53 final ClosedWorld _closedWorld; 52 final ClosedWorld _closedWorld;
54 53
55 /// The members of instantiated interceptor classes: maps a member name to the 54 /// The members of instantiated interceptor classes: maps a member name to the
56 /// list of members that have that name. This map is used by the codegen to 55 /// list of members that have that name. This map is used by the codegen to
57 /// know whether a send must be intercepted or not. 56 /// know whether a send must be intercepted or not.
58 final Map<String, Set<MemberEntity>> _interceptedElements; 57 final Map<String, Set<MemberEntity>> _interceptedElements;
59 58
60 /// Set of classes whose methods are intercepted. 59 /// Set of classes whose methods are intercepted.
61 final Set<ClassEntity> _interceptedClasses; 60 final Set<ClassEntity> _interceptedClasses;
62 61
(...skipping 14 matching lines...) Expand all
77 final Map<String, Set<MemberEntity>> _interceptedMixinElements = 76 final Map<String, Set<MemberEntity>> _interceptedMixinElements =
78 new Map<String, Set<MemberEntity>>(); 77 new Map<String, Set<MemberEntity>>();
79 78
80 final Map<String, Set<ClassEntity>> _interceptedClassesCache = 79 final Map<String, Set<ClassEntity>> _interceptedClassesCache =
81 new Map<String, Set<ClassEntity>>(); 80 new Map<String, Set<ClassEntity>>();
82 81
83 final Set<ClassEntity> _noClasses = new Set<ClassEntity>(); 82 final Set<ClassEntity> _noClasses = new Set<ClassEntity>();
84 83
85 InterceptorDataImpl( 84 InterceptorDataImpl(
86 this._nativeData, 85 this._nativeData,
87 this._helpers, 86 this._commonElements,
88 this._closedWorld, 87 this._closedWorld,
89 this._interceptedElements, 88 this._interceptedElements,
90 this._interceptedClasses, 89 this._interceptedClasses,
91 this._classesMixedIntoInterceptedClasses); 90 this._classesMixedIntoInterceptedClasses);
92 91
93 bool isInterceptedMethod(MemberElement element) { 92 bool isInterceptedMethod(MemberElement element) {
94 if (!element.isInstanceMember) return false; 93 if (!element.isInstanceMember) return false;
95 if (element.isGenerativeConstructorBody) { 94 if (element.isGenerativeConstructorBody) {
96 return _nativeData.isNativeOrExtendsNative(element.enclosingClass); 95 return _nativeData.isNativeOrExtendsNative(element.enclosingClass);
97 } 96 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 if (elements.isEmpty) return false; 131 if (elements.isEmpty) return false;
133 return elements.any((element) { 132 return elements.any((element) {
134 return selector.applies(element) && 133 return selector.applies(element) &&
135 (mask == null || mask.canHit(element, selector, _closedWorld)); 134 (mask == null || mask.canHit(element, selector, _closedWorld));
136 }); 135 });
137 } 136 }
138 137
139 /// True if the given class is an internal class used for type inference 138 /// True if the given class is an internal class used for type inference
140 /// and never exists at runtime. 139 /// and never exists at runtime.
141 bool _isCompileTimeOnlyClass(ClassEntity class_) { 140 bool _isCompileTimeOnlyClass(ClassEntity class_) {
142 return class_ == _helpers.jsPositiveIntClass || 141 return class_ == _commonElements.jsPositiveIntClass ||
143 class_ == _helpers.jsUInt32Class || 142 class_ == _commonElements.jsUInt32Class ||
144 class_ == _helpers.jsUInt31Class || 143 class_ == _commonElements.jsUInt31Class ||
145 class_ == _helpers.jsFixedArrayClass || 144 class_ == _commonElements.jsFixedArrayClass ||
146 class_ == _helpers.jsUnmodifiableArrayClass || 145 class_ == _commonElements.jsUnmodifiableArrayClass ||
147 class_ == _helpers.jsMutableArrayClass || 146 class_ == _commonElements.jsMutableArrayClass ||
148 class_ == _helpers.jsExtendableArrayClass; 147 class_ == _commonElements.jsExtendableArrayClass;
149 } 148 }
150 149
151 /// Returns a set of interceptor classes that contain a member named [name] 150 /// Returns a set of interceptor classes that contain a member named [name]
152 /// 151 ///
153 /// Returns an empty set if there is no class. Do not modify the returned set. 152 /// Returns an empty set if there is no class. Do not modify the returned set.
154 Set<ClassEntity> getInterceptedClassesOn(String name) { 153 Set<ClassEntity> getInterceptedClassesOn(String name) {
155 Set<MemberEntity> intercepted = _interceptedElements[name]; 154 Set<MemberEntity> intercepted = _interceptedElements[name];
156 if (intercepted == null) return _noClasses; 155 if (intercepted == null) return _noClasses;
157 return _interceptedClassesCache.putIfAbsent(name, () { 156 return _interceptedClassesCache.putIfAbsent(name, () {
158 // Populate the cache by running through all the elements and 157 // Populate the cache by running through all the elements and
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (!type.treatAsRaw) return false; 208 if (!type.treatAsRaw) return false;
210 InterfaceType interfaceType = type; 209 InterfaceType interfaceType = type;
211 ClassEntity classElement = interfaceType.element; 210 ClassEntity classElement = interfaceType.element;
212 if (isInterceptedClass(classElement)) return false; 211 if (isInterceptedClass(classElement)) return false;
213 return _closedWorld.hasOnlySubclasses(classElement); 212 return _closedWorld.hasOnlySubclasses(classElement);
214 } 213 }
215 } 214 }
216 215
217 class InterceptorDataBuilderImpl implements InterceptorDataBuilder { 216 class InterceptorDataBuilderImpl implements InterceptorDataBuilder {
218 final NativeBasicData _nativeData; 217 final NativeBasicData _nativeData;
219 final BackendHelpers _helpers;
220 final ElementEnvironment _elementEnvironment; 218 final ElementEnvironment _elementEnvironment;
221 final CommonElements _commonElements; 219 final CommonElements _commonElements;
222 220
223 /// The members of instantiated interceptor classes: maps a member name to the 221 /// The members of instantiated interceptor classes: maps a member name to the
224 /// list of members that have that name. This map is used by the codegen to 222 /// list of members that have that name. This map is used by the codegen to
225 /// know whether a send must be intercepted or not. 223 /// know whether a send must be intercepted or not.
226 final Map<String, Set<MemberEntity>> _interceptedElements = 224 final Map<String, Set<MemberEntity>> _interceptedElements =
227 <String, Set<MemberEntity>>{}; 225 <String, Set<MemberEntity>>{};
228 226
229 /// Set of classes whose methods are intercepted. 227 /// Set of classes whose methods are intercepted.
230 final Set<ClassEntity> _interceptedClasses = new Set<ClassEntity>(); 228 final Set<ClassEntity> _interceptedClasses = new Set<ClassEntity>();
231 229
232 /// Set of classes used as mixins on intercepted (native and primitive) 230 /// Set of classes used as mixins on intercepted (native and primitive)
233 /// classes. Methods on these classes might also be mixed in to regular Dart 231 /// classes. Methods on these classes might also be mixed in to regular Dart
234 /// (unintercepted) classes. 232 /// (unintercepted) classes.
235 final Set<ClassEntity> _classesMixedIntoInterceptedClasses = 233 final Set<ClassEntity> _classesMixedIntoInterceptedClasses =
236 new Set<ClassEntity>(); 234 new Set<ClassEntity>();
237 235
238 InterceptorDataBuilderImpl(this._nativeData, this._helpers, 236 InterceptorDataBuilderImpl(
239 this._elementEnvironment, this._commonElements); 237 this._nativeData, this._elementEnvironment, this._commonElements);
240 238
241 InterceptorData onResolutionComplete(ClosedWorld closedWorld) { 239 InterceptorData onResolutionComplete(ClosedWorld closedWorld) {
242 return new InterceptorDataImpl( 240 return new InterceptorDataImpl(
243 _nativeData, 241 _nativeData,
244 _helpers, 242 _commonElements,
245 closedWorld, 243 closedWorld,
246 _interceptedElements, 244 _interceptedElements,
247 _interceptedClasses, 245 _interceptedClasses,
248 _classesMixedIntoInterceptedClasses); 246 _classesMixedIntoInterceptedClasses);
249 } 247 }
250 248
251 void addInterceptorsForNativeClassMembers(ClassEntity cls) { 249 void addInterceptorsForNativeClassMembers(ClassEntity cls) {
252 _elementEnvironment.forEachClassMember(cls, 250 _elementEnvironment.forEachClassMember(cls,
253 (ClassEntity cls, MemberEntity member) { 251 (ClassEntity cls, MemberEntity member) {
254 if (member.name == Identifiers.call) return; 252 if (member.name == Identifiers.call) return;
(...skipping 14 matching lines...) Expand all
269 if (_interceptedClasses.add(cls)) { 267 if (_interceptedClasses.add(cls)) {
270 _elementEnvironment.forEachClassMember(cls, 268 _elementEnvironment.forEachClassMember(cls,
271 (ClassEntity cls, MemberEntity member) { 269 (ClassEntity cls, MemberEntity member) {
272 // All methods on [Object] are shadowed by [Interceptor]. 270 // All methods on [Object] are shadowed by [Interceptor].
273 if (cls == _commonElements.objectClass) return; 271 if (cls == _commonElements.objectClass) return;
274 Set<MemberEntity> set = _interceptedElements.putIfAbsent( 272 Set<MemberEntity> set = _interceptedElements.putIfAbsent(
275 member.name, () => new Set<MemberEntity>()); 273 member.name, () => new Set<MemberEntity>());
276 set.add(member); 274 set.add(member);
277 }); 275 });
278 } 276 }
279 _interceptedClasses.add(_helpers.jsInterceptorClass); 277 _interceptedClasses.add(_commonElements.jsInterceptorClass);
280 } 278 }
281 } 279 }
282 280
283 class OneShotInterceptorData { 281 class OneShotInterceptorData {
284 final InterceptorData _interceptorData; 282 final InterceptorData _interceptorData;
285 final BackendHelpers _helpers; 283 final CommonElements _commonElements;
286 284
287 OneShotInterceptorData(this._interceptorData, this._helpers); 285 OneShotInterceptorData(this._interceptorData, this._commonElements);
288 286
289 /// A collection of selectors that must have a one shot interceptor generated. 287 /// A collection of selectors that must have a one shot interceptor generated.
290 final Map<jsAst.Name, Selector> _oneShotInterceptors = 288 final Map<jsAst.Name, Selector> _oneShotInterceptors =
291 <jsAst.Name, Selector>{}; 289 <jsAst.Name, Selector>{};
292 290
293 Selector getOneShotInterceptorSelector(jsAst.Name name) => 291 Selector getOneShotInterceptorSelector(jsAst.Name name) =>
294 _oneShotInterceptors[name]; 292 _oneShotInterceptors[name];
295 293
296 Iterable<jsAst.Name> get oneShotInterceptorNames => 294 Iterable<jsAst.Name> get oneShotInterceptorNames =>
297 _oneShotInterceptors.keys.toList()..sort(); 295 _oneShotInterceptors.keys.toList()..sort();
(...skipping 20 matching lines...) Expand all
318 if (!_oneShotInterceptors.containsKey(name)) { 316 if (!_oneShotInterceptors.containsKey(name)) {
319 registerSpecializedGetInterceptor(classes, namer); 317 registerSpecializedGetInterceptor(classes, namer);
320 _oneShotInterceptors[name] = selector; 318 _oneShotInterceptors[name] = selector;
321 } 319 }
322 return name; 320 return name;
323 } 321 }
324 322
325 void registerSpecializedGetInterceptor( 323 void registerSpecializedGetInterceptor(
326 Set<ClassEntity> classes, Namer namer) { 324 Set<ClassEntity> classes, Namer namer) {
327 jsAst.Name name = namer.nameForGetInterceptor(classes); 325 jsAst.Name name = namer.nameForGetInterceptor(classes);
328 if (classes.contains(_helpers.jsInterceptorClass)) { 326 if (classes.contains(_commonElements.jsInterceptorClass)) {
329 // We can't use a specialized [getInterceptorMethod], so we make 327 // We can't use a specialized [getInterceptorMethod], so we make
330 // sure we emit the one with all checks. 328 // sure we emit the one with all checks.
331 _specializedGetInterceptors[name] = _interceptorData.interceptedClasses; 329 _specializedGetInterceptors[name] = _interceptorData.interceptedClasses;
332 } else { 330 } else {
333 _specializedGetInterceptors[name] = classes; 331 _specializedGetInterceptors[name] = classes;
334 } 332 }
335 } 333 }
336 } 334 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/impact_transformer.dart ('k') | pkg/compiler/lib/src/js_backend/js_interop_analysis.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698