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

Side by Side Diff: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart

Issue 1776533002: dart2js: Destroy some type inference graph edges after type inference. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: fix failing tests that use initialized MemberTypeInformations Created 4 years, 9 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 compiler.src.inferrer.type_graph_nodes; 5 library compiler.src.inferrer.type_graph_nodes;
6 6
7 import 'dart:collection' show IterableBase; 7 import 'dart:collection' show IterableBase;
8 8
9 import '../common.dart'; 9 import '../common.dart';
10 import '../common/names.dart' show Identifiers; 10 import '../common/names.dart' show Identifiers;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 _assignments = STOP_TRACKING_ASSIGNMENTS_MARKER; 230 _assignments = STOP_TRACKING_ASSIGNMENTS_MARKER;
231 abandonInferencing = true; 231 abandonInferencing = true;
232 isStable = true; 232 isStable = true;
233 } 233 }
234 234
235 void maybeResume() { 235 void maybeResume() {
236 if (!mightResume) return; 236 if (!mightResume) return;
237 abandonInferencing = false; 237 abandonInferencing = false;
238 doNotEnqueue = false; 238 doNotEnqueue = false;
239 } 239 }
240
241 /// Destroys information not needed after type inference.
242 void cleanup() {
243 users = null;
244 _assignments = null;
245 }
240 } 246 }
241 247
242 abstract class ApplyableTypeInformation implements TypeInformation { 248 abstract class ApplyableTypeInformation implements TypeInformation {
243 bool mightBePassedToFunctionApply = false; 249 bool mightBePassedToFunctionApply = false;
244 } 250 }
245 251
246 /** 252 /**
247 * Marker node used only during tree construction but not during actual type 253 * Marker node used only during tree construction but not during actual type
248 * refinement. 254 * refinement.
249 * 255 *
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 class MemberTypeInformation extends ElementTypeInformation 384 class MemberTypeInformation extends ElementTypeInformation
379 with ApplyableTypeInformation { 385 with ApplyableTypeInformation {
380 TypedElement get element => super.element; 386 TypedElement get element => super.element;
381 387
382 /** 388 /**
383 * If [element] is a function, [closurizedCount] is the number of 389 * If [element] is a function, [closurizedCount] is the number of
384 * times it is closurized. The value gets updated while infering. 390 * times it is closurized. The value gets updated while infering.
385 */ 391 */
386 int closurizedCount = 0; 392 int closurizedCount = 0;
387 393
394 // Strict `bool` value is computed in cleanup(). Also used as a flag to see if
395 // cleanup has been called.
396 bool _isCalledOnce = null;
397
388 /** 398 /**
389 * This map contains the callers of [element]. It stores all unique call sites 399 * This map contains the callers of [element]. It stores all unique call sites
390 * to enable counting the global number of call sites of [element]. 400 * to enable counting the global number of call sites of [element].
391 * 401 *
392 * A call site is either an AST [ast.Node], a [cps_ir.Node] or in the case of 402 * A call site is either an AST [ast.Node], a [cps_ir.Node] or in the case of
393 * synthesized calls, an [Element] (see uses of [synthesizeForwardingCall] 403 * synthesized calls, an [Element] (see uses of [synthesizeForwardingCall]
394 * in [SimpleTypeInferrerVisitor]). 404 * in [SimpleTypeInferrerVisitor]).
405 *
406 * The global information is summarized in [cleanup], after which [_callers]
407 * is set to `null`.
395 */ 408 */
396 final Map<Element, Setlet<Spannable>> _callers = new Map<Element, Setlet>(); 409 Map<Element, Setlet<Spannable>> _callers;
397 410
398 MemberTypeInformation._internal(Element element) 411 MemberTypeInformation._internal(Element element)
399 : super._internal(null, element); 412 : super._internal(null, element);
400 413
401 void addCall(Element caller, Spannable node) { 414 void addCall(Element caller, Spannable node) {
402 assert(node is ast.Node || node is cps_ir.Node || node is Element); 415 assert(node is ast.Node || node is cps_ir.Node || node is Element);
416 _callers ??= <Element, Setlet>{};
403 _callers.putIfAbsent(caller, () => new Setlet()).add(node); 417 _callers.putIfAbsent(caller, () => new Setlet()).add(node);
404 } 418 }
405 419
406 void removeCall(Element caller, node) { 420 void removeCall(Element caller, node) {
421 if (_callers == null) return;
407 Setlet calls = _callers[caller]; 422 Setlet calls = _callers[caller];
408 if (calls == null) return; 423 if (calls == null) return;
409 calls.remove(node); 424 calls.remove(node);
410 if (calls.isEmpty) { 425 if (calls.isEmpty) {
411 _callers.remove(caller); 426 _callers.remove(caller);
412 } 427 }
413 } 428 }
414 429
415 Iterable<Element> get callers => _callers.keys; 430 Iterable<Element> get callers {
431 // TODO(sra): This is called only from an unused API and a test. If it
432 // becomes used, [cleanup] will need to copy `_caller.keys`.
433
434 // `simple_inferrer_callers_test.dart` ensures that cleanup has not
435 // happened.
436 return _callers.keys;
437 }
416 438
417 bool isCalledOnce() { 439 bool isCalledOnce() {
440 // If this assert fires it means that this MemberTypeInformation for the
441 // element was not part of type inference. This happens for
442 // ConstructorBodyElements, so guard the call with a test for
443 // ConstructorBodyElement. For other elements, investigate why the element
444 // was not present for type inference.
445 assert(_isCalledOnce != null);
446 return _isCalledOnce ?? false;
447 }
448
449 bool _computeIsCalledOnce() {
450 if (_callers == null) return false;
418 int count = 0; 451 int count = 0;
419 for (var set in _callers.values) { 452 for (var set in _callers.values) {
420 count += set.length; 453 count += set.length;
421 if (count > 1) return false; 454 if (count > 1) return false;
422 } 455 }
423 return count == 1; 456 return count == 1;
424 } 457 }
425 458
426 bool get isClosurized => closurizedCount > 0; 459 bool get isClosurized => closurizedCount > 0;
427 460
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // The number of assignments of non-final fields is 556 // The number of assignments of non-final fields is
524 // not stable. Therefore such a field cannot be stable. 557 // not stable. Therefore such a field cannot be stable.
525 if (element.isField && !(element.isConst || element.isFinal)) { 558 if (element.isField && !(element.isConst || element.isFinal)) {
526 return false; 559 return false;
527 } 560 }
528 561
529 if (element.isFunction) return false; 562 if (element.isFunction) return false;
530 563
531 return super.hasStableType(inferrer); 564 return super.hasStableType(inferrer);
532 } 565 }
566
567 void cleanup() {
568 // This node is on multiple lists so cleanup() can be called twice.
569 if (_isCalledOnce != null) return;
570 _isCalledOnce = _computeIsCalledOnce();
571 _callers = null;
572 super.cleanup();
573 }
533 } 574 }
534 575
535 /** 576 /**
536 * A node representing parameters: 577 * A node representing parameters:
537 * 578 *
538 * - Parameters 579 * - Parameters
539 * - Initializing formals 580 * - Initializing formals
540 * 581 *
541 * These should never be created directly but instead are constructed by 582 * These should never be created directly but instead are constructed by
542 * the [ElementTypeInformation] factory. 583 * the [ElementTypeInformation] factory.
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 return new ContainerTypeMask(originalType.forwardTo, 1353 return new ContainerTypeMask(originalType.forwardTo,
1313 originalType.allocationNode, 1354 originalType.allocationNode,
1314 originalType.allocationElement, 1355 originalType.allocationElement,
1315 elementType.type, 1356 elementType.type,
1316 inferredLength); 1357 inferredLength);
1317 } 1358 }
1318 return mask; 1359 return mask;
1319 } 1360 }
1320 1361
1321 TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType; 1362 TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType;
1363
1364 void cleanup() {
1365 super.cleanup();
1366 elementType.cleanup();
1367 _flowsInto = null;
1368 }
1322 } 1369 }
1323 1370
1324 /** 1371 /**
1325 * An [ElementInContainerTypeInformation] holds the common type of the 1372 * An [ElementInContainerTypeInformation] holds the common type of the
1326 * elements in a [ListTypeInformation]. 1373 * elements in a [ListTypeInformation].
1327 */ 1374 */
1328 class ElementInContainerTypeInformation extends InferredTypeInformation { 1375 class ElementInContainerTypeInformation extends InferredTypeInformation {
1329 ElementInContainerTypeInformation(MemberTypeInformation context, 1376 ElementInContainerTypeInformation(MemberTypeInformation context,
1330 elementType) 1377 elementType)
1331 : super(context, elementType); 1378 : super(context, elementType);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 } 1522 }
1476 1523
1477 TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType; 1524 TypeMask safeType(TypeGraphInferrerEngine inferrer) => originalType;
1478 1525
1479 bool hasStableType(TypeGraphInferrerEngine inferrer) { 1526 bool hasStableType(TypeGraphInferrerEngine inferrer) {
1480 return keyType.isStable && 1527 return keyType.isStable &&
1481 valueType.isStable && 1528 valueType.isStable &&
1482 super.hasStableType(inferrer); 1529 super.hasStableType(inferrer);
1483 } 1530 }
1484 1531
1532 void cleanup() {
1533 super.cleanup();
1534 keyType.cleanup();
1535 valueType.cleanup();
1536 for (TypeInformation info in typeInfoMap.values) {
1537 info.cleanup();
1538 }
1539 _flowsInto = null;
1540 }
1541
1485 String toString() { 1542 String toString() {
1486 return 'Map $type (K:$keyType, V:$valueType) contents $typeInfoMap'; 1543 return 'Map $type (K:$keyType, V:$valueType) contents $typeInfoMap';
1487 } 1544 }
1488 } 1545 }
1489 1546
1490 /** 1547 /**
1491 * A [KeyInMapTypeInformation] holds the common type 1548 * A [KeyInMapTypeInformation] holds the common type
1492 * for the keys in a [MapTypeInformation] 1549 * for the keys in a [MapTypeInformation]
1493 */ 1550 */
1494 class KeyInMapTypeInformation extends InferredTypeInformation { 1551 class KeyInMapTypeInformation extends InferredTypeInformation {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1661 } else if (annotation.isVoid) { 1718 } else if (annotation.isVoid) {
1662 otherType = compiler.typesTask.nullType; 1719 otherType = compiler.typesTask.nullType;
1663 } else { 1720 } else {
1664 assert(annotation.isInterfaceType); 1721 assert(annotation.isInterfaceType);
1665 otherType = new TypeMask.nonNullSubtype(annotation.element, compiler.world); 1722 otherType = new TypeMask.nonNullSubtype(annotation.element, compiler.world);
1666 } 1723 }
1667 if (isNullable) otherType = otherType.nullable(); 1724 if (isNullable) otherType = otherType.nullable();
1668 if (type == null) return otherType; 1725 if (type == null) return otherType;
1669 return type.intersection(otherType, compiler.world); 1726 return type.intersection(otherType, compiler.world);
1670 } 1727 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart ('k') | pkg/compiler/lib/src/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698