| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( | 218 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( |
| 219 TypeTestStubKind test_kind, | 219 TypeTestStubKind test_kind, |
| 220 Register instance_reg, | 220 Register instance_reg, |
| 221 Register type_arguments_reg, | 221 Register type_arguments_reg, |
| 222 Register temp_reg, | 222 Register temp_reg, |
| 223 Label* is_instance_lbl, | 223 Label* is_instance_lbl, |
| 224 Label* is_not_instance_lbl) { | 224 Label* is_not_instance_lbl) { |
| 225 const SubtypeTestCache& type_test_cache = | 225 const SubtypeTestCache& type_test_cache = |
| 226 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); | 226 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); |
| 227 StubCode* stub_code = isolate()->stub_code(); | 227 StubCode* stub_code = isolate()->stub_code(); |
| 228 __ LoadObject(temp_reg, type_test_cache, PP); | 228 __ LoadUniqueObject(temp_reg, type_test_cache, PP); |
| 229 __ pushq(temp_reg); // Subtype test cache. | 229 __ pushq(temp_reg); // Subtype test cache. |
| 230 __ pushq(instance_reg); // Instance. | 230 __ pushq(instance_reg); // Instance. |
| 231 if (test_kind == kTestTypeOneArg) { | 231 if (test_kind == kTestTypeOneArg) { |
| 232 ASSERT(type_arguments_reg == kNoRegister); | 232 ASSERT(type_arguments_reg == kNoRegister); |
| 233 __ PushObject(Object::null_object(), PP); | 233 __ PushObject(Object::null_object(), PP); |
| 234 __ Call(&stub_code->Subtype1TestCacheLabel(), PP); | 234 __ Call(&stub_code->Subtype1TestCacheLabel(), PP); |
| 235 } else if (test_kind == kTestTypeTwoArgs) { | 235 } else if (test_kind == kTestTypeTwoArgs) { |
| 236 ASSERT(type_arguments_reg == kNoRegister); | 236 ASSERT(type_arguments_reg == kNoRegister); |
| 237 __ PushObject(Object::null_object(), PP); | 237 __ PushObject(Object::null_object(), PP); |
| 238 __ Call(&stub_code->Subtype2TestCacheLabel(), PP); | 238 __ Call(&stub_code->Subtype2TestCacheLabel(), PP); |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 Label done; | 616 Label done; |
| 617 if (!test_cache.IsNull()) { | 617 if (!test_cache.IsNull()) { |
| 618 // Generate runtime call. | 618 // Generate runtime call. |
| 619 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 619 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 620 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 620 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 621 __ PushObject(Object::null_object(), PP); // Make room for the result. | 621 __ PushObject(Object::null_object(), PP); // Make room for the result. |
| 622 __ pushq(RAX); // Push the instance. | 622 __ pushq(RAX); // Push the instance. |
| 623 __ PushObject(type, PP); // Push the type. | 623 __ PushObject(type, PP); // Push the type. |
| 624 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. | 624 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. |
| 625 __ pushq(RDX); // Instantiator type arguments. | 625 __ pushq(RDX); // Instantiator type arguments. |
| 626 __ LoadObject(RAX, test_cache, PP); | 626 __ LoadUniqueObject(RAX, test_cache, PP); |
| 627 __ pushq(RAX); | 627 __ pushq(RAX); |
| 628 GenerateRuntimeCall(token_pos, | 628 GenerateRuntimeCall(token_pos, |
| 629 deopt_id, | 629 deopt_id, |
| 630 kInstanceofRuntimeEntry, | 630 kInstanceofRuntimeEntry, |
| 631 5, | 631 5, |
| 632 locs); | 632 locs); |
| 633 // Pop the parameters supplied to the runtime entry. The result of the | 633 // Pop the parameters supplied to the runtime entry. The result of the |
| 634 // instanceof runtime call will be left as the result of the operation. | 634 // instanceof runtime call will be left as the result of the operation. |
| 635 __ Drop(5); | 635 __ Drop(5); |
| 636 if (negate_result) { | 636 if (negate_result) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 | 713 |
| 714 __ Bind(&runtime_call); | 714 __ Bind(&runtime_call); |
| 715 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 715 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 716 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 716 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 717 __ PushObject(Object::null_object(), PP); // Make room for the result. | 717 __ PushObject(Object::null_object(), PP); // Make room for the result. |
| 718 __ pushq(RAX); // Push the source object. | 718 __ pushq(RAX); // Push the source object. |
| 719 __ PushObject(dst_type, PP); // Push the type of the destination. | 719 __ PushObject(dst_type, PP); // Push the type of the destination. |
| 720 __ pushq(RCX); // Instantiator. | 720 __ pushq(RCX); // Instantiator. |
| 721 __ pushq(RDX); // Instantiator type arguments. | 721 __ pushq(RDX); // Instantiator type arguments. |
| 722 __ PushObject(dst_name, PP); // Push the name of the destination. | 722 __ PushObject(dst_name, PP); // Push the name of the destination. |
| 723 __ LoadObject(RAX, test_cache, PP); | 723 __ LoadUniqueObject(RAX, test_cache, PP); |
| 724 __ pushq(RAX); | 724 __ pushq(RAX); |
| 725 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); | 725 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 726 // Pop the parameters supplied to the runtime entry. The result of the | 726 // Pop the parameters supplied to the runtime entry. The result of the |
| 727 // type check runtime call is the checked value. | 727 // type check runtime call is the checked value. |
| 728 __ Drop(6); | 728 __ Drop(6); |
| 729 __ popq(RAX); | 729 __ popq(RAX); |
| 730 | 730 |
| 731 __ Bind(&is_assignable); | 731 __ Bind(&is_assignable); |
| 732 __ popq(RDX); // Remove pushed instantiator type arguments. | 732 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 733 __ popq(RCX); // Remove pushed instantiator. | 733 __ popq(RCX); // Remove pushed instantiator. |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1237 | 1237 |
| 1238 void FlowGraphCompiler::EmitEdgeCounter() { | 1238 void FlowGraphCompiler::EmitEdgeCounter() { |
| 1239 // We do not check for overflow when incrementing the edge counter. The | 1239 // We do not check for overflow when incrementing the edge counter. The |
| 1240 // function should normally be optimized long before the counter can | 1240 // function should normally be optimized long before the counter can |
| 1241 // overflow; and though we do not reset the counters when we optimize or | 1241 // overflow; and though we do not reset the counters when we optimize or |
| 1242 // deoptimize, there is a bound on the number of | 1242 // deoptimize, there is a bound on the number of |
| 1243 // optimization/deoptimization cycles we will attempt. | 1243 // optimization/deoptimization cycles we will attempt. |
| 1244 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); | 1244 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld)); |
| 1245 counter.SetAt(0, Smi::Handle(Smi::New(0))); | 1245 counter.SetAt(0, Smi::Handle(Smi::New(0))); |
| 1246 __ Comment("Edge counter"); | 1246 __ Comment("Edge counter"); |
| 1247 __ LoadObject(RAX, counter, PP); | 1247 __ LoadUniqueObject(RAX, counter, PP); |
| 1248 intptr_t increment_start = assembler_->CodeSize(); | 1248 intptr_t increment_start = assembler_->CodeSize(); |
| 1249 __ IncrementSmiField(FieldAddress(RAX, Array::element_offset(0)), 1); | 1249 __ IncrementSmiField(FieldAddress(RAX, Array::element_offset(0)), 1); |
| 1250 int32_t size = assembler_->CodeSize() - increment_start; | 1250 int32_t size = assembler_->CodeSize() - increment_start; |
| 1251 if (isolate()->edge_counter_increment_size() == -1) { | 1251 if (isolate()->edge_counter_increment_size() == -1) { |
| 1252 isolate()->set_edge_counter_increment_size(size); | 1252 isolate()->set_edge_counter_increment_size(size); |
| 1253 } else { | 1253 } else { |
| 1254 ASSERT(size == isolate()->edge_counter_increment_size()); | 1254 ASSERT(size == isolate()->edge_counter_increment_size()); |
| 1255 } | 1255 } |
| 1256 } | 1256 } |
| 1257 | 1257 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1271 intptr_t token_pos, | 1271 intptr_t token_pos, |
| 1272 LocationSummary* locs) { | 1272 LocationSummary* locs) { |
| 1273 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1273 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
| 1274 // Each ICData propagated from unoptimized to optimized code contains the | 1274 // Each ICData propagated from unoptimized to optimized code contains the |
| 1275 // function that corresponds to the Dart function of that IC call. Due | 1275 // function that corresponds to the Dart function of that IC call. Due |
| 1276 // to inlining in optimized code, that function may not correspond to the | 1276 // to inlining in optimized code, that function may not correspond to the |
| 1277 // top-level function (parsed_function().function()) which could be | 1277 // top-level function (parsed_function().function()) which could be |
| 1278 // reoptimized and which counter needs to be incremented. | 1278 // reoptimized and which counter needs to be incremented. |
| 1279 // Pass the function explicitly, it is used in IC stub. | 1279 // Pass the function explicitly, it is used in IC stub. |
| 1280 __ LoadObject(RDI, parsed_function().function(), PP); | 1280 __ LoadObject(RDI, parsed_function().function(), PP); |
| 1281 __ LoadObject(RBX, ic_data, PP); | 1281 __ LoadUniqueObject(RBX, ic_data, PP); |
| 1282 GenerateDartCall(deopt_id, | 1282 GenerateDartCall(deopt_id, |
| 1283 token_pos, | 1283 token_pos, |
| 1284 target_label, | 1284 target_label, |
| 1285 RawPcDescriptors::kIcCall, | 1285 RawPcDescriptors::kIcCall, |
| 1286 locs); | 1286 locs); |
| 1287 __ Drop(argument_count, RCX); | 1287 __ Drop(argument_count, RCX); |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 | 1290 |
| 1291 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, | 1291 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, |
| 1292 const ICData& ic_data, | 1292 const ICData& ic_data, |
| 1293 intptr_t argument_count, | 1293 intptr_t argument_count, |
| 1294 intptr_t deopt_id, | 1294 intptr_t deopt_id, |
| 1295 intptr_t token_pos, | 1295 intptr_t token_pos, |
| 1296 LocationSummary* locs) { | 1296 LocationSummary* locs) { |
| 1297 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); | 1297 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); |
| 1298 __ LoadObject(RBX, ic_data, PP); | 1298 __ LoadUniqueObject(RBX, ic_data, PP); |
| 1299 GenerateDartCall(deopt_id, | 1299 GenerateDartCall(deopt_id, |
| 1300 token_pos, | 1300 token_pos, |
| 1301 target_label, | 1301 target_label, |
| 1302 RawPcDescriptors::kIcCall, | 1302 RawPcDescriptors::kIcCall, |
| 1303 locs); | 1303 locs); |
| 1304 __ Drop(argument_count, RCX); | 1304 __ Drop(argument_count, RCX); |
| 1305 } | 1305 } |
| 1306 | 1306 |
| 1307 | 1307 |
| 1308 void FlowGraphCompiler::EmitMegamorphicInstanceCall( | 1308 void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 __ movups(reg, Address(RSP, 0)); | 1794 __ movups(reg, Address(RSP, 0)); |
| 1795 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); | 1795 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); |
| 1796 } | 1796 } |
| 1797 | 1797 |
| 1798 | 1798 |
| 1799 #undef __ | 1799 #undef __ |
| 1800 | 1800 |
| 1801 } // namespace dart | 1801 } // namespace dart |
| 1802 | 1802 |
| 1803 #endif // defined TARGET_ARCH_X64 | 1803 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |