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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/type_propagation.dart

Issue 1234753003: dart2js cps: Rewrite mutable variables to continuation parameters. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add tests and fix an assertion Created 5 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 import 'optimizers.dart'; 5 import 'optimizers.dart';
6 6
7 import '../constants/constant_system.dart'; 7 import '../constants/constant_system.dart';
8 import '../resolution/operators.dart'; 8 import '../resolution/operators.dart';
9 import '../constants/values.dart'; 9 import '../constants/values.dart';
10 import '../dart_types.dart' as types; 10 import '../dart_types.dart' as types;
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 parent.body = replacement; 592 parent.body = replacement;
593 replacement.parent = parent; 593 replacement.parent = parent;
594 node.parent = null; 594 node.parent = null;
595 if (unlink) { 595 if (unlink) {
596 RemovalVisitor.remove(node); 596 RemovalVisitor.remove(node);
597 } 597 }
598 reanalyze(replacement); 598 reanalyze(replacement);
599 } 599 }
600 600
601 /// Inserts [insertedCode] before [node]. 601 /// Inserts [insertedCode] before [node].
602 /// 602 ///
603 /// [node] will end up in the hole of [insertedCode], and [insertedCode] 603 /// [node] will end up in the hole of [insertedCode], and [insertedCode]
604 /// will become rooted where [node] was. 604 /// will become rooted where [node] was.
605 void insertBefore(Expression node, CpsFragment insertedCode) { 605 void insertBefore(Expression node, CpsFragment insertedCode) {
606 if (insertedCode.isEmpty) return; // Nothing to do. 606 if (insertedCode.isEmpty) return; // Nothing to do.
607 assert(insertedCode.isOpen); 607 assert(insertedCode.isOpen);
608 InteriorNode parent = node.parent; 608 InteriorNode parent = node.parent;
609 InteriorNode context = insertedCode.context; 609 InteriorNode context = insertedCode.context;
610 610
611 parent.body = insertedCode.root; 611 parent.body = insertedCode.root;
612 insertedCode.root.parent = parent; 612 insertedCode.root.parent = parent;
613 613
614 // We want to recompute the types for [insertedCode] without 614 // We want to recompute the types for [insertedCode] without
615 // traversing the entire subtree of [node]. Temporarily close the 615 // traversing the entire subtree of [node]. Temporarily close the
616 // term with a dummy node while recomputing types. 616 // term with a dummy node while recomputing types.
617 context.body = new Unreachable(); 617 context.body = new Unreachable();
618 new ParentVisitor().visit(insertedCode.root); 618 new ParentVisitor().visit(insertedCode.root);
619 reanalyze(insertedCode.root); 619 reanalyze(insertedCode.root);
620 620
621 context.body = node; 621 context.body = node;
622 node.parent = context; 622 node.parent = context;
623 } 623 }
624 624
625 /// Make a constant primitive for [constant] and set its entry in [values]. 625 /// Make a constant primitive for [constant] and set its entry in [values].
626 Constant makeConstantPrimitive(ConstantValue constant) { 626 Constant makeConstantPrimitive(ConstantValue constant) {
627 Constant primitive = new Constant(constant); 627 Constant primitive = new Constant(constant);
(...skipping 18 matching lines...) Expand all
646 return letPrim; 646 return letPrim;
647 } 647 }
648 648
649 /// Side-effect free expressions with constant results are be replaced by: 649 /// Side-effect free expressions with constant results are be replaced by:
650 /// 650 ///
651 /// (LetPrim p = constant (InvokeContinuation k p)). 651 /// (LetPrim p = constant (InvokeContinuation k p)).
652 /// 652 ///
653 /// The new expression will be visited. 653 /// The new expression will be visited.
654 /// 654 ///
655 /// Returns true if the node was replaced. 655 /// Returns true if the node was replaced.
656 bool constifyExpression(Invoke node) { 656 bool constifyExpression(CallExpression node) {
657 Continuation continuation = node.continuation.definition; 657 Continuation continuation = node.continuation.definition;
658 ConstantValue constant = replacements[node]; 658 ConstantValue constant = replacements[node];
659 if (constant == null) return false; 659 if (constant == null) return false;
660 Constant primitive = makeConstantPrimitive(constant); 660 Constant primitive = makeConstantPrimitive(constant);
661 LetPrim letPrim = makeLetPrimInvoke(primitive, continuation); 661 LetPrim letPrim = makeLetPrimInvoke(primitive, continuation);
662 replaceSubtree(node, letPrim); 662 replaceSubtree(node, letPrim);
663 visitLetPrim(letPrim); 663 visitLetPrim(letPrim);
664 return true; 664 return true;
665 } 665 }
666 666
(...skipping 18 matching lines...) Expand all
685 visitInvokeContinuation(invoke); 685 visitInvokeContinuation(invoke);
686 return; 686 return;
687 } 687 }
688 if (boolifiedValue == AbstractBool.False) { 688 if (boolifiedValue == AbstractBool.False) {
689 InvokeContinuation invoke = new InvokeContinuation(falseCont, []); 689 InvokeContinuation invoke = new InvokeContinuation(falseCont, []);
690 replaceSubtree(node, invoke); 690 replaceSubtree(node, invoke);
691 visitInvokeContinuation(invoke); 691 visitInvokeContinuation(invoke);
692 return; 692 return;
693 } 693 }
694 694
695 if (condition is ApplyBuiltinOperator && 695 if (condition is ApplyBuiltinOperator &&
696 condition.operator == BuiltinOperator.LooseEq) { 696 condition.operator == BuiltinOperator.LooseEq) {
697 Primitive leftArg = condition.arguments[0].definition; 697 Primitive leftArg = condition.arguments[0].definition;
698 Primitive rightArg = condition.arguments[1].definition; 698 Primitive rightArg = condition.arguments[1].definition;
699 AbstractValue left = getValue(leftArg); 699 AbstractValue left = getValue(leftArg);
700 AbstractValue right = getValue(rightArg); 700 AbstractValue right = getValue(rightArg);
701 if (right.isNullConstant && 701 if (right.isNullConstant &&
702 lattice.isDefinitelyNotNumStringBool(left)) { 702 lattice.isDefinitelyNotNumStringBool(left)) {
703 // Rewrite: 703 // Rewrite:
704 // if (x == null) S1 else S2 704 // if (x == null) S1 else S2
705 // => 705 // =>
706 // if (x) S2 else S1 (note the swapped branches) 706 // if (x) S2 else S1 (note the swapped branches)
707 Branch branch = new Branch(new IsTrue(leftArg), falseCont, trueCont); 707 Branch branch = new Branch(new IsTrue(leftArg), falseCont, trueCont);
708 replaceSubtree(node, branch); 708 replaceSubtree(node, branch);
709 return; 709 return;
710 } else if (left.isNullConstant && 710 } else if (left.isNullConstant &&
711 lattice.isDefinitelyNotNumStringBool(right)) { 711 lattice.isDefinitelyNotNumStringBool(right)) {
712 Branch branch = new Branch(new IsTrue(rightArg), falseCont, trueCont); 712 Branch branch = new Branch(new IsTrue(rightArg), falseCont, trueCont);
713 replaceSubtree(node, branch); 713 replaceSubtree(node, branch);
714 return; 714 return;
715 } 715 }
716 } 716 }
717 } 717 }
718 718
719 /// Replaces [node] with a more specialized instruction, if possible. 719 /// Replaces [node] with a more specialized instruction, if possible.
720 /// 720 ///
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 target, 836 target,
837 getDartArgument(node, 0)); 837 getDartArgument(node, 0));
838 set.body = new InvokeContinuation(cont, <Primitive>[]); 838 set.body = new InvokeContinuation(cont, <Primitive>[]);
839 replaceSubtree(node, set); 839 replaceSubtree(node, set);
840 visitSetField(set); 840 visitSetField(set);
841 return true; 841 return true;
842 } 842 }
843 } 843 }
844 844
845 /// Create a check that throws if [index] is not a valid index on [list]. 845 /// Create a check that throws if [index] is not a valid index on [list].
846 /// 846 ///
847 /// This function assumes that [index] is an integer. 847 /// This function assumes that [index] is an integer.
848 /// 848 ///
849 /// Returns a CPS fragment whose context is the branch where no error 849 /// Returns a CPS fragment whose context is the branch where no error
850 /// was thrown. 850 /// was thrown.
851 CpsFragment makeBoundsCheck(Primitive list, 851 CpsFragment makeBoundsCheck(Primitive list,
852 Primitive index, 852 Primitive index,
853 SourceInformation sourceInfo) { 853 SourceInformation sourceInfo) {
854 CpsFragment cps = new CpsFragment(sourceInfo); 854 CpsFragment cps = new CpsFragment(sourceInfo);
855 Continuation fail = cps.letCont(); 855 Continuation fail = cps.letCont();
856 Primitive isTooSmall = cps.applyBuiltin( 856 Primitive isTooSmall = cps.applyBuiltin(
(...skipping 30 matching lines...) Expand all
887 887
888 /// Counts number of index accesses on [list] and determines based on 888 /// Counts number of index accesses on [list] and determines based on
889 /// that number if we should try to inline them. 889 /// that number if we should try to inline them.
890 /// 890 ///
891 /// This is a short-term solution to avoid inserting a lot of bounds checks, 891 /// This is a short-term solution to avoid inserting a lot of bounds checks,
892 /// since there is currently no optimization for eliminating them. 892 /// since there is currently no optimization for eliminating them.
893 bool hasTooManyIndexAccesses(Primitive list) { 893 bool hasTooManyIndexAccesses(Primitive list) {
894 int count = 0; 894 int count = 0;
895 for (Reference ref = list.firstRef; ref != null; ref = ref.next) { 895 for (Reference ref = list.firstRef; ref != null; ref = ref.next) {
896 Node use = ref.parent; 896 Node use = ref.parent;
897 if (use is InvokeMethod && 897 if (use is InvokeMethod &&
898 (use.selector.isIndex || use.selector.isIndexSet) && 898 (use.selector.isIndex || use.selector.isIndexSet) &&
899 getDartReceiver(use) == list) { 899 getDartReceiver(use) == list) {
900 ++count; 900 ++count;
901 } else if (use is GetIndex && use.object.definition == list) { 901 } else if (use is GetIndex && use.object.definition == list) {
902 ++count; 902 ++count;
903 } else if (use is SetIndex && use.object.definition == list) { 903 } else if (use is SetIndex && use.object.definition == list) {
904 ++count; 904 ++count;
905 } 905 }
906 if (count > 2) return true; 906 if (count > 2) return true;
907 } 907 }
908 return false; 908 return false;
909 } 909 }
910 910
911 /// Tries to replace [node] with one or more direct array access operations. 911 /// Tries to replace [node] with one or more direct array access operations.
912 /// 912 ///
913 /// Returns `true` if the node was replaced. 913 /// Returns `true` if the node was replaced.
914 bool specializeArrayAccess(InvokeMethod node) { 914 bool specializeArrayAccess(InvokeMethod node) {
915 Primitive list = getDartReceiver(node); 915 Primitive list = getDartReceiver(node);
916 AbstractValue listValue = getValue(list); 916 AbstractValue listValue = getValue(list);
917 // Ensure that the object is a native list or null. 917 // Ensure that the object is a native list or null.
918 if (!lattice.isDefinitelyNativeList(listValue, allowNull: true)) { 918 if (!lattice.isDefinitelyNativeList(listValue, allowNull: true)) {
919 return false; 919 return false;
920 } 920 }
921 bool isFixedLength = 921 bool isFixedLength =
922 lattice.isDefinitelyFixedNativeList(listValue, allowNull: true); 922 lattice.isDefinitelyFixedNativeList(listValue, allowNull: true);
923 bool isMutable = 923 bool isMutable =
924 lattice.isDefinitelyMutableNativeList(listValue, allowNull: true); 924 lattice.isDefinitelyMutableNativeList(listValue, allowNull: true);
925 SourceInformation sourceInfo = node.sourceInformation; 925 SourceInformation sourceInfo = node.sourceInformation;
926 Continuation cont = node.continuation.definition; 926 Continuation cont = node.continuation.definition;
927 switch (node.selector.name) { 927 switch (node.selector.name) {
928 case 'length': 928 case 'length':
929 if (!node.selector.isGetter) return false; 929 if (!node.selector.isGetter) return false;
930 CpsFragment cps = new CpsFragment(sourceInfo); 930 CpsFragment cps = new CpsFragment(sourceInfo);
931 cps.invokeContinuation(cont, [cps.letPrim(new GetLength(list))]); 931 cps.invokeContinuation(cont, [cps.letPrim(new GetLength(list))]);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 } 1034 }
1035 } 1035 }
1036 1036
1037 // Rewrite the iterator variable to 'current' and 'index' variables. 1037 // Rewrite the iterator variable to 'current' and 'index' variables.
1038 Primitive originalLength = new GetLength(list); 1038 Primitive originalLength = new GetLength(list);
1039 originalLength.hint = new OriginalLengthEntity(); 1039 originalLength.hint = new OriginalLengthEntity();
1040 MutableVariable index = new MutableVariable(new LoopIndexEntity()); 1040 MutableVariable index = new MutableVariable(new LoopIndexEntity());
1041 MutableVariable current = new MutableVariable(new LoopItemEntity()); 1041 MutableVariable current = new MutableVariable(new LoopItemEntity());
1042 1042
1043 // Rewrite all uses of the iterator. 1043 // Rewrite all uses of the iterator.
1044 while (iterator.firstRef != null) { 1044 while (iterator.firstRef != null) {
1045 InvokeMethod use = iterator.firstRef.parent; 1045 InvokeMethod use = iterator.firstRef.parent;
1046 Continuation useCont = use.continuation.definition; 1046 Continuation useCont = use.continuation.definition;
1047 if (use.selector == currentSelector) { 1047 if (use.selector == currentSelector) {
1048 // Rewrite iterator.current to a use of the 'current' variable. 1048 // Rewrite iterator.current to a use of the 'current' variable.
1049 Parameter result = useCont.parameters.single; 1049 Parameter result = useCont.parameters.single;
1050 if (result.hint != null) { 1050 if (result.hint != null) {
1051 // If 'current' was originally moved into a named variable, use 1051 // If 'current' was originally moved into a named variable, use
1052 // that variable name for the mutable variable. 1052 // that variable name for the mutable variable.
1053 current.hint = result.hint; 1053 current.hint = result.hint;
1054 } 1054 }
1055 LetPrim let = 1055 LetPrim let =
1056 makeLetPrimInvoke(new GetMutableVariable(current), useCont); 1056 makeLetPrimInvoke(new GetMutableVariable(current), useCont);
1057 replaceSubtree(use, let); 1057 replaceSubtree(use, let);
1058 } else { 1058 } else {
1059 assert (use.selector == moveNextSelector); 1059 assert (use.selector == moveNextSelector);
1060 // Rewrite iterator.moveNext() to: 1060 // Rewrite iterator.moveNext() to:
1061 // 1061 //
1062 // if (index < list.length) { 1062 // if (index < list.length) {
1063 // current = null; 1063 // current = null;
1064 // continuation(false); 1064 // continuation(false);
1065 // } else { 1065 // } else {
1066 // current = list[index]; 1066 // current = list[index];
1067 // index = index + 1; 1067 // index = index + 1;
1068 // continuation(true); 1068 // continuation(true);
1069 // } 1069 // }
1070 // 1070 //
1071 // (The above does not show concurrent modification checks) 1071 // (The above does not show concurrent modification checks)
1072 1072
1073 // [cps] contains the code we insert instead of moveNext(). 1073 // [cps] contains the code we insert instead of moveNext().
1074 CpsFragment cps = new CpsFragment(node.sourceInformation); 1074 CpsFragment cps = new CpsFragment(node.sourceInformation);
1075 1075
1076 // We must check for concurrent modification when calling moveNext. 1076 // We must check for concurrent modification when calling moveNext.
1077 // When moveNext is used as a loop condition, the check prevents 1077 // When moveNext is used as a loop condition, the check prevents
1078 // `index < list.length` from becoming the loop condition, and we 1078 // `index < list.length` from becoming the loop condition, and we
1079 // get code like this: 1079 // get code like this:
1080 // 1080 //
1081 // while (true) { 1081 // while (true) {
1082 // if (originalLength !== list.length) throw; 1082 // if (originalLength !== list.length) throw;
1083 // if (index < list.length) { 1083 // if (index < list.length) {
1084 // ... 1084 // ...
1085 // } else { 1085 // } else {
1086 // ... 1086 // ...
1087 // break; 1087 // break;
1088 // } 1088 // }
1089 // } 1089 // }
1090 // 1090 //
1091 // For loops, we therefore check for concurrent modification before 1091 // For loops, we therefore check for concurrent modification before
1092 // invoking the recursive continuation, so the loop becomes: 1092 // invoking the recursive continuation, so the loop becomes:
1093 // 1093 //
1094 // if (originalLength !== list.length) throw; 1094 // if (originalLength !== list.length) throw;
1095 // while (index < list.length) { 1095 // while (index < list.length) {
1096 // ... 1096 // ...
1097 // if (originalLength !== list.length) throw; 1097 // if (originalLength !== list.length) throw;
1098 // } 1098 // }
1099 // 1099 //
1100 // The check before the loop can often be eliminated because it 1100 // The check before the loop can often be eliminated because it
1101 // follows immediately after the 'iterator' call. 1101 // follows immediately after the 'iterator' call.
1102 InteriorNode parent = getEffectiveParent(use); 1102 InteriorNode parent = getEffectiveParent(use);
1103 if (!isFixedLength) { 1103 if (!isFixedLength) {
1104 if (parent is Continuation && parent.isRecursive) { 1104 if (parent is Continuation && parent.isRecursive) {
1105 // Check for concurrent modification before every invocation 1105 // Check for concurrent modification before every invocation
1106 // of the continuation. 1106 // of the continuation.
1107 // TODO(asgerf): Do this in a continuation so multiple 1107 // TODO(asgerf): Do this in a continuation so multiple
1108 // continues can share the same code. 1108 // continues can share the same code.
1109 for (Reference ref = parent.firstRef; 1109 for (Reference ref = parent.firstRef;
1110 ref != null; 1110 ref != null;
1111 ref = ref.next) { 1111 ref = ref.next) {
1112 Expression invocationCaller = ref.parent; 1112 Expression invocationCaller = ref.parent;
1113 if (getEffectiveParent(invocationCaller) == iteratorCont) { 1113 if (getEffectiveParent(invocationCaller) == iteratorCont) {
1114 // No need to check for concurrent modification immediately 1114 // No need to check for concurrent modification immediately
1115 // after the call to 'iterator'. 1115 // after the call to 'iterator'.
1116 continue; 1116 continue;
1117 } 1117 }
1118 CpsFragment check = makeConcurrentModificationCheck( 1118 CpsFragment check = makeConcurrentModificationCheck(
1119 list, originalLength, sourceInfo); 1119 list, originalLength, sourceInfo);
1120 insertBefore(invocationCaller, check); 1120 insertBefore(invocationCaller, check);
1121 } 1121 }
1122 } else { 1122 } else {
1123 cps.append(makeConcurrentModificationCheck( 1123 cps.append(makeConcurrentModificationCheck(
1124 list, originalLength, sourceInfo)); 1124 list, originalLength, sourceInfo));
1125 } 1125 }
1126 } 1126 }
1127 1127
1128 // Check if there are more elements. 1128 // Check if there are more elements.
1129 Primitive hasMore = cps.applyBuiltin( 1129 Primitive hasMore = cps.applyBuiltin(
1130 BuiltinOperator.NumLt, 1130 BuiltinOperator.NumLt,
1131 [cps.getMutable(index), cps.letPrim(new GetLength(list))]); 1131 [cps.getMutable(index), cps.letPrim(new GetLength(list))]);
1132 1132
1133 // Return false if there are no more. 1133 // Return false if there are no more.
1134 CpsFragment falseBranch = cps.ifFalse(hasMore); 1134 CpsFragment falseBranch = cps.ifFalse(hasMore);
1135 falseBranch 1135 falseBranch
1136 ..setMutable(current, falseBranch.makeNull()) 1136 ..setMutable(current, falseBranch.makeNull())
1137 ..invokeContinuation(useCont, [falseBranch.makeFalse()]); 1137 ..invokeContinuation(useCont, [falseBranch.makeFalse()]);
1138 1138
1139 // Return true if there are more element. 1139 // Return true if there are more element.
1140 cps.setMutable(current, 1140 cps.setMutable(current,
1141 cps.letPrim(new GetIndex(list, cps.getMutable(index)))); 1141 cps.letPrim(new GetIndex(list, cps.getMutable(index))));
1142 cps.setMutable(index, cps.applyBuiltin( 1142 cps.setMutable(index, cps.applyBuiltin(
1143 BuiltinOperator.NumAdd, 1143 BuiltinOperator.NumAdd,
1144 [cps.getMutable(index), cps.makeOne()])); 1144 [cps.getMutable(index), cps.makeOne()]));
1145 cps.invokeContinuation(useCont, [cps.makeTrue()]); 1145 cps.invokeContinuation(useCont, [cps.makeTrue()]);
1146 1146
1147 // Replace the moveNext() call. It will be visited later. 1147 // Replace the moveNext() call. It will be visited later.
1148 replaceSubtree(use, cps.result); 1148 replaceSubtree(use, cps.result);
1149 } 1149 }
1150 } 1150 }
(...skipping 19 matching lines...) Expand all
1170 1170
1171 // TODO(asgerf): Rewrite 'add', 'removeLast', ... 1171 // TODO(asgerf): Rewrite 'add', 'removeLast', ...
1172 1172
1173 default: 1173 default:
1174 return false; 1174 return false;
1175 } 1175 }
1176 } 1176 }
1177 1177
1178 /// If [prim] is the parameter to a call continuation, returns the 1178 /// If [prim] is the parameter to a call continuation, returns the
1179 /// corresponding call. 1179 /// corresponding call.
1180 Invoke getInvocationWithResult(Primitive prim) { 1180 CallExpression getCallWithResult(Primitive prim) {
1181 if (prim is Parameter && prim.parent is Continuation) { 1181 if (prim is Parameter && prim.parent is Continuation) {
1182 Continuation cont = prim.parent; 1182 Continuation cont = prim.parent;
1183 if (cont.hasExactlyOneUse) { 1183 if (cont.hasExactlyOneUse) {
1184 Node use = cont.firstRef.parent; 1184 Node use = cont.firstRef.parent;
1185 if (use is Invoke) { 1185 if (use is CallExpression) {
1186 return use; 1186 return use;
1187 } 1187 }
1188 } 1188 }
1189 } 1189 }
1190 return null; 1190 return null;
1191 } 1191 }
1192 1192
1193 /// Returns the first parent of [node] that is not a pure expression. 1193 /// Returns the first parent of [node] that is not a pure expression.
1194 InteriorNode getEffectiveParent(Expression node) { 1194 InteriorNode getEffectiveParent(Expression node) {
1195 while (true) { 1195 while (true) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 target, 1236 target,
1237 new Selector.fromElement(target), 1237 new Selector.fromElement(target),
1238 node.arguments, 1238 node.arguments,
1239 node.continuation, 1239 node.continuation,
1240 node.sourceInformation); 1240 node.sourceInformation);
1241 node.receiver.unlink(); 1241 node.receiver.unlink();
1242 replaceSubtree(node, invoke, unlink: false); 1242 replaceSubtree(node, invoke, unlink: false);
1243 visitInvokeStatic(invoke); 1243 visitInvokeStatic(invoke);
1244 return true; 1244 return true;
1245 } 1245 }
1246 Invoke tearOffInvoke = getInvocationWithResult(tearOff); 1246 CallExpression tearOffInvoke = getCallWithResult(tearOff);
1247 if (tearOffInvoke is InvokeMethod && tearOffInvoke.selector.isGetter) { 1247 if (tearOffInvoke is InvokeMethod && tearOffInvoke.selector.isGetter) {
1248 Selector getter = tearOffInvoke.selector; 1248 Selector getter = tearOffInvoke.selector;
1249 1249
1250 // TODO(asgerf): Support torn-off intercepted methods. 1250 // TODO(asgerf): Support torn-off intercepted methods.
1251 if (isInterceptedSelector(getter)) return false; 1251 if (isInterceptedSelector(getter)) return false;
1252 1252
1253 Continuation getterCont = tearOffInvoke.continuation.definition; 1253 Continuation getterCont = tearOffInvoke.continuation.definition;
1254 1254
1255 // TODO(asgerf): Support torn-off intercepted methods. 1255 // TODO(asgerf): Support torn-off intercepted methods.
1256 if (isInterceptedSelector(getter)) return false; 1256 if (isInterceptedSelector(getter)) return false;
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 Map<Definition, AbstractValue> values; 2284 Map<Definition, AbstractValue> values;
2285 2285
2286 ResetAnalysisInfo(this.reachableNodes, this.values); 2286 ResetAnalysisInfo(this.reachableNodes, this.values);
2287 2287
2288 visit(Node node) { 2288 visit(Node node) {
2289 reachableNodes.remove(node); 2289 reachableNodes.remove(node);
2290 if (node is Definition) values.remove(node); 2290 if (node is Definition) values.remove(node);
2291 node.accept(this); 2291 node.accept(this);
2292 } 2292 }
2293 } 2293 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/optimizers.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698