| 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 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 608 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 609 __ pushq(RAX); // Push the instance. | 609 __ pushq(RAX); // Push the instance. |
| 610 __ PushObject(type); // Push the type. | 610 __ PushObject(type); // Push the type. |
| 611 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. | 611 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. |
| 612 __ pushq(RDX); // Instantiator type arguments. | 612 __ pushq(RDX); // Instantiator type arguments. |
| 613 __ LoadObject(RAX, test_cache); | 613 __ LoadObject(RAX, test_cache); |
| 614 __ pushq(RAX); | 614 __ pushq(RAX); |
| 615 GenerateCallRuntime(token_pos, | 615 GenerateCallRuntime(token_pos, |
| 616 deopt_id, | 616 deopt_id, |
| 617 kInstanceofRuntimeEntry, | 617 kInstanceofRuntimeEntry, |
| 618 5, |
| 618 locs); | 619 locs); |
| 619 // Pop the parameters supplied to the runtime entry. The result of the | 620 // Pop the parameters supplied to the runtime entry. The result of the |
| 620 // instanceof runtime call will be left as the result of the operation. | 621 // instanceof runtime call will be left as the result of the operation. |
| 621 __ Drop(5); | 622 __ Drop(5); |
| 622 if (negate_result) { | 623 if (negate_result) { |
| 623 __ popq(RDX); | 624 __ popq(RDX); |
| 624 __ LoadObject(RAX, Bool::True()); | 625 __ LoadObject(RAX, Bool::True()); |
| 625 __ cmpq(RDX, RAX); | 626 __ cmpq(RDX, RAX); |
| 626 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 627 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 627 __ LoadObject(RAX, Bool::False()); | 628 __ LoadObject(RAX, Bool::False()); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 } | 693 } |
| 693 const String& error_message = String::ZoneHandle( | 694 const String& error_message = String::ZoneHandle( |
| 694 Symbols::New(error.ToErrorCString())); | 695 Symbols::New(error.ToErrorCString())); |
| 695 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 696 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 696 __ pushq(RAX); // Push the source object. | 697 __ pushq(RAX); // Push the source object. |
| 697 __ PushObject(dst_name); // Push the name of the destination. | 698 __ PushObject(dst_name); // Push the name of the destination. |
| 698 __ PushObject(error_message); | 699 __ PushObject(error_message); |
| 699 GenerateCallRuntime(token_pos, | 700 GenerateCallRuntime(token_pos, |
| 700 deopt_id, | 701 deopt_id, |
| 701 kMalformedTypeErrorRuntimeEntry, | 702 kMalformedTypeErrorRuntimeEntry, |
| 703 3, |
| 702 locs); | 704 locs); |
| 703 // We should never return here. | 705 // We should never return here. |
| 704 __ int3(); | 706 __ int3(); |
| 705 | 707 |
| 706 __ Bind(&is_assignable); // For a null object. | 708 __ Bind(&is_assignable); // For a null object. |
| 707 __ popq(RDX); // Remove pushed instantiator type arguments. | 709 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 708 __ popq(RCX); // Remove pushed instantiator. | 710 __ popq(RCX); // Remove pushed instantiator. |
| 709 return; | 711 return; |
| 710 } | 712 } |
| 711 | 713 |
| 712 // Generate inline type check, linking to runtime call if not assignable. | 714 // Generate inline type check, linking to runtime call if not assignable. |
| 713 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 715 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
| 714 test_cache = GenerateInlineInstanceof(token_pos, dst_type, | 716 test_cache = GenerateInlineInstanceof(token_pos, dst_type, |
| 715 &is_assignable, &runtime_call); | 717 &is_assignable, &runtime_call); |
| 716 | 718 |
| 717 __ Bind(&runtime_call); | 719 __ Bind(&runtime_call); |
| 718 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 720 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 719 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 721 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 720 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 722 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 721 __ pushq(RAX); // Push the source object. | 723 __ pushq(RAX); // Push the source object. |
| 722 __ PushObject(dst_type); // Push the type of the destination. | 724 __ PushObject(dst_type); // Push the type of the destination. |
| 723 __ pushq(RCX); // Instantiator. | 725 __ pushq(RCX); // Instantiator. |
| 724 __ pushq(RDX); // Instantiator type arguments. | 726 __ pushq(RDX); // Instantiator type arguments. |
| 725 __ PushObject(dst_name); // Push the name of the destination. | 727 __ PushObject(dst_name); // Push the name of the destination. |
| 726 __ LoadObject(RAX, test_cache); | 728 __ LoadObject(RAX, test_cache); |
| 727 __ pushq(RAX); | 729 __ pushq(RAX); |
| 728 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs); | 730 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 729 // Pop the parameters supplied to the runtime entry. The result of the | 731 // Pop the parameters supplied to the runtime entry. The result of the |
| 730 // type check runtime call is the checked value. | 732 // type check runtime call is the checked value. |
| 731 __ Drop(6); | 733 __ Drop(6); |
| 732 __ popq(RAX); | 734 __ popq(RAX); |
| 733 | 735 |
| 734 __ Bind(&is_assignable); | 736 __ Bind(&is_assignable); |
| 735 __ popq(RDX); // Remove pushed instantiator type arguments. | 737 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 736 __ popq(RCX); // Remove pushed instantiator. | 738 __ popq(RCX); // Remove pushed instantiator. |
| 737 } | 739 } |
| 738 | 740 |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 // Add deoptimization continuation point after the call and before the | 1253 // Add deoptimization continuation point after the call and before the |
| 1252 // arguments are removed. | 1254 // arguments are removed. |
| 1253 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); | 1255 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); |
| 1254 } | 1256 } |
| 1255 } | 1257 } |
| 1256 | 1258 |
| 1257 | 1259 |
| 1258 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, | 1260 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, |
| 1259 intptr_t deopt_id, | 1261 intptr_t deopt_id, |
| 1260 const RuntimeEntry& entry, | 1262 const RuntimeEntry& entry, |
| 1263 intptr_t argument_count, |
| 1261 LocationSummary* locs) { | 1264 LocationSummary* locs) { |
| 1262 __ CallRuntime(entry); | 1265 __ CallRuntime(entry, argument_count); |
| 1263 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); | 1266 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); |
| 1264 RecordSafepoint(locs); | 1267 RecordSafepoint(locs); |
| 1265 if (deopt_id != Isolate::kNoDeoptId) { | 1268 if (deopt_id != Isolate::kNoDeoptId) { |
| 1266 // Marks either the continuation point in unoptimized code or the | 1269 // Marks either the continuation point in unoptimized code or the |
| 1267 // deoptimization point in optimized code, after call. | 1270 // deoptimization point in optimized code, after call. |
| 1268 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); | 1271 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); |
| 1269 if (is_optimizing()) { | 1272 if (is_optimizing()) { |
| 1270 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1273 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1271 } else { | 1274 } else { |
| 1272 // Add deoptimization continuation point after the call and before the | 1275 // Add deoptimization continuation point after the call and before the |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 __ movups(reg, Address(RSP, 0)); | 1891 __ movups(reg, Address(RSP, 0)); |
| 1889 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1892 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1890 } | 1893 } |
| 1891 | 1894 |
| 1892 | 1895 |
| 1893 #undef __ | 1896 #undef __ |
| 1894 | 1897 |
| 1895 } // namespace dart | 1898 } // namespace dart |
| 1896 | 1899 |
| 1897 #endif // defined TARGET_ARCH_X64 | 1900 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |