| 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 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 585 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
| 586 test_cache = GenerateInlineInstanceof(token_pos, type, | 586 test_cache = GenerateInlineInstanceof(token_pos, type, |
| 587 &is_instance, &is_not_instance); | 587 &is_instance, &is_not_instance); |
| 588 | 588 |
| 589 // test_cache is null if there is no fall-through. | 589 // test_cache is null if there is no fall-through. |
| 590 Label done; | 590 Label done; |
| 591 if (!test_cache.IsNull()) { | 591 if (!test_cache.IsNull()) { |
| 592 // Generate runtime call. | 592 // Generate runtime call. |
| 593 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 593 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 594 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 594 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 595 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. | 595 __ PushObject(Object::null_object(), PP); // Make room for the result. |
| 596 __ pushq(RAX); // Push the instance. | 596 __ pushq(RAX); // Push the instance. |
| 597 __ PushObject(type, PP); // Push the type. | 597 __ PushObject(type, PP); // Push the type. |
| 598 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. | 598 __ pushq(RCX); // TODO(srdjan): Pass instantiator instead of null. |
| 599 __ pushq(RDX); // Instantiator type arguments. | 599 __ pushq(RDX); // Instantiator type arguments. |
| 600 __ LoadObject(RAX, test_cache, PP); | 600 __ LoadObject(RAX, test_cache, PP); |
| 601 __ pushq(RAX); | 601 __ pushq(RAX); |
| 602 GenerateRuntimeCall(token_pos, | 602 GenerateRuntimeCall(token_pos, |
| 603 deopt_id, | 603 deopt_id, |
| 604 kInstanceofRuntimeEntry, | 604 kInstanceofRuntimeEntry, |
| 605 5, | 605 5, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); | 655 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); |
| 656 __ pushq(RCX); // Store instantiator. | 656 __ pushq(RCX); // Store instantiator. |
| 657 __ pushq(RDX); // Store instantiator type arguments. | 657 __ pushq(RDX); // Store instantiator type arguments. |
| 658 // A null object is always assignable and is returned as result. | 658 // A null object is always assignable and is returned as result. |
| 659 Label is_assignable, runtime_call; | 659 Label is_assignable, runtime_call; |
| 660 __ CompareObject(RAX, Object::null_object(), PP); | 660 __ CompareObject(RAX, Object::null_object(), PP); |
| 661 __ j(EQUAL, &is_assignable); | 661 __ j(EQUAL, &is_assignable); |
| 662 | 662 |
| 663 // Generate throw new TypeError() if the type is malformed or malbounded. | 663 // Generate throw new TypeError() if the type is malformed or malbounded. |
| 664 if (dst_type.IsMalformedOrMalbounded()) { | 664 if (dst_type.IsMalformedOrMalbounded()) { |
| 665 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. | 665 __ PushObject(Object::null_object(), PP); // Make room for the result. |
| 666 __ pushq(RAX); // Push the source object. | 666 __ pushq(RAX); // Push the source object. |
| 667 __ PushObject(dst_name, PP); // Push the name of the destination. | 667 __ PushObject(dst_name, PP); // Push the name of the destination. |
| 668 __ PushObject(dst_type, PP); // Push the type of the destination. | 668 __ PushObject(dst_type, PP); // Push the type of the destination. |
| 669 GenerateRuntimeCall(token_pos, | 669 GenerateRuntimeCall(token_pos, |
| 670 deopt_id, | 670 deopt_id, |
| 671 kBadTypeErrorRuntimeEntry, | 671 kBadTypeErrorRuntimeEntry, |
| 672 3, | 672 3, |
| 673 locs); | 673 locs); |
| 674 // We should never return here. | 674 // We should never return here. |
| 675 __ int3(); | 675 __ int3(); |
| 676 | 676 |
| 677 __ Bind(&is_assignable); // For a null object. | 677 __ Bind(&is_assignable); // For a null object. |
| 678 __ popq(RDX); // Remove pushed instantiator type arguments. | 678 __ popq(RDX); // Remove pushed instantiator type arguments. |
| 679 __ popq(RCX); // Remove pushed instantiator. | 679 __ popq(RCX); // Remove pushed instantiator. |
| 680 return; | 680 return; |
| 681 } | 681 } |
| 682 | 682 |
| 683 // Generate inline type check, linking to runtime call if not assignable. | 683 // Generate inline type check, linking to runtime call if not assignable. |
| 684 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 684 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
| 685 test_cache = GenerateInlineInstanceof(token_pos, dst_type, | 685 test_cache = GenerateInlineInstanceof(token_pos, dst_type, |
| 686 &is_assignable, &runtime_call); | 686 &is_assignable, &runtime_call); |
| 687 | 687 |
| 688 __ Bind(&runtime_call); | 688 __ Bind(&runtime_call); |
| 689 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. | 689 __ movq(RDX, Address(RSP, 0)); // Get instantiator type arguments. |
| 690 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. | 690 __ movq(RCX, Address(RSP, kWordSize)); // Get instantiator. |
| 691 __ PushObject(Object::ZoneHandle(), PP); // Make room for the result. | 691 __ PushObject(Object::null_object(), PP); // Make room for the result. |
| 692 __ pushq(RAX); // Push the source object. | 692 __ pushq(RAX); // Push the source object. |
| 693 __ PushObject(dst_type, PP); // Push the type of the destination. | 693 __ PushObject(dst_type, PP); // Push the type of the destination. |
| 694 __ pushq(RCX); // Instantiator. | 694 __ pushq(RCX); // Instantiator. |
| 695 __ pushq(RDX); // Instantiator type arguments. | 695 __ pushq(RDX); // Instantiator type arguments. |
| 696 __ PushObject(dst_name, PP); // Push the name of the destination. | 696 __ PushObject(dst_name, PP); // Push the name of the destination. |
| 697 __ LoadObject(RAX, test_cache, PP); | 697 __ LoadObject(RAX, test_cache, PP); |
| 698 __ pushq(RAX); | 698 __ pushq(RAX); |
| 699 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); | 699 GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 700 // Pop the parameters supplied to the runtime entry. The result of the | 700 // Pop the parameters supplied to the runtime entry. The result of the |
| 701 // type check runtime call is the checked value. | 701 // type check runtime call is the checked value. |
| (...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 __ movups(reg, Address(RSP, 0)); | 1717 __ movups(reg, Address(RSP, 0)); |
| 1718 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); | 1718 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); |
| 1719 } | 1719 } |
| 1720 | 1720 |
| 1721 | 1721 |
| 1722 #undef __ | 1722 #undef __ |
| 1723 | 1723 |
| 1724 } // namespace dart | 1724 } // namespace dart |
| 1725 | 1725 |
| 1726 #endif // defined TARGET_ARCH_X64 | 1726 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |