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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 ASSERT(reason() != ICData::kDeoptAtCall); | 181 ASSERT(reason() != ICData::kDeoptAtCall); |
182 Assembler* assem = compiler->assembler(); | 182 Assembler* assem = compiler->assembler(); |
183 #define __ assem-> | 183 #define __ assem-> |
184 __ Comment("%s", Name()); | 184 __ Comment("%s", Name()); |
185 __ Bind(entry_label()); | 185 __ Bind(entry_label()); |
186 if (FLAG_trap_on_deoptimization) { | 186 if (FLAG_trap_on_deoptimization) { |
187 __ int3(); | 187 __ int3(); |
188 } | 188 } |
189 | 189 |
190 ASSERT(deopt_env() != NULL); | 190 ASSERT(deopt_env() != NULL); |
191 | 191 __ pushl(CODE_REG); |
192 __ Call(*StubCode::Deoptimize_entry()); | 192 __ Call(*StubCode::Deoptimize_entry()); |
193 set_pc_offset(assem->CodeSize()); | 193 set_pc_offset(assem->CodeSize()); |
194 __ int3(); | 194 __ int3(); |
195 #undef __ | 195 #undef __ |
196 } | 196 } |
197 | 197 |
198 | 198 |
199 #define __ assembler()-> | 199 #define __ assembler()-> |
200 | 200 |
201 | 201 |
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 } | 992 } |
993 | 993 |
994 | 994 |
995 // NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc | 995 // NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc |
996 // needs to be updated to match. | 996 // needs to be updated to match. |
997 void FlowGraphCompiler::EmitFrameEntry() { | 997 void FlowGraphCompiler::EmitFrameEntry() { |
998 const Function& function = parsed_function().function(); | 998 const Function& function = parsed_function().function(); |
999 if (CanOptimizeFunction() && | 999 if (CanOptimizeFunction() && |
1000 function.IsOptimizable() && | 1000 function.IsOptimizable() && |
1001 (!is_optimizing() || may_reoptimize())) { | 1001 (!is_optimizing() || may_reoptimize())) { |
1002 const Register function_reg = EDI; | 1002 const Register function_reg = EBX; |
1003 __ LoadObject(function_reg, function); | 1003 __ LoadObject(function_reg, function); |
1004 | 1004 |
1005 // Patch point is after the eventually inlined function object. | |
1006 entry_patch_pc_offset_ = assembler()->CodeSize(); | |
1007 | |
1008 // Reoptimization of an optimized function is triggered by counting in | 1005 // Reoptimization of an optimized function is triggered by counting in |
1009 // IC stubs, but not at the entry of the function. | 1006 // IC stubs, but not at the entry of the function. |
1010 if (!is_optimizing()) { | 1007 if (!is_optimizing()) { |
1011 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); | 1008 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); |
1012 } | 1009 } |
1013 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()), | 1010 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()), |
1014 Immediate(GetOptimizationThreshold())); | 1011 Immediate(GetOptimizationThreshold())); |
1015 ASSERT(function_reg == EDI); | 1012 ASSERT(function_reg == EBX); |
1016 __ J(GREATER_EQUAL, *StubCode::OptimizeFunction_entry()); | 1013 __ J(GREATER_EQUAL, *StubCode::OptimizeFunction_entry()); |
1017 } else if (!flow_graph().IsCompiledForOsr()) { | |
1018 entry_patch_pc_offset_ = assembler()->CodeSize(); | |
1019 } | 1014 } |
1020 __ Comment("Enter frame"); | 1015 __ Comment("Enter frame"); |
1021 if (flow_graph().IsCompiledForOsr()) { | 1016 if (flow_graph().IsCompiledForOsr()) { |
1022 intptr_t extra_slots = StackSize() | 1017 intptr_t extra_slots = StackSize() |
1023 - flow_graph().num_stack_locals() | 1018 - flow_graph().num_stack_locals() |
1024 - flow_graph().num_copied_params(); | 1019 - flow_graph().num_copied_params(); |
1025 ASSERT(extra_slots >= 0); | 1020 ASSERT(extra_slots >= 0); |
1026 __ EnterOsrFrame(extra_slots * kWordSize); | 1021 __ EnterOsrFrame(extra_slots * kWordSize); |
1027 } else { | 1022 } else { |
1028 ASSERT(StackSize() >= 0); | 1023 ASSERT(StackSize() >= 0); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); | 1124 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); |
1130 } | 1125 } |
1131 } | 1126 } |
1132 } | 1127 } |
1133 | 1128 |
1134 ASSERT(!block_order().is_empty()); | 1129 ASSERT(!block_order().is_empty()); |
1135 VisitBlocks(); | 1130 VisitBlocks(); |
1136 | 1131 |
1137 __ int3(); | 1132 __ int3(); |
1138 GenerateDeferredCode(); | 1133 GenerateDeferredCode(); |
1139 // Emit function patching code. This will be swapped with the first 5 bytes | |
1140 // at entry point. | |
1141 patch_code_pc_offset_ = assembler()->CodeSize(); | |
1142 __ Jmp(*StubCode::FixCallersTarget_entry()); | |
1143 | 1134 |
1144 if (is_optimizing()) { | 1135 if (is_optimizing()) { |
1145 lazy_deopt_pc_offset_ = assembler()->CodeSize(); | 1136 lazy_deopt_pc_offset_ = assembler()->CodeSize(); |
1146 __ Jmp(*StubCode::DeoptimizeLazy_entry()); | 1137 __ Jmp(*StubCode::DeoptimizeLazy_entry()); |
1147 } | 1138 } |
1148 } | 1139 } |
1149 | 1140 |
1150 | 1141 |
1151 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, | 1142 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, |
1152 const StubEntry& stub_entry, | 1143 const StubEntry& stub_entry, |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1255 intptr_t deopt_id, | 1246 intptr_t deopt_id, |
1256 intptr_t token_pos, | 1247 intptr_t token_pos, |
1257 LocationSummary* locs) { | 1248 LocationSummary* locs) { |
1258 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1249 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
1259 // Each ICData propagated from unoptimized to optimized code contains the | 1250 // Each ICData propagated from unoptimized to optimized code contains the |
1260 // function that corresponds to the Dart function of that IC call. Due | 1251 // function that corresponds to the Dart function of that IC call. Due |
1261 // to inlining in optimized code, that function may not correspond to the | 1252 // to inlining in optimized code, that function may not correspond to the |
1262 // top-level function (parsed_function().function()) which could be | 1253 // top-level function (parsed_function().function()) which could be |
1263 // reoptimized and which counter needs to be incremented. | 1254 // reoptimized and which counter needs to be incremented. |
1264 // Pass the function explicitly, it is used in IC stub. | 1255 // Pass the function explicitly, it is used in IC stub. |
1265 __ LoadObject(EDI, parsed_function().function()); | 1256 __ LoadObject(EBX, parsed_function().function()); |
1266 __ LoadObject(ECX, ic_data); | 1257 __ LoadObject(ECX, ic_data); |
1267 GenerateDartCall(deopt_id, | 1258 GenerateDartCall(deopt_id, |
1268 token_pos, | 1259 token_pos, |
1269 stub_entry, | 1260 stub_entry, |
1270 RawPcDescriptors::kIcCall, | 1261 RawPcDescriptors::kIcCall, |
1271 locs); | 1262 locs); |
1272 __ Drop(argument_count); | 1263 __ Drop(argument_count); |
1273 } | 1264 } |
1274 | 1265 |
1275 | 1266 |
(...skipping 20 matching lines...) Expand all Loading... |
1296 intptr_t deopt_id, | 1287 intptr_t deopt_id, |
1297 intptr_t token_pos, | 1288 intptr_t token_pos, |
1298 LocationSummary* locs) { | 1289 LocationSummary* locs) { |
1299 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table(); | 1290 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table(); |
1300 const String& name = String::Handle(zone(), ic_data.target_name()); | 1291 const String& name = String::Handle(zone(), ic_data.target_name()); |
1301 const Array& arguments_descriptor = | 1292 const Array& arguments_descriptor = |
1302 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); | 1293 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); |
1303 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); | 1294 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); |
1304 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), | 1295 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), |
1305 table->Lookup(name, arguments_descriptor)); | 1296 table->Lookup(name, arguments_descriptor)); |
1306 const Register receiverR = EDI; | 1297 const Register receiverR = ECX; |
1307 const Register cacheR = EBX; | 1298 const Register cacheR = EBX; |
1308 const Register targetR = EBX; | 1299 const Register targetR = EBX; |
1309 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize)); | 1300 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize)); |
1310 __ LoadObject(cacheR, cache); | 1301 __ LoadObject(cacheR, cache); |
1311 | 1302 |
1312 if (FLAG_use_megamorphic_stub) { | 1303 if (FLAG_use_megamorphic_stub) { |
1313 __ Call(*StubCode::MegamorphicLookup_entry()); | 1304 __ Call(*StubCode::MegamorphicLookup_entry()); |
1314 } else { | 1305 } else { |
1315 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); | 1306 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); |
1316 } | 1307 } |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 __ movups(reg, Address(ESP, 0)); | 1839 __ movups(reg, Address(ESP, 0)); |
1849 __ addl(ESP, Immediate(kFpuRegisterSize)); | 1840 __ addl(ESP, Immediate(kFpuRegisterSize)); |
1850 } | 1841 } |
1851 | 1842 |
1852 | 1843 |
1853 #undef __ | 1844 #undef __ |
1854 | 1845 |
1855 } // namespace dart | 1846 } // namespace dart |
1856 | 1847 |
1857 #endif // defined TARGET_ARCH_IA32 | 1848 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |