| 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 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 611 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 612 __ pushl(EAX); // Push the instance. | 612 __ pushl(EAX); // Push the instance. |
| 613 __ PushObject(type); // Push the type. | 613 __ PushObject(type); // Push the type. |
| 614 __ pushl(ECX); // Instantiator. | 614 __ pushl(ECX); // Instantiator. |
| 615 __ pushl(EDX); // Instantiator type arguments. | 615 __ pushl(EDX); // Instantiator type arguments. |
| 616 __ LoadObject(EAX, test_cache); | 616 __ LoadObject(EAX, test_cache); |
| 617 __ pushl(EAX); | 617 __ pushl(EAX); |
| 618 GenerateCallRuntime(token_pos, | 618 GenerateCallRuntime(token_pos, |
| 619 deopt_id, | 619 deopt_id, |
| 620 kInstanceofRuntimeEntry, | 620 kInstanceofRuntimeEntry, |
| 621 5, |
| 621 locs); | 622 locs); |
| 622 // Pop the parameters supplied to the runtime entry. The result of the | 623 // Pop the parameters supplied to the runtime entry. The result of the |
| 623 // instanceof runtime call will be left as the result of the operation. | 624 // instanceof runtime call will be left as the result of the operation. |
| 624 __ Drop(5); | 625 __ Drop(5); |
| 625 if (negate_result) { | 626 if (negate_result) { |
| 626 __ popl(EDX); | 627 __ popl(EDX); |
| 627 __ LoadObject(EAX, Bool::True()); | 628 __ LoadObject(EAX, Bool::True()); |
| 628 __ cmpl(EDX, EAX); | 629 __ cmpl(EDX, EAX); |
| 629 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 630 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 630 __ LoadObject(EAX, Bool::False()); | 631 __ LoadObject(EAX, Bool::False()); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 } | 699 } |
| 699 const String& error_message = String::ZoneHandle( | 700 const String& error_message = String::ZoneHandle( |
| 700 Symbols::New(error.ToErrorCString())); | 701 Symbols::New(error.ToErrorCString())); |
| 701 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 702 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 702 __ pushl(EAX); // Push the source object. | 703 __ pushl(EAX); // Push the source object. |
| 703 __ PushObject(dst_name); // Push the name of the destination. | 704 __ PushObject(dst_name); // Push the name of the destination. |
| 704 __ PushObject(error_message); | 705 __ PushObject(error_message); |
| 705 GenerateCallRuntime(token_pos, | 706 GenerateCallRuntime(token_pos, |
| 706 deopt_id, | 707 deopt_id, |
| 707 kMalformedTypeErrorRuntimeEntry, | 708 kMalformedTypeErrorRuntimeEntry, |
| 709 3, |
| 708 locs); | 710 locs); |
| 709 // We should never return here. | 711 // We should never return here. |
| 710 __ int3(); | 712 __ int3(); |
| 711 | 713 |
| 712 __ Bind(&is_assignable); // For a null object. | 714 __ Bind(&is_assignable); // For a null object. |
| 713 __ popl(EDX); // Remove pushed instantiator type arguments. | 715 __ popl(EDX); // Remove pushed instantiator type arguments. |
| 714 __ popl(ECX); // Remove pushed instantiator. | 716 __ popl(ECX); // Remove pushed instantiator. |
| 715 return; | 717 return; |
| 716 } | 718 } |
| 717 | 719 |
| 718 // Generate inline type check, linking to runtime call if not assignable. | 720 // Generate inline type check, linking to runtime call if not assignable. |
| 719 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); | 721 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); |
| 720 test_cache = GenerateInlineInstanceof(token_pos, dst_type, | 722 test_cache = GenerateInlineInstanceof(token_pos, dst_type, |
| 721 &is_assignable, &runtime_call); | 723 &is_assignable, &runtime_call); |
| 722 | 724 |
| 723 __ Bind(&runtime_call); | 725 __ Bind(&runtime_call); |
| 724 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. | 726 __ movl(EDX, Address(ESP, 0)); // Get instantiator type arguments. |
| 725 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. | 727 __ movl(ECX, Address(ESP, kWordSize)); // Get instantiator. |
| 726 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 728 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| 727 __ pushl(EAX); // Push the source object. | 729 __ pushl(EAX); // Push the source object. |
| 728 __ PushObject(dst_type); // Push the type of the destination. | 730 __ PushObject(dst_type); // Push the type of the destination. |
| 729 __ pushl(ECX); // Instantiator. | 731 __ pushl(ECX); // Instantiator. |
| 730 __ pushl(EDX); // Instantiator type arguments. | 732 __ pushl(EDX); // Instantiator type arguments. |
| 731 __ PushObject(dst_name); // Push the name of the destination. | 733 __ PushObject(dst_name); // Push the name of the destination. |
| 732 __ LoadObject(EAX, test_cache); | 734 __ LoadObject(EAX, test_cache); |
| 733 __ pushl(EAX); | 735 __ pushl(EAX); |
| 734 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, locs); | 736 GenerateCallRuntime(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
| 735 // Pop the parameters supplied to the runtime entry. The result of the | 737 // Pop the parameters supplied to the runtime entry. The result of the |
| 736 // type check runtime call is the checked value. | 738 // type check runtime call is the checked value. |
| 737 __ Drop(6); | 739 __ Drop(6); |
| 738 __ popl(EAX); | 740 __ popl(EAX); |
| 739 | 741 |
| 740 __ Bind(&is_assignable); | 742 __ Bind(&is_assignable); |
| 741 __ popl(EDX); // Remove pushed instantiator type arguments. | 743 __ popl(EDX); // Remove pushed instantiator type arguments. |
| 742 __ popl(ECX); // Remove pushed instantiator. | 744 __ popl(ECX); // Remove pushed instantiator. |
| 743 } | 745 } |
| 744 | 746 |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 // Add deoptimization continuation point after the call and before the | 1258 // Add deoptimization continuation point after the call and before the |
| 1257 // arguments are removed. | 1259 // arguments are removed. |
| 1258 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); | 1260 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos); |
| 1259 } | 1261 } |
| 1260 } | 1262 } |
| 1261 | 1263 |
| 1262 | 1264 |
| 1263 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, | 1265 void FlowGraphCompiler::GenerateCallRuntime(intptr_t token_pos, |
| 1264 intptr_t deopt_id, | 1266 intptr_t deopt_id, |
| 1265 const RuntimeEntry& entry, | 1267 const RuntimeEntry& entry, |
| 1268 intptr_t argument_count, |
| 1266 LocationSummary* locs) { | 1269 LocationSummary* locs) { |
| 1267 __ CallRuntime(entry); | 1270 __ CallRuntime(entry, argument_count); |
| 1268 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); | 1271 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos); |
| 1269 RecordSafepoint(locs); | 1272 RecordSafepoint(locs); |
| 1270 if (deopt_id != Isolate::kNoDeoptId) { | 1273 if (deopt_id != Isolate::kNoDeoptId) { |
| 1271 // Marks either the continuation point in unoptimized code or the | 1274 // Marks either the continuation point in unoptimized code or the |
| 1272 // deoptimization point in optimized code, after call. | 1275 // deoptimization point in optimized code, after call. |
| 1273 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); | 1276 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); |
| 1274 if (is_optimizing()) { | 1277 if (is_optimizing()) { |
| 1275 AddDeoptIndexAtCall(deopt_id_after, token_pos); | 1278 AddDeoptIndexAtCall(deopt_id_after, token_pos); |
| 1276 } else { | 1279 } else { |
| 1277 // Add deoptimization continuation point after the call and before the | 1280 // Add deoptimization continuation point after the call and before the |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 __ movups(reg, Address(ESP, 0)); | 1912 __ movups(reg, Address(ESP, 0)); |
| 1910 __ addl(ESP, Immediate(kFpuRegisterSize)); | 1913 __ addl(ESP, Immediate(kFpuRegisterSize)); |
| 1911 } | 1914 } |
| 1912 | 1915 |
| 1913 | 1916 |
| 1914 #undef __ | 1917 #undef __ |
| 1915 | 1918 |
| 1916 } // namespace dart | 1919 } // namespace dart |
| 1917 | 1920 |
| 1918 #endif // defined TARGET_ARCH_IA32 | 1921 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |