| 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 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); | 534 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 535 } | 535 } |
| 536 // If one type argument only, check if type argument is Object or Dynamic. | 536 // If one type argument only, check if type argument is Object or Dynamic. |
| 537 if (type_arguments.Length() == 1) { | 537 if (type_arguments.Length() == 1) { |
| 538 const AbstractType& tp_argument = AbstractType::ZoneHandle( | 538 const AbstractType& tp_argument = AbstractType::ZoneHandle( |
| 539 type_arguments.TypeAt(0)); | 539 type_arguments.TypeAt(0)); |
| 540 ASSERT(!tp_argument.IsMalformed()); | 540 ASSERT(!tp_argument.IsMalformed()); |
| 541 if (tp_argument.IsType()) { | 541 if (tp_argument.IsType()) { |
| 542 ASSERT(tp_argument.HasResolvedTypeClass()); | 542 ASSERT(tp_argument.HasResolvedTypeClass()); |
| 543 // Check if type argument is dynamic or Object. | 543 // Check if type argument is dynamic or Object. |
| 544 const Type& object_type = | 544 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 545 Type::Handle(Isolate::Current()->object_store()->object_type()); | |
| 546 Error& malformed_error = Error::Handle(); | 545 Error& malformed_error = Error::Handle(); |
| 547 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) { | 546 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) { |
| 548 // Instance class test only necessary. | 547 // Instance class test only necessary. |
| 549 return GenerateSubtype1TestCacheLookup( | 548 return GenerateSubtype1TestCacheLookup( |
| 550 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); | 549 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 551 } | 550 } |
| 552 } | 551 } |
| 553 } | 552 } |
| 554 // Regular subtype test cache involving instance's type arguments. | 553 // Regular subtype test cache involving instance's type arguments. |
| 555 const Register kTypeArgumentsReg = kNoRegister; | 554 const Register kTypeArgumentsReg = kNoRegister; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); | 672 __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
| 674 | 673 |
| 675 __ movl(EDI, | 674 __ movl(EDI, |
| 676 FieldAddress(EDX, TypeArguments::type_at_offset(type.Index()))); | 675 FieldAddress(EDX, TypeArguments::type_at_offset(type.Index()))); |
| 677 // EDI: concrete type of type. | 676 // EDI: concrete type of type. |
| 678 // Check if type argument is dynamic. | 677 // Check if type argument is dynamic. |
| 679 __ CompareObject(EDI, Type::ZoneHandle(Type::DynamicType())); | 678 __ CompareObject(EDI, Type::ZoneHandle(Type::DynamicType())); |
| 680 __ j(EQUAL, is_instance_lbl); | 679 __ j(EQUAL, is_instance_lbl); |
| 681 __ cmpl(EDI, raw_null); | 680 __ cmpl(EDI, raw_null); |
| 682 __ j(EQUAL, is_instance_lbl); | 681 __ j(EQUAL, is_instance_lbl); |
| 683 const Type& object_type = | 682 const Type& object_type = Type::ZoneHandle(Type::ObjectType()); |
| 684 Type::ZoneHandle(Isolate::Current()->object_store()->object_type()); | |
| 685 __ CompareObject(EDI, object_type); | 683 __ CompareObject(EDI, object_type); |
| 686 __ j(EQUAL, is_instance_lbl); | 684 __ j(EQUAL, is_instance_lbl); |
| 687 | 685 |
| 688 // For Smi check quickly against int and num interfaces. | 686 // For Smi check quickly against int and num interfaces. |
| 689 Label not_smi; | 687 Label not_smi; |
| 690 __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi? | 688 __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi? |
| 691 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 689 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
| 692 __ CompareObject(EDI, Type::ZoneHandle(Type::IntInterface())); | 690 __ CompareObject(EDI, Type::ZoneHandle(Type::IntInterface())); |
| 693 __ j(EQUAL, is_instance_lbl); | 691 __ j(EQUAL, is_instance_lbl); |
| 694 __ CompareObject(EDI, Type::ZoneHandle(Type::NumberInterface())); | 692 __ CompareObject(EDI, Type::ZoneHandle(Type::NumberInterface())); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 906 // - ECX: instantiator or raw_null. | 904 // - ECX: instantiator or raw_null. |
| 907 // Returns: | 905 // Returns: |
| 908 // - object in EAX for successful assignable check (or throws TypeError). | 906 // - object in EAX for successful assignable check (or throws TypeError). |
| 909 // Performance notes: positive checks must be quick, negative checks can be slow | 907 // Performance notes: positive checks must be quick, negative checks can be slow |
| 910 // as they throw an exception. | 908 // as they throw an exception. |
| 911 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t cid, | 909 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t cid, |
| 912 intptr_t token_pos, | 910 intptr_t token_pos, |
| 913 intptr_t try_index, | 911 intptr_t try_index, |
| 914 const AbstractType& dst_type, | 912 const AbstractType& dst_type, |
| 915 const String& dst_name) { | 913 const String& dst_name) { |
| 916 ASSERT(FLAG_enable_type_checks); | |
| 917 ASSERT(token_pos >= 0); | 914 ASSERT(token_pos >= 0); |
| 918 ASSERT(!dst_type.IsNull()); | 915 ASSERT(!dst_type.IsNull()); |
| 919 ASSERT(dst_type.IsFinalized()); | 916 ASSERT(dst_type.IsFinalized()); |
| 920 // Assignable check is skipped in FlowGraphBuilder, not here. | 917 // Assignable check is skipped in FlowGraphBuilder, not here. |
| 921 ASSERT(dst_type.IsMalformed() || | 918 ASSERT(dst_type.IsMalformed() || |
| 922 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); | 919 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); |
| 923 ASSERT(!dst_type.IsVoidType()); | 920 ASSERT(!dst_type.IsVoidType()); |
| 924 __ pushl(ECX); // Store instantiator. | 921 __ pushl(ECX); // Store instantiator. |
| 925 __ pushl(EDX); // Store instantiator type arguments. | 922 __ pushl(EDX); // Store instantiator type arguments. |
| 926 // A null object is always assignable and is returned as result. | 923 // A null object is always assignable and is returned as result. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 __ cvtsi2sd(result, temp); | 1043 __ cvtsi2sd(result, temp); |
| 1047 __ Bind(&done); | 1044 __ Bind(&done); |
| 1048 } | 1045 } |
| 1049 | 1046 |
| 1050 | 1047 |
| 1051 #undef __ | 1048 #undef __ |
| 1052 | 1049 |
| 1053 } // namespace dart | 1050 } // namespace dart |
| 1054 | 1051 |
| 1055 #endif // defined TARGET_ARCH_IA32 | 1052 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |