| OLD | NEW |
| 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 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); | 825 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); |
| 826 if (ic_data.NumberOfChecks() != 1) return false; | 826 if (ic_data.NumberOfChecks() != 1) return false; |
| 827 ASSERT(ic_data.HasOneTarget()); | 827 ASSERT(ic_data.HasOneTarget()); |
| 828 | 828 |
| 829 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); | 829 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 830 TargetEntryInstr* entry; | 830 TargetEntryInstr* entry; |
| 831 Definition* last; | 831 Definition* last; |
| 832 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0), | 832 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0), |
| 833 target, | 833 target, |
| 834 call, | 834 call, |
| 835 call->ArgumentAt(0), |
| 835 call->token_pos(), | 836 call->token_pos(), |
| 836 *call->ic_data(), | 837 *call->ic_data(), |
| 837 &entry, &last)) { | 838 &entry, &last)) { |
| 838 return false; | 839 return false; |
| 839 } | 840 } |
| 840 // Insert receiver class check. | 841 // Insert receiver class check. |
| 841 AddReceiverCheck(call); | 842 AddReceiverCheck(call); |
| 842 // Remove the original push arguments. | 843 // Remove the original push arguments. |
| 843 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 844 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 844 PushArgumentInstr* push = call->PushArgumentAt(i); | 845 PushArgumentInstr* push = call->PushArgumentAt(i); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 858 call->set_previous(NULL); | 859 call->set_previous(NULL); |
| 859 call->set_next(NULL); | 860 call->set_next(NULL); |
| 860 return true; | 861 return true; |
| 861 } | 862 } |
| 862 | 863 |
| 863 | 864 |
| 864 bool FlowGraphOptimizer::InlineSetIndexed( | 865 bool FlowGraphOptimizer::InlineSetIndexed( |
| 865 MethodRecognizer::Kind kind, | 866 MethodRecognizer::Kind kind, |
| 866 const Function& target, | 867 const Function& target, |
| 867 Instruction* call, | 868 Instruction* call, |
| 869 Definition* receiver, |
| 868 intptr_t token_pos, | 870 intptr_t token_pos, |
| 869 const ICData* ic_data, | 871 const ICData* ic_data, |
| 870 const ICData& value_check, | 872 const ICData& value_check, |
| 871 TargetEntryInstr** entry, | 873 TargetEntryInstr** entry, |
| 872 Definition** last) { | 874 Definition** last) { |
| 873 intptr_t array_cid = MethodKindToCid(kind); | 875 intptr_t array_cid = MethodKindToCid(kind); |
| 874 ASSERT(array_cid != kIllegalCid); | 876 ASSERT(array_cid != kIllegalCid); |
| 875 | 877 |
| 876 Definition* array = call->ArgumentAt(0); | 878 Definition* array = receiver; |
| 877 Definition* index = call->ArgumentAt(1); | 879 Definition* index = call->ArgumentAt(1); |
| 878 Definition* stored_value = call->ArgumentAt(2); | 880 Definition* stored_value = call->ArgumentAt(2); |
| 879 | 881 |
| 880 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), | 882 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), |
| 881 call->GetBlock()->try_index()); | 883 call->GetBlock()->try_index()); |
| 882 (*entry)->InheritDeoptTarget(call); | 884 (*entry)->InheritDeoptTarget(call); |
| 883 Instruction* cursor = *entry; | 885 Instruction* cursor = *entry; |
| 884 if (FLAG_enable_type_checks) { | 886 if (FLAG_enable_type_checks) { |
| 885 // Only type check for the value. A type check for the index is not | 887 // Only type check for the value. A type check for the index is not |
| 886 // needed here because we insert a deoptimizing smi-check for the case | 888 // needed here because we insert a deoptimizing smi-check for the case |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 *last, | 994 *last, |
| 993 call->env(), | 995 call->env(), |
| 994 Definition::kEffect); | 996 Definition::kEffect); |
| 995 return true; | 997 return true; |
| 996 } | 998 } |
| 997 | 999 |
| 998 | 1000 |
| 999 bool FlowGraphOptimizer::TryInlineRecognizedMethod(intptr_t receiver_cid, | 1001 bool FlowGraphOptimizer::TryInlineRecognizedMethod(intptr_t receiver_cid, |
| 1000 const Function& target, | 1002 const Function& target, |
| 1001 Instruction* call, | 1003 Instruction* call, |
| 1004 Definition* receiver, |
| 1002 intptr_t token_pos, | 1005 intptr_t token_pos, |
| 1003 const ICData& ic_data, | 1006 const ICData& ic_data, |
| 1004 TargetEntryInstr** entry, | 1007 TargetEntryInstr** entry, |
| 1005 Definition** last) { | 1008 Definition** last) { |
| 1006 ICData& value_check = ICData::ZoneHandle(); | 1009 ICData& value_check = ICData::ZoneHandle(); |
| 1007 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); | 1010 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); |
| 1008 switch (kind) { | 1011 switch (kind) { |
| 1009 // Recognized [] operators. | 1012 // Recognized [] operators. |
| 1010 case MethodRecognizer::kImmutableArrayGetIndexed: | 1013 case MethodRecognizer::kImmutableArrayGetIndexed: |
| 1011 case MethodRecognizer::kObjectArrayGetIndexed: | 1014 case MethodRecognizer::kObjectArrayGetIndexed: |
| 1012 case MethodRecognizer::kGrowableArrayGetIndexed: | 1015 case MethodRecognizer::kGrowableArrayGetIndexed: |
| 1013 case MethodRecognizer::kFloat32ArrayGetIndexed: | 1016 case MethodRecognizer::kFloat32ArrayGetIndexed: |
| 1014 case MethodRecognizer::kFloat64ArrayGetIndexed: | 1017 case MethodRecognizer::kFloat64ArrayGetIndexed: |
| 1015 case MethodRecognizer::kInt8ArrayGetIndexed: | 1018 case MethodRecognizer::kInt8ArrayGetIndexed: |
| 1016 case MethodRecognizer::kUint8ArrayGetIndexed: | 1019 case MethodRecognizer::kUint8ArrayGetIndexed: |
| 1017 case MethodRecognizer::kUint8ClampedArrayGetIndexed: | 1020 case MethodRecognizer::kUint8ClampedArrayGetIndexed: |
| 1018 case MethodRecognizer::kExternalUint8ArrayGetIndexed: | 1021 case MethodRecognizer::kExternalUint8ArrayGetIndexed: |
| 1019 case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed: | 1022 case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed: |
| 1020 case MethodRecognizer::kInt16ArrayGetIndexed: | 1023 case MethodRecognizer::kInt16ArrayGetIndexed: |
| 1021 case MethodRecognizer::kUint16ArrayGetIndexed: | 1024 case MethodRecognizer::kUint16ArrayGetIndexed: |
| 1022 return InlineGetIndexed(kind, call, ic_data, entry, last); | 1025 return InlineGetIndexed(kind, call, receiver, ic_data, entry, last); |
| 1023 case MethodRecognizer::kFloat32x4ArrayGetIndexed: | 1026 case MethodRecognizer::kFloat32x4ArrayGetIndexed: |
| 1024 if (!ShouldInlineSimd()) return false; | 1027 if (!ShouldInlineSimd()) return false; |
| 1025 return InlineGetIndexed(kind, call, ic_data, entry, last); | 1028 return InlineGetIndexed(kind, call, receiver, ic_data, entry, last); |
| 1026 case MethodRecognizer::kInt32ArrayGetIndexed: | 1029 case MethodRecognizer::kInt32ArrayGetIndexed: |
| 1027 case MethodRecognizer::kUint32ArrayGetIndexed: | 1030 case MethodRecognizer::kUint32ArrayGetIndexed: |
| 1028 if (!CanUnboxInt32()) return false; | 1031 if (!CanUnboxInt32()) return false; |
| 1029 return InlineGetIndexed(kind, call, ic_data, entry, last); | 1032 return InlineGetIndexed(kind, call, receiver, ic_data, entry, last); |
| 1030 | 1033 |
| 1031 // Recognized []= operators. | 1034 // Recognized []= operators. |
| 1032 case MethodRecognizer::kObjectArraySetIndexed: | 1035 case MethodRecognizer::kObjectArraySetIndexed: |
| 1033 case MethodRecognizer::kGrowableArraySetIndexed: | 1036 case MethodRecognizer::kGrowableArraySetIndexed: |
| 1034 if (ArgIsAlways(kSmiCid, ic_data, 2)) { | 1037 if (ArgIsAlways(kSmiCid, ic_data, 2)) { |
| 1035 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1038 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1036 } | 1039 } |
| 1037 return InlineSetIndexed(kind, target, call, token_pos, | 1040 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1038 &ic_data, value_check, entry, last); | 1041 &ic_data, value_check, entry, last); |
| 1039 case MethodRecognizer::kInt8ArraySetIndexed: | 1042 case MethodRecognizer::kInt8ArraySetIndexed: |
| 1040 case MethodRecognizer::kUint8ArraySetIndexed: | 1043 case MethodRecognizer::kUint8ArraySetIndexed: |
| 1041 case MethodRecognizer::kUint8ClampedArraySetIndexed: | 1044 case MethodRecognizer::kUint8ClampedArraySetIndexed: |
| 1042 case MethodRecognizer::kExternalUint8ArraySetIndexed: | 1045 case MethodRecognizer::kExternalUint8ArraySetIndexed: |
| 1043 case MethodRecognizer::kExternalUint8ClampedArraySetIndexed: | 1046 case MethodRecognizer::kExternalUint8ClampedArraySetIndexed: |
| 1044 case MethodRecognizer::kInt16ArraySetIndexed: | 1047 case MethodRecognizer::kInt16ArraySetIndexed: |
| 1045 case MethodRecognizer::kUint16ArraySetIndexed: | 1048 case MethodRecognizer::kUint16ArraySetIndexed: |
| 1046 if (!ArgIsAlways(kSmiCid, ic_data, 2)) return false; | 1049 if (!ArgIsAlways(kSmiCid, ic_data, 2)) return false; |
| 1047 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1050 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1048 return InlineSetIndexed(kind, target, call, token_pos, | 1051 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1049 &ic_data, value_check, entry, last); | 1052 &ic_data, value_check, entry, last); |
| 1050 case MethodRecognizer::kInt32ArraySetIndexed: | 1053 case MethodRecognizer::kInt32ArraySetIndexed: |
| 1051 case MethodRecognizer::kUint32ArraySetIndexed: | 1054 case MethodRecognizer::kUint32ArraySetIndexed: |
| 1052 if (!CanUnboxInt32()) return false; | 1055 if (!CanUnboxInt32()) return false; |
| 1053 // Check that value is always smi or mint, if the platform has unboxed | 1056 // Check that value is always smi or mint, if the platform has unboxed |
| 1054 // mints (ia32 with at least SSE 4.1). | 1057 // mints (ia32 with at least SSE 4.1). |
| 1055 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1058 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1056 if (FlowGraphCompiler::SupportsUnboxedMints()) { | 1059 if (FlowGraphCompiler::SupportsUnboxedMints()) { |
| 1057 if (!HasOnlySmiOrMint(value_check)) { | 1060 if (!HasOnlySmiOrMint(value_check)) { |
| 1058 return false; | 1061 return false; |
| 1059 } | 1062 } |
| 1060 } else if (!HasOnlyOneSmi(value_check)) { | 1063 } else if (!HasOnlyOneSmi(value_check)) { |
| 1061 return false; | 1064 return false; |
| 1062 } | 1065 } |
| 1063 return InlineSetIndexed(kind, target, call, token_pos, | 1066 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1064 &ic_data, value_check, entry, last); | 1067 &ic_data, value_check, entry, last); |
| 1065 case MethodRecognizer::kFloat32ArraySetIndexed: | 1068 case MethodRecognizer::kFloat32ArraySetIndexed: |
| 1066 case MethodRecognizer::kFloat64ArraySetIndexed: | 1069 case MethodRecognizer::kFloat64ArraySetIndexed: |
| 1067 // Check that value is always double. | 1070 // Check that value is always double. |
| 1068 if (!ArgIsAlways(kDoubleCid, ic_data, 2)) return false; | 1071 if (!ArgIsAlways(kDoubleCid, ic_data, 2)) return false; |
| 1069 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1072 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1070 return InlineSetIndexed(kind, target, call, token_pos, | 1073 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1071 &ic_data, value_check, entry, last); | 1074 &ic_data, value_check, entry, last); |
| 1072 case MethodRecognizer::kFloat32x4ArraySetIndexed: | 1075 case MethodRecognizer::kFloat32x4ArraySetIndexed: |
| 1073 if (!ShouldInlineSimd()) return false; | 1076 if (!ShouldInlineSimd()) return false; |
| 1074 // Check that value is always a Float32x4. | 1077 // Check that value is always a Float32x4. |
| 1075 if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false; | 1078 if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false; |
| 1076 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1079 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
| 1077 return InlineSetIndexed(kind, target, call, token_pos, | 1080 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
| 1078 &ic_data, value_check, entry, last); | 1081 &ic_data, value_check, entry, last); |
| 1079 case MethodRecognizer::kByteArrayBaseGetInt8: | 1082 case MethodRecognizer::kByteArrayBaseGetInt8: |
| 1080 return InlineByteArrayViewLoad(call, receiver_cid, | 1083 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1081 kTypedDataInt8ArrayCid, | 1084 kTypedDataInt8ArrayCid, |
| 1082 ic_data, entry, last); | 1085 ic_data, entry, last); |
| 1083 case MethodRecognizer::kByteArrayBaseGetUint8: | 1086 case MethodRecognizer::kByteArrayBaseGetUint8: |
| 1084 return InlineByteArrayViewLoad(call, receiver_cid, | 1087 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1085 kTypedDataUint8ArrayCid, | 1088 kTypedDataUint8ArrayCid, |
| 1086 ic_data, entry, last); | 1089 ic_data, entry, last); |
| 1087 case MethodRecognizer::kByteArrayBaseGetInt16: | 1090 case MethodRecognizer::kByteArrayBaseGetInt16: |
| 1088 return InlineByteArrayViewLoad(call, receiver_cid, | 1091 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1089 kTypedDataInt16ArrayCid, | 1092 kTypedDataInt16ArrayCid, |
| 1090 ic_data, entry, last); | 1093 ic_data, entry, last); |
| 1091 case MethodRecognizer::kByteArrayBaseGetUint16: | 1094 case MethodRecognizer::kByteArrayBaseGetUint16: |
| 1092 return InlineByteArrayViewLoad(call, receiver_cid, | 1095 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1093 kTypedDataUint16ArrayCid, | 1096 kTypedDataUint16ArrayCid, |
| 1094 ic_data, entry, last); | 1097 ic_data, entry, last); |
| 1095 case MethodRecognizer::kByteArrayBaseGetInt32: | 1098 case MethodRecognizer::kByteArrayBaseGetInt32: |
| 1096 if (!CanUnboxInt32()) return false; | 1099 if (!CanUnboxInt32()) return false; |
| 1097 return InlineByteArrayViewLoad(call, receiver_cid, | 1100 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1098 kTypedDataInt32ArrayCid, | 1101 kTypedDataInt32ArrayCid, |
| 1099 ic_data, entry, last); | 1102 ic_data, entry, last); |
| 1100 case MethodRecognizer::kByteArrayBaseGetUint32: | 1103 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 1101 if (!CanUnboxInt32()) return false; | 1104 if (!CanUnboxInt32()) return false; |
| 1102 return InlineByteArrayViewLoad(call, receiver_cid, | 1105 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1103 kTypedDataUint32ArrayCid, | 1106 kTypedDataUint32ArrayCid, |
| 1104 ic_data, entry, last); | 1107 ic_data, entry, last); |
| 1105 case MethodRecognizer::kByteArrayBaseGetFloat32: | 1108 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 1106 return InlineByteArrayViewLoad(call, receiver_cid, | 1109 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1107 kTypedDataFloat32ArrayCid, | 1110 kTypedDataFloat32ArrayCid, |
| 1108 ic_data, entry, last); | 1111 ic_data, entry, last); |
| 1109 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1112 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1110 return InlineByteArrayViewLoad(call, receiver_cid, | 1113 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1111 kTypedDataFloat64ArrayCid, | 1114 kTypedDataFloat64ArrayCid, |
| 1112 ic_data, entry, last); | 1115 ic_data, entry, last); |
| 1113 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | 1116 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1114 if (!ShouldInlineSimd()) return false; | 1117 if (!ShouldInlineSimd()) return false; |
| 1115 return InlineByteArrayViewLoad(call, receiver_cid, | 1118 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1116 kTypedDataFloat32x4ArrayCid, | 1119 kTypedDataFloat32x4ArrayCid, |
| 1117 ic_data, entry, last); | 1120 ic_data, entry, last); |
| 1118 default: | 1121 default: |
| 1119 return false; | 1122 return false; |
| 1120 } | 1123 } |
| 1121 } | 1124 } |
| 1122 | 1125 |
| 1123 | 1126 |
| 1124 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, | 1127 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, |
| 1125 intptr_t array_cid, | 1128 intptr_t array_cid, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 elements, | 1182 elements, |
| 1180 NULL, | 1183 NULL, |
| 1181 Definition::kValue); | 1184 Definition::kValue); |
| 1182 *array = elements; | 1185 *array = elements; |
| 1183 } | 1186 } |
| 1184 return array_cid; | 1187 return array_cid; |
| 1185 } | 1188 } |
| 1186 | 1189 |
| 1187 bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind, | 1190 bool FlowGraphOptimizer::InlineGetIndexed(MethodRecognizer::Kind kind, |
| 1188 Instruction* call, | 1191 Instruction* call, |
| 1192 Definition* receiver, |
| 1189 const ICData& ic_data, | 1193 const ICData& ic_data, |
| 1190 TargetEntryInstr** entry, | 1194 TargetEntryInstr** entry, |
| 1191 Definition** last) { | 1195 Definition** last) { |
| 1192 intptr_t array_cid = MethodKindToCid(kind); | 1196 intptr_t array_cid = MethodKindToCid(kind); |
| 1193 ASSERT(array_cid != kIllegalCid); | 1197 ASSERT(array_cid != kIllegalCid); |
| 1194 | 1198 |
| 1195 Definition* array = call->ArgumentAt(0); | 1199 Definition* array = receiver; |
| 1196 Definition* index = call->ArgumentAt(1); | 1200 Definition* index = call->ArgumentAt(1); |
| 1197 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), | 1201 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), |
| 1198 call->GetBlock()->try_index()); | 1202 call->GetBlock()->try_index()); |
| 1199 (*entry)->InheritDeoptTarget(call); | 1203 (*entry)->InheritDeoptTarget(call); |
| 1200 Instruction* cursor = *entry; | 1204 Instruction* cursor = *entry; |
| 1201 | 1205 |
| 1202 array_cid = PrepareInlineIndexedOp(call, | 1206 array_cid = PrepareInlineIndexedOp(call, |
| 1203 array_cid, | 1207 array_cid, |
| 1204 &array, | 1208 &array, |
| 1205 index, | 1209 index, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1235 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); | 1239 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); |
| 1236 if (ic_data.NumberOfChecks() != 1) return false; | 1240 if (ic_data.NumberOfChecks() != 1) return false; |
| 1237 ASSERT(ic_data.HasOneTarget()); | 1241 ASSERT(ic_data.HasOneTarget()); |
| 1238 | 1242 |
| 1239 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); | 1243 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 1240 TargetEntryInstr* entry; | 1244 TargetEntryInstr* entry; |
| 1241 Definition* last; | 1245 Definition* last; |
| 1242 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0), | 1246 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0), |
| 1243 target, | 1247 target, |
| 1244 call, | 1248 call, |
| 1249 call->ArgumentAt(0), |
| 1245 call->token_pos(), | 1250 call->token_pos(), |
| 1246 *call->ic_data(), | 1251 *call->ic_data(), |
| 1247 &entry, &last)) { | 1252 &entry, &last)) { |
| 1248 return false; | 1253 return false; |
| 1249 } | 1254 } |
| 1250 | 1255 |
| 1251 // Insert receiver class check. | 1256 // Insert receiver class check. |
| 1252 AddReceiverCheck(call); | 1257 AddReceiverCheck(call); |
| 1253 // Remove the original push arguments. | 1258 // Remove the original push arguments. |
| 1254 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 1259 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 ReplaceCall(call, setFlag); | 2481 ReplaceCall(call, setFlag); |
| 2477 return true; | 2482 return true; |
| 2478 } | 2483 } |
| 2479 default: | 2484 default: |
| 2480 return false; | 2485 return false; |
| 2481 } | 2486 } |
| 2482 } | 2487 } |
| 2483 | 2488 |
| 2484 | 2489 |
| 2485 bool FlowGraphOptimizer::InlineByteArrayViewLoad(Instruction* call, | 2490 bool FlowGraphOptimizer::InlineByteArrayViewLoad(Instruction* call, |
| 2491 Definition* receiver, |
| 2486 intptr_t array_cid, | 2492 intptr_t array_cid, |
| 2487 intptr_t view_cid, | 2493 intptr_t view_cid, |
| 2488 const ICData& ic_data, | 2494 const ICData& ic_data, |
| 2489 TargetEntryInstr** entry, | 2495 TargetEntryInstr** entry, |
| 2490 Definition** last) { | 2496 Definition** last) { |
| 2491 ASSERT(array_cid != kIllegalCid); | 2497 ASSERT(array_cid != kIllegalCid); |
| 2492 Definition* array = call->ArgumentAt(0); | 2498 Definition* array = receiver; |
| 2493 Definition* index = call->ArgumentAt(1); | 2499 Definition* index = call->ArgumentAt(1); |
| 2494 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), | 2500 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(), |
| 2495 call->GetBlock()->try_index()); | 2501 call->GetBlock()->try_index()); |
| 2496 (*entry)->InheritDeoptTarget(call); | 2502 (*entry)->InheritDeoptTarget(call); |
| 2497 Instruction* cursor = *entry; | 2503 Instruction* cursor = *entry; |
| 2498 | 2504 |
| 2499 array_cid = PrepareInlineByteArrayViewOp(call, | 2505 array_cid = PrepareInlineByteArrayViewOp(call, |
| 2500 array_cid, | 2506 array_cid, |
| 2501 view_cid, | 2507 view_cid, |
| 2502 &array, | 2508 &array, |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2618 Function& target = Function::Handle(); | 2624 Function& target = Function::Handle(); |
| 2619 GrowableArray<intptr_t> class_ids; | 2625 GrowableArray<intptr_t> class_ids; |
| 2620 call->ic_data()->GetCheckAt(0, &class_ids, &target); | 2626 call->ic_data()->GetCheckAt(0, &class_ids, &target); |
| 2621 const intptr_t receiver_cid = class_ids[0]; | 2627 const intptr_t receiver_cid = class_ids[0]; |
| 2622 | 2628 |
| 2623 TargetEntryInstr* entry; | 2629 TargetEntryInstr* entry; |
| 2624 Definition* last; | 2630 Definition* last; |
| 2625 if (!TryInlineRecognizedMethod(receiver_cid, | 2631 if (!TryInlineRecognizedMethod(receiver_cid, |
| 2626 target, | 2632 target, |
| 2627 call, | 2633 call, |
| 2634 call->ArgumentAt(0), |
| 2628 call->token_pos(), | 2635 call->token_pos(), |
| 2629 *call->ic_data(), | 2636 *call->ic_data(), |
| 2630 &entry, &last)) { | 2637 &entry, &last)) { |
| 2631 return false; | 2638 return false; |
| 2632 } | 2639 } |
| 2633 | 2640 |
| 2634 // Insert receiver class check. | 2641 // Insert receiver class check. |
| 2635 AddReceiverCheck(call); | 2642 AddReceiverCheck(call); |
| 2636 // Remove the original push arguments. | 2643 // Remove the original push arguments. |
| 2637 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 2644 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| (...skipping 5227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7865 } | 7872 } |
| 7866 | 7873 |
| 7867 // Insert materializations at environment uses. | 7874 // Insert materializations at environment uses. |
| 7868 for (intptr_t i = 0; i < exits.length(); i++) { | 7875 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7869 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7876 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7870 } | 7877 } |
| 7871 } | 7878 } |
| 7872 | 7879 |
| 7873 | 7880 |
| 7874 } // namespace dart | 7881 } // namespace dart |
| OLD | NEW |