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

Side by Side Diff: pkg/compiler/lib/src/world.dart

Issue 2968743002: Use .callMethod instead of LocalFunctionElement as key in inference (Closed)
Patch Set: Created 3 years, 5 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 dart2js.world; 5 library dart2js.world;
6 6
7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; 7 import 'closure.dart' show ClosureClassElement;
8 import 'common.dart'; 8 import 'common.dart';
9 import 'constants/constant_system.dart'; 9 import 'constants/constant_system.dart';
10 import 'common_elements.dart' show CommonElements, ElementEnvironment; 10 import 'common_elements.dart' show CommonElements, ElementEnvironment;
11 import 'elements/entities.dart'; 11 import 'elements/entities.dart';
12 import 'elements/elements.dart' 12 import 'elements/elements.dart'
13 show 13 show
14 ClassElement, 14 ClassElement,
15 Element, 15 Element,
16 MemberElement, 16 MemberElement,
17 MethodElement,
17 MixinApplicationElement, 18 MixinApplicationElement,
18 TypedefElement; 19 TypedefElement;
19 import 'elements/resolution_types.dart'; 20 import 'elements/resolution_types.dart';
20 import 'elements/types.dart'; 21 import 'elements/types.dart';
21 import 'js_backend/backend_usage.dart' show BackendUsage; 22 import 'js_backend/backend_usage.dart' show BackendUsage;
22 import 'js_backend/interceptor_data.dart' show InterceptorData; 23 import 'js_backend/interceptor_data.dart' show InterceptorData;
23 import 'js_backend/native_data.dart' show NativeData; 24 import 'js_backend/native_data.dart' show NativeData;
24 import 'ordered_typeset.dart'; 25 import 'ordered_typeset.dart';
25 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; 26 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
26 import 'universe/class_set.dart'; 27 import 'universe/class_set.dart';
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 /// Returns the single [MemberEntity] that matches a call to [selector] on a 305 /// Returns the single [MemberEntity] that matches a call to [selector] on a
305 /// receiver of type [mask]. If multiple targets exist, `null` is returned. 306 /// receiver of type [mask]. If multiple targets exist, `null` is returned.
306 MemberEntity locateSingleElement(Selector selector, TypeMask mask); 307 MemberEntity locateSingleElement(Selector selector, TypeMask mask);
307 308
308 /// Returns the single field that matches a call to [selector] on a 309 /// Returns the single field that matches a call to [selector] on a
309 /// receiver of type [mask]. If multiple targets exist or the single target 310 /// receiver of type [mask]. If multiple targets exist or the single target
310 /// is not a field, `null` is returned. 311 /// is not a field, `null` is returned.
311 FieldEntity locateSingleField(Selector selector, TypeMask mask); 312 FieldEntity locateSingleField(Selector selector, TypeMask mask);
312 313
313 /// Returns the side effects of executing [element]. 314 /// Returns the side effects of executing [element].
314 SideEffects getSideEffectsOfElement(Entity element); 315 SideEffects getSideEffectsOfElement(FunctionEntity element);
315 316
316 /// Returns the side effects of calling [selector] on a receiver of type 317 /// Returns the side effects of calling [selector] on a receiver of type
317 /// [mask]. 318 /// [mask].
318 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask); 319 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask);
319 320
320 /// Returns `true` if [element] is guaranteed not to throw an exception. 321 /// Returns `true` if [element] is guaranteed not to throw an exception.
321 bool getCannotThrow(Entity element); 322 bool getCannotThrow(FunctionEntity element);
322 323
323 /// Returns `true` if [element] is called in a loop. 324 /// Returns `true` if [element] is called in a loop.
324 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? 325 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
325 bool isCalledInLoop(Entity element); 326 // TODO(johnniwinther): Change [MemberEntity] to [FunctionEntity].
327 bool isCalledInLoop(MemberEntity element);
326 328
327 /// Returns `true` if [element] might be passed to `Function.apply`. 329 /// Returns `true` if [element] might be passed to `Function.apply`.
328 // TODO(johnniwinther): Is this 'passed invocation target` or 330 // TODO(johnniwinther): Is this 'passed invocation target` or
329 // `passed as argument`? 331 // `passed as argument`?
330 bool getMightBePassedToApply(Entity element); 332 bool getMightBePassedToApply(FunctionEntity element);
331 333
332 /// Returns a string representation of the closed world. 334 /// Returns a string representation of the closed world.
333 /// 335 ///
334 /// If [cls] is provided, the dump will contain only classes related to [cls]. 336 /// If [cls] is provided, the dump will contain only classes related to [cls].
335 String dump([ClassEntity cls]); 337 String dump([ClassEntity cls]);
336 } 338 }
337 339
338 /// Interface for computing side effects and uses of elements. This is used 340 /// Interface for computing side effects and uses of elements. This is used
339 /// during type inference to compute the [ClosedWorld] for code generation. 341 /// during type inference to compute the [ClosedWorld] for code generation.
340 abstract class ClosedWorldRefiner { 342 abstract class ClosedWorldRefiner {
341 /// The closed world being refined. 343 /// The closed world being refined.
342 ClosedWorld get closedWorld; 344 ClosedWorld get closedWorld;
343 345
344 /// Registers the side [effects] of executing [element]. 346 /// Registers the side [effects] of executing [element].
345 void registerSideEffects(Entity element, SideEffects effects); 347 void registerSideEffects(FunctionEntity element, SideEffects effects);
346 348
347 /// Registers the executing of [element] as without side effects. 349 /// Registers the executing of [element] as without side effects.
348 void registerSideEffectsFree(Entity element); 350 void registerSideEffectsFree(FunctionEntity element);
349 351
350 /// Returns the currently known side effects of executing [element]. 352 /// Returns the currently known side effects of executing [element].
351 SideEffects getCurrentlyKnownSideEffects(Entity element); 353 SideEffects getCurrentlyKnownSideEffects(FunctionEntity element);
352 354
353 /// Registers that [element] might be passed to `Function.apply`. 355 /// Registers that [element] might be passed to `Function.apply`.
354 // TODO(johnniwinther): Is this 'passed invocation target` or 356 // TODO(johnniwinther): Is this 'passed invocation target` or
355 // `passed as argument`? 357 // `passed as argument`?
356 void registerMightBePassedToApply(Entity element); 358 void registerMightBePassedToApply(FunctionEntity element);
357 359
358 /// Returns `true` if [element] might be passed to `Function.apply` given the 360 /// Returns `true` if [element] might be passed to `Function.apply` given the
359 /// currently inferred information. 361 /// currently inferred information.
360 bool getCurrentlyKnownMightBePassedToApply(Entity element); 362 bool getCurrentlyKnownMightBePassedToApply(FunctionEntity element);
361 363
362 /// Registers that [element] is called in a loop. 364 /// Registers that [element] is called in a loop.
363 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'? 365 // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
364 void addFunctionCalledInLoop(Entity element); 366 void addFunctionCalledInLoop(MemberEntity element);
365 367
366 /// Registers that [element] is guaranteed not to throw an exception. 368 /// Registers that [element] is guaranteed not to throw an exception.
367 void registerCannotThrow(Entity element); 369 void registerCannotThrow(FunctionEntity element);
368 370
369 /// Adds the closure class [cls] to the inference world. The class is 371 /// Adds the closure class [cls] to the inference world. The class is
370 /// considered directly instantiated. 372 /// considered directly instantiated.
371 void registerClosureClass(covariant ClassElement cls); 373 void registerClosureClass(covariant ClassElement cls);
372 } 374 }
373 375
374 abstract class OpenWorld implements World { 376 abstract class OpenWorld implements World {
375 /// Called to add [cls] to the set of known classes. 377 /// Called to add [cls] to the set of known classes.
376 /// 378 ///
377 /// This ensures that class hierarchy queries can be performed on [cls] and 379 /// This ensures that class hierarchy queries can be performed on [cls] and
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses; 418 final Map<ClassEntity, Set<ClassEntity>> _typesImplementedBySubclasses;
417 419
418 // We keep track of subtype and subclass relationships in four 420 // We keep track of subtype and subclass relationships in four
419 // distinct sets to make class hierarchy analysis faster. 421 // distinct sets to make class hierarchy analysis faster.
420 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes; 422 final Map<ClassEntity, ClassHierarchyNode> _classHierarchyNodes;
421 final Map<ClassEntity, ClassSet> _classSets; 423 final Map<ClassEntity, ClassSet> _classSets;
422 424
423 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache = 425 final Map<ClassEntity, Map<ClassEntity, bool>> _subtypeCoveredByCache =
424 <ClassEntity, Map<ClassEntity, bool>>{}; 426 <ClassEntity, Map<ClassEntity, bool>>{};
425 427
426 final Set<Entity> _functionsCalledInLoop = new Set<Entity>(); 428 final Set<MemberEntity> _functionsCalledInLoop = new Set<MemberEntity>();
427 final Map<Entity, SideEffects> _sideEffects = new Map<Entity, SideEffects>(); 429 final Map<FunctionEntity, SideEffects> _sideEffects =
430 new Map<FunctionEntity, SideEffects>();
428 431
429 final Set<Entity> _sideEffectsFreeElements = new Set<Entity>(); 432 final Set<FunctionEntity> _sideEffectsFreeElements =
433 new Set<FunctionEntity>();
430 434
431 final Set<Entity> _elementsThatCannotThrow = new Set<Entity>(); 435 final Set<FunctionEntity> _elementsThatCannotThrow =
436 new Set<FunctionEntity>();
432 437
433 final Set<Entity> _functionsThatMightBePassedToApply = new Set<Entity>(); 438 final Set<FunctionEntity> _functionsThatMightBePassedToApply =
439 new Set<FunctionEntity>();
434 440
435 CommonMasks _commonMasks; 441 CommonMasks _commonMasks;
436 442
437 final ElementEnvironment elementEnvironment; 443 final ElementEnvironment elementEnvironment;
438 final DartTypes dartTypes; 444 final DartTypes dartTypes;
439 final CommonElements commonElements; 445 final CommonElements commonElements;
440 446
441 // TODO(johnniwinther): Avoid this. 447 // TODO(johnniwinther): Avoid this.
442 final ResolutionWorldBuilder _resolverWorld; 448 final ResolutionWorldBuilder _resolverWorld;
443 449
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 sideEffects.setAllSideEffects(); 1080 sideEffects.setAllSideEffects();
1075 sideEffects.setDependsOnSomething(); 1081 sideEffects.setDependsOnSomething();
1076 } 1082 }
1077 } else { 1083 } else {
1078 sideEffects.add(getSideEffectsOfElement(e)); 1084 sideEffects.add(getSideEffectsOfElement(e));
1079 } 1085 }
1080 } 1086 }
1081 return sideEffects; 1087 return sideEffects;
1082 } 1088 }
1083 1089
1084 SideEffects getSideEffectsOfElement(covariant Entity element) { 1090 SideEffects getSideEffectsOfElement(FunctionEntity element) {
1085 assert(checkEntity(element)); 1091 assert(checkEntity(element));
1086 return _sideEffects.putIfAbsent(element, _makeSideEffects); 1092 return _sideEffects.putIfAbsent(element, _makeSideEffects);
1087 } 1093 }
1088 1094
1089 static SideEffects _makeSideEffects() => new SideEffects(); 1095 static SideEffects _makeSideEffects() => new SideEffects();
1090 1096
1091 @override 1097 @override
1092 SideEffects getCurrentlyKnownSideEffects(Entity element) { 1098 SideEffects getCurrentlyKnownSideEffects(FunctionEntity element) {
1093 return getSideEffectsOfElement(element); 1099 return getSideEffectsOfElement(element);
1094 } 1100 }
1095 1101
1096 void registerSideEffects(Entity element, SideEffects effects) { 1102 void registerSideEffects(FunctionEntity element, SideEffects effects) {
1097 assert(checkEntity(element)); 1103 assert(checkEntity(element));
1098 if (_sideEffectsFreeElements.contains(element)) return; 1104 if (_sideEffectsFreeElements.contains(element)) return;
1099 _sideEffects[element] = effects; 1105 _sideEffects[element] = effects;
1100 } 1106 }
1101 1107
1102 void registerSideEffectsFree(Entity element) { 1108 void registerSideEffectsFree(FunctionEntity element) {
1103 assert(checkEntity(element)); 1109 assert(checkEntity(element));
1104 _sideEffects[element] = new SideEffects.empty(); 1110 _sideEffects[element] = new SideEffects.empty();
1105 _sideEffectsFreeElements.add(element); 1111 _sideEffectsFreeElements.add(element);
1106 } 1112 }
1107 1113
1108 void addFunctionCalledInLoop(Entity element) { 1114 void addFunctionCalledInLoop(MemberEntity element) {
1109 assert(checkEntity(element)); 1115 assert(checkEntity(element));
1110 _functionsCalledInLoop.add(element); 1116 _functionsCalledInLoop.add(element);
1111 } 1117 }
1112 1118
1113 bool isCalledInLoop(Entity element) { 1119 bool isCalledInLoop(MemberEntity element) {
1114 assert(checkEntity(element)); 1120 assert(checkEntity(element));
1115 return _functionsCalledInLoop.contains(element); 1121 return _functionsCalledInLoop.contains(element);
1116 } 1122 }
1117 1123
1118 void registerCannotThrow(Entity element) { 1124 void registerCannotThrow(FunctionEntity element) {
1119 assert(checkEntity(element)); 1125 assert(checkEntity(element));
1120 _elementsThatCannotThrow.add(element); 1126 _elementsThatCannotThrow.add(element);
1121 } 1127 }
1122 1128
1123 bool getCannotThrow(Entity element) { 1129 bool getCannotThrow(FunctionEntity element) {
1124 return _elementsThatCannotThrow.contains(element); 1130 return _elementsThatCannotThrow.contains(element);
1125 } 1131 }
1126 1132
1127 void registerMightBePassedToApply(Entity element) { 1133 void registerMightBePassedToApply(FunctionEntity element) {
1128 _functionsThatMightBePassedToApply.add(element); 1134 _functionsThatMightBePassedToApply.add(element);
1129 } 1135 }
1130 1136
1131 bool getMightBePassedToApply(Entity element) { 1137 bool getMightBePassedToApply(FunctionEntity element) {
1132 // We have to check whether the element we look at was created after
1133 // type inference ran. This is currently only the case for the call
1134 // method of function classes that were generated for function
1135 // expressions. In such a case, we have to look at the original
1136 // function expressions's element.
1137 // TODO(herhut): Generate classes for function expressions earlier.
1138 if (element is SynthesizedCallMethodElementX) {
1139 return getMightBePassedToApply(element.expression);
Siggi Cherem (dart-lang) 2017/06/30 18:13:54 neat to get rid of this, but this is unrelated to
Johnni Winther 2017/06/30 19:02:02 No, this was a fix for the same kind of discrepanc
Siggi Cherem (dart-lang) 2017/06/30 20:34:36 I see - the comment above was misleading, it gave
Johnni Winther 2017/07/03 07:26:07 When the comment was written they _were_ created a
1140 }
1141 return _functionsThatMightBePassedToApply.contains(element); 1138 return _functionsThatMightBePassedToApply.contains(element);
1142 } 1139 }
1143 1140
1144 @override 1141 @override
1145 bool getCurrentlyKnownMightBePassedToApply(Entity element) { 1142 bool getCurrentlyKnownMightBePassedToApply(FunctionEntity element) {
1146 return getMightBePassedToApply(element); 1143 return getMightBePassedToApply(element);
1147 } 1144 }
1148 1145
1149 @override 1146 @override
1150 String dump([ClassEntity cls]) { 1147 String dump([ClassEntity cls]) {
1151 if (cls is! ClassElement) { 1148 if (cls is! ClassElement) {
1152 // TODO(johnniwinther): Support [cls] as a [ClassEntity]. 1149 // TODO(johnniwinther): Support [cls] as a [ClassEntity].
1153 cls = null; 1150 cls = null;
1154 } 1151 }
1155 StringBuffer sb = new StringBuffer(); 1152 StringBuffer sb = new StringBuffer();
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 if (cls != commonElements.functionClass && 1290 if (cls != commonElements.functionClass &&
1294 cls.implementsFunction(commonElements)) { 1291 cls.implementsFunction(commonElements)) {
1295 ClassSet subtypeSet = getClassSet(commonElements.functionClass); 1292 ClassSet subtypeSet = getClassSet(commonElements.functionClass);
1296 subtypeSet.addSubtype(node); 1293 subtypeSet.addSubtype(node);
1297 } 1294 }
1298 if (!node.isInstantiated && node.parentNode != null) { 1295 if (!node.isInstantiated && node.parentNode != null) {
1299 _updateSuperClassHierarchyNodeForClass(node.parentNode); 1296 _updateSuperClassHierarchyNodeForClass(node.parentNode);
1300 } 1297 }
1301 } 1298 }
1302 1299
1303 SideEffects getSideEffectsOfElement(Element element) { 1300 SideEffects getSideEffectsOfElement(covariant MethodElement element) {
1304 // The type inferrer (where the side effects are being computed), 1301 // The type inferrer (where the side effects are being computed),
1305 // does not see generative constructor bodies because they are 1302 // does not see generative constructor bodies because they are
1306 // created by the backend. Also, it does not make any distinction 1303 // created by the backend. Also, it does not make any distinction
1307 // between a constructor and its body for side effects. This 1304 // between a constructor and its body for side effects. This
1308 // implies that currently, the side effects of a constructor body 1305 // implies that currently, the side effects of a constructor body
1309 // contain the side effects of the initializers. 1306 // contain the side effects of the initializers.
1310 assert(!element.isGenerativeConstructorBody); 1307 assert(!element.isGenerativeConstructorBody);
1311 assert(!element.isField); 1308 assert(!element.isField);
1312 return super.getSideEffectsOfElement(element); 1309 return super.getSideEffectsOfElement(element);
1313 } 1310 }
1314 } 1311 }
OLDNEW
« pkg/compiler/lib/src/types/types.dart ('K') | « pkg/compiler/lib/src/types/types.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698