| 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/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/cha.h" | 10 #include "vm/cha.h" |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 pending_deoptimization_env_); | 801 pending_deoptimization_env_); |
| 802 info->set_pc_offset(assembler()->CodeSize()); | 802 info->set_pc_offset(assembler()->CodeSize()); |
| 803 deopt_infos_.Add(info); | 803 deopt_infos_.Add(info); |
| 804 } | 804 } |
| 805 | 805 |
| 806 | 806 |
| 807 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters | 807 // This function must be in sync with FlowGraphCompiler::SaveLiveRegisters |
| 808 // and FlowGraphCompiler::SlowPathEnvironmentFor. | 808 // and FlowGraphCompiler::SlowPathEnvironmentFor. |
| 809 // See StackFrame::VisitObjectPointers for the details of how stack map is | 809 // See StackFrame::VisitObjectPointers for the details of how stack map is |
| 810 // interpreted. | 810 // interpreted. |
| 811 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { | 811 void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs, |
| 812 intptr_t slow_path_argument_count) { |
| 812 if (is_optimizing() || locs->live_registers()->HasUntaggedValues()) { | 813 if (is_optimizing() || locs->live_registers()->HasUntaggedValues()) { |
| 813 const intptr_t spill_area_size = is_optimizing() ? | 814 const intptr_t spill_area_size = is_optimizing() ? |
| 814 flow_graph_.graph_entry()->spill_slot_count() : 0; | 815 flow_graph_.graph_entry()->spill_slot_count() : 0; |
| 815 | 816 |
| 816 RegisterSet* registers = locs->live_registers(); | 817 RegisterSet* registers = locs->live_registers(); |
| 817 ASSERT(registers != NULL); | 818 ASSERT(registers != NULL); |
| 818 const intptr_t kFpuRegisterSpillFactor = | 819 const intptr_t kFpuRegisterSpillFactor = |
| 819 kFpuRegisterSize / kWordSize; | 820 kFpuRegisterSize / kWordSize; |
| 820 const intptr_t live_registers_size = registers->CpuRegisterCount() + | 821 const intptr_t live_registers_size = registers->CpuRegisterCount() + |
| 821 (registers->FpuRegisterCount() * kFpuRegisterSpillFactor); | 822 (registers->FpuRegisterCount() * kFpuRegisterSpillFactor); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 // General purpose registers have the highest register number at the | 862 // General purpose registers have the highest register number at the |
| 862 // highest address (i.e., first in the stackmap). | 863 // highest address (i.e., first in the stackmap). |
| 863 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) { | 864 for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; --i) { |
| 864 Register reg = static_cast<Register>(i); | 865 Register reg = static_cast<Register>(i); |
| 865 if (locs->live_registers()->ContainsRegister(reg)) { | 866 if (locs->live_registers()->ContainsRegister(reg)) { |
| 866 bitmap->Set(bitmap->Length(), locs->live_registers()->IsTagged(reg)); | 867 bitmap->Set(bitmap->Length(), locs->live_registers()->IsTagged(reg)); |
| 867 } | 868 } |
| 868 } | 869 } |
| 869 } | 870 } |
| 870 | 871 |
| 871 intptr_t register_bit_count = bitmap->Length() - spill_area_size; | 872 // Arguments pushed on top of live registers in the slow path are tagged. |
| 873 for (intptr_t i = 0; i < slow_path_argument_count; ++i) { |
| 874 bitmap->Set(bitmap->Length(), true); |
| 875 } |
| 876 |
| 877 // The slow path area Outside the spill area contains are live registers |
| 878 // and pushed arguments for calls inside the slow path. |
| 879 intptr_t slow_path_bit_count = bitmap->Length() - spill_area_size; |
| 872 stackmap_table_builder()->AddEntry(assembler()->CodeSize(), | 880 stackmap_table_builder()->AddEntry(assembler()->CodeSize(), |
| 873 bitmap, | 881 bitmap, |
| 874 register_bit_count); | 882 slow_path_bit_count); |
| 875 } | 883 } |
| 876 } | 884 } |
| 877 | 885 |
| 878 | 886 |
| 879 // This function must be kept in sync with: | 887 // This function must be kept in sync with: |
| 880 // | 888 // |
| 881 // FlowGraphCompiler::RecordSafepoint | 889 // FlowGraphCompiler::RecordSafepoint |
| 882 // FlowGraphCompiler::SaveLiveRegisters | 890 // FlowGraphCompiler::SaveLiveRegisters |
| 883 // MaterializeObjectInstr::RemapRegisters | 891 // MaterializeObjectInstr::RemapRegisters |
| 884 // | 892 // |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 LocationSummary* locs, | 1154 LocationSummary* locs, |
| 1147 const ICData& ic_data_in) { | 1155 const ICData& ic_data_in) { |
| 1148 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); | 1156 const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original()); |
| 1149 if (FLAG_precompiled_mode) { | 1157 if (FLAG_precompiled_mode) { |
| 1150 EmitSwitchableInstanceCall(ic_data, argument_count, | 1158 EmitSwitchableInstanceCall(ic_data, argument_count, |
| 1151 deopt_id, token_pos, locs); | 1159 deopt_id, token_pos, locs); |
| 1152 return; | 1160 return; |
| 1153 } | 1161 } |
| 1154 if (FLAG_always_megamorphic_calls) { | 1162 if (FLAG_always_megamorphic_calls) { |
| 1155 EmitMegamorphicInstanceCall(ic_data, argument_count, | 1163 EmitMegamorphicInstanceCall(ic_data, argument_count, |
| 1156 deopt_id, token_pos, locs); | 1164 deopt_id, token_pos, locs, |
| 1165 CatchClauseNode::kInvalidTryIndex); |
| 1157 return; | 1166 return; |
| 1158 } | 1167 } |
| 1159 ASSERT(!ic_data.IsNull()); | 1168 ASSERT(!ic_data.IsNull()); |
| 1160 if (is_optimizing() && (ic_data.NumberOfUsedChecks() == 0)) { | 1169 if (is_optimizing() && (ic_data.NumberOfUsedChecks() == 0)) { |
| 1161 // Emit IC call that will count and thus may need reoptimization at | 1170 // Emit IC call that will count and thus may need reoptimization at |
| 1162 // function entry. | 1171 // function entry. |
| 1163 ASSERT(may_reoptimize() || flow_graph().IsCompiledForOsr()); | 1172 ASSERT(may_reoptimize() || flow_graph().IsCompiledForOsr()); |
| 1164 switch (ic_data.NumArgsTested()) { | 1173 switch (ic_data.NumArgsTested()) { |
| 1165 case 1: | 1174 case 1: |
| 1166 EmitOptimizedInstanceCall( | 1175 EmitOptimizedInstanceCall( |
| 1167 *StubCode::OneArgOptimizedCheckInlineCache_entry(), ic_data, | 1176 *StubCode::OneArgOptimizedCheckInlineCache_entry(), ic_data, |
| 1168 argument_count, deopt_id, token_pos, locs); | 1177 argument_count, deopt_id, token_pos, locs); |
| 1169 return; | 1178 return; |
| 1170 case 2: | 1179 case 2: |
| 1171 EmitOptimizedInstanceCall( | 1180 EmitOptimizedInstanceCall( |
| 1172 *StubCode::TwoArgsOptimizedCheckInlineCache_entry(), ic_data, | 1181 *StubCode::TwoArgsOptimizedCheckInlineCache_entry(), ic_data, |
| 1173 argument_count, deopt_id, token_pos, locs); | 1182 argument_count, deopt_id, token_pos, locs); |
| 1174 return; | 1183 return; |
| 1175 default: | 1184 default: |
| 1176 UNIMPLEMENTED(); | 1185 UNIMPLEMENTED(); |
| 1177 } | 1186 } |
| 1178 return; | 1187 return; |
| 1179 } | 1188 } |
| 1180 | 1189 |
| 1181 if (is_optimizing()) { | 1190 if (is_optimizing()) { |
| 1182 EmitMegamorphicInstanceCall(ic_data, argument_count, | 1191 EmitMegamorphicInstanceCall(ic_data, argument_count, |
| 1183 deopt_id, token_pos, locs); | 1192 deopt_id, token_pos, locs, |
| 1193 CatchClauseNode::kInvalidTryIndex); |
| 1184 return; | 1194 return; |
| 1185 } | 1195 } |
| 1186 | 1196 |
| 1187 switch (ic_data.NumArgsTested()) { | 1197 switch (ic_data.NumArgsTested()) { |
| 1188 case 1: | 1198 case 1: |
| 1189 EmitInstanceCall( | 1199 EmitInstanceCall( |
| 1190 *StubCode::OneArgCheckInlineCache_entry(), ic_data, argument_count, | 1200 *StubCode::OneArgCheckInlineCache_entry(), ic_data, argument_count, |
| 1191 deopt_id, token_pos, locs); | 1201 deopt_id, token_pos, locs); |
| 1192 break; | 1202 break; |
| 1193 case 2: | 1203 case 2: |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 | 1934 |
| 1925 | 1935 |
| 1926 void FlowGraphCompiler::FrameStateClear() { | 1936 void FlowGraphCompiler::FrameStateClear() { |
| 1927 ASSERT(!is_optimizing()); | 1937 ASSERT(!is_optimizing()); |
| 1928 frame_state_.TruncateTo(0); | 1938 frame_state_.TruncateTo(0); |
| 1929 } | 1939 } |
| 1930 #endif | 1940 #endif |
| 1931 | 1941 |
| 1932 | 1942 |
| 1933 } // namespace dart | 1943 } // namespace dart |
| OLD | NEW |