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 |