| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 | 401 |
| 402 // Fall through if bool_register contains null. | 402 // Fall through if bool_register contains null. |
| 403 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, | 403 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, |
| 404 Label* is_true, | 404 Label* is_true, |
| 405 Label* is_false) { | 405 Label* is_false) { |
| 406 const Immediate raw_null = | 406 const Immediate raw_null = |
| 407 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 407 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 408 Label fall_through; | 408 Label fall_through; |
| 409 __ cmpl(bool_register, raw_null); | 409 __ cmpl(bool_register, raw_null); |
| 410 __ j(EQUAL, &fall_through, Assembler::kNearJump); | 410 __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| 411 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 411 __ CompareObject(bool_register, bool_true()); |
| 412 __ CompareObject(bool_register, bool_true); | |
| 413 __ j(EQUAL, is_true); | 412 __ j(EQUAL, is_true); |
| 414 __ jmp(is_false); | 413 __ jmp(is_false); |
| 415 __ Bind(&fall_through); | 414 __ Bind(&fall_through); |
| 416 } | 415 } |
| 417 | 416 |
| 418 | 417 |
| 419 // Clobbers ECX. | 418 // Clobbers ECX. |
| 420 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( | 419 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( |
| 421 TypeTestStubKind test_kind, | 420 TypeTestStubKind test_kind, |
| 422 Register instance_reg, | 421 Register instance_reg, |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 // - EDX: instantiator type arguments or raw_null. | 782 // - EDX: instantiator type arguments or raw_null. |
| 784 // - ECX: instantiator or raw_null. | 783 // - ECX: instantiator or raw_null. |
| 785 // Returns: | 784 // Returns: |
| 786 // - true or false in EAX. | 785 // - true or false in EAX. |
| 787 void FlowGraphCompiler::GenerateInstanceOf(intptr_t cid, | 786 void FlowGraphCompiler::GenerateInstanceOf(intptr_t cid, |
| 788 intptr_t token_index, | 787 intptr_t token_index, |
| 789 intptr_t try_index, | 788 intptr_t try_index, |
| 790 const AbstractType& type, | 789 const AbstractType& type, |
| 791 bool negate_result) { | 790 bool negate_result) { |
| 792 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 791 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 793 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 794 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 795 | 792 |
| 796 const Immediate raw_null = | 793 const Immediate raw_null = |
| 797 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 794 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 798 Label is_instance, is_not_instance; | 795 Label is_instance, is_not_instance; |
| 799 __ pushl(ECX); // Store instantiator on stack. | 796 __ pushl(ECX); // Store instantiator on stack. |
| 800 __ pushl(EDX); // Store instantiator type arguments. | 797 __ pushl(EDX); // Store instantiator type arguments. |
| 801 // If type is instantiated and non-parameterized, we can inline code | 798 // If type is instantiated and non-parameterized, we can inline code |
| 802 // checking whether the tested instance is a Smi. | 799 // checking whether the tested instance is a Smi. |
| 803 if (type.IsInstantiated()) { | 800 if (type.IsInstantiated()) { |
| 804 // A null object is only an instance of Object and Dynamic, which has | 801 // A null object is only an instance of Object and Dynamic, which has |
| (...skipping 24 matching lines...) Expand all Loading... |
| 829 __ pushl(EDX); // Instantiator type arguments. | 826 __ pushl(EDX); // Instantiator type arguments. |
| 830 __ LoadObject(EAX, test_cache); | 827 __ LoadObject(EAX, test_cache); |
| 831 __ pushl(EAX); | 828 __ pushl(EAX); |
| 832 GenerateCallRuntime(cid, token_index, try_index, kInstanceofRuntimeEntry); | 829 GenerateCallRuntime(cid, token_index, try_index, kInstanceofRuntimeEntry); |
| 833 // Pop the two parameters supplied to the runtime entry. The result of the | 830 // Pop the two parameters supplied to the runtime entry. The result of the |
| 834 // instanceof runtime call will be left as the result of the operation. | 831 // instanceof runtime call will be left as the result of the operation. |
| 835 __ Drop(7); | 832 __ Drop(7); |
| 836 Label done; | 833 Label done; |
| 837 if (negate_result) { | 834 if (negate_result) { |
| 838 __ popl(EDX); | 835 __ popl(EDX); |
| 839 __ LoadObject(EAX, bool_true); | 836 __ LoadObject(EAX, bool_true()); |
| 840 __ cmpl(EDX, EAX); | 837 __ cmpl(EDX, EAX); |
| 841 __ j(NOT_EQUAL, &done, Assembler::kNearJump); | 838 __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| 842 __ LoadObject(EAX, bool_false); | 839 __ LoadObject(EAX, bool_false()); |
| 843 } else { | 840 } else { |
| 844 __ popl(EAX); | 841 __ popl(EAX); |
| 845 } | 842 } |
| 846 __ jmp(&done, Assembler::kNearJump); | 843 __ jmp(&done, Assembler::kNearJump); |
| 847 | 844 |
| 848 __ Bind(&is_not_instance); | 845 __ Bind(&is_not_instance); |
| 849 __ LoadObject(EAX, negate_result ? bool_true : bool_false); | 846 __ LoadObject(EAX, negate_result ? bool_true() : bool_false()); |
| 850 __ jmp(&done, Assembler::kNearJump); | 847 __ jmp(&done, Assembler::kNearJump); |
| 851 | 848 |
| 852 __ Bind(&is_instance); | 849 __ Bind(&is_instance); |
| 853 __ LoadObject(EAX, negate_result ? bool_false : bool_true); | 850 __ LoadObject(EAX, negate_result ? bool_false() : bool_true()); |
| 854 __ Bind(&done); | 851 __ Bind(&done); |
| 855 __ popl(EDX); // Remove pushed instantiator type arguments. | 852 __ popl(EDX); // Remove pushed instantiator type arguments. |
| 856 __ popl(ECX); // Remove pushed instantiator. | 853 __ popl(ECX); // Remove pushed instantiator. |
| 857 } | 854 } |
| 858 | 855 |
| 859 | 856 |
| 860 // Optimize assignable type check by adding inlined tests for: | 857 // Optimize assignable type check by adding inlined tests for: |
| 861 // - NULL -> return NULL. | 858 // - NULL -> return NULL. |
| 862 // - Smi -> compile time subtype check (only if dst class is not parameterized). | 859 // - Smi -> compile time subtype check (only if dst class is not parameterized). |
| 863 // - Class equality (only if class is not parameterized). | 860 // - Class equality (only if class is not parameterized). |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 __ cvtsi2sd(result, temp); | 1006 __ cvtsi2sd(result, temp); |
| 1010 __ Bind(&done); | 1007 __ Bind(&done); |
| 1011 } | 1008 } |
| 1012 | 1009 |
| 1013 | 1010 |
| 1014 #undef __ | 1011 #undef __ |
| 1015 | 1012 |
| 1016 } // namespace dart | 1013 } // namespace dart |
| 1017 | 1014 |
| 1018 #endif // defined TARGET_ARCH_IA32 | 1015 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |