Chromium Code Reviews| Index: runtime/vm/code_generator_ia32.cc |
| =================================================================== |
| --- runtime/vm/code_generator_ia32.cc (revision 5920) |
| +++ runtime/vm/code_generator_ia32.cc (working copy) |
| @@ -1468,7 +1468,7 @@ |
| Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| Label done, runtime_call; |
| __ cmpl(EAX, raw_null); |
| - __ j(EQUAL, &done, Assembler::kNearJump); |
| + __ j(EQUAL, &done); |
| // Generate throw new TypeError() if the type is malformed. |
| if (dst_type.IsMalformed()) { |
| @@ -1543,21 +1543,16 @@ |
| // If dst_type is an interface, we can skip the class equality check, |
| // because instances cannot be of an interface type. |
| if (!dst_type_class.is_interface()) { |
| - // Check if classes are equal. |
| - __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| - TestClassAndJump(dst_type_class, &done); // Uses ECX. |
| - // Check superclasses using a loop (faster than runtime call). |
| - Label loop_done, loop; |
| - __ Bind(&loop); |
| - // ECX: class. |
| - __ movl(ECX, FieldAddress(ECX, Class::super_type_offset())); |
| - // The supertype of Object is a null object. |
| - __ cmpl(ECX, raw_null); |
| - __ j(EQUAL, &loop_done, Assembler::kNearJump); |
| - __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); |
| - TestClassAndJump(dst_type_class, &done); // Uses ECX. |
| - __ jmp(&loop); |
| - __ Bind(&loop_done); |
| + __ LoadObject(EDX, dst_type_class); |
| + __ cmpl(EDX, ECX); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + __ pushl(EAX); |
| + __ call(&StubCode::IsSubTypeLabel()); |
| + __ movl(EDI, EAX); |
| + __ popl(EAX); |
| + __ cmpl(EDI, Immediate(1)); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + // Otherwise fallthrough |
| } else { |
| // However, for specific core library interfaces, we can check for |
| // specific core library classes. |
| @@ -1601,30 +1596,16 @@ |
| __ cmpl(ECX, raw_null); |
| __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| } else { |
| - // Check interfaces. |
| - Label fall_through; |
| - // Get interfaces array from class. |
| - __ movl(EBX, FieldAddress(EAX, Object::class_offset())); |
| - __ movl(EBX, FieldAddress(EBX, Class::interfaces_offset())); |
| - __ cmpl(EBX, raw_null); |
| - __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| - // Iterate over interfaces array and check if any of interfaces match. |
| - __ movl(EDI, FieldAddress(EBX, Array::length_offset())); |
| - // EDI: array index |
| - // EBX: array |
| - Label loop; |
| - __ Bind(&loop); |
| - __ subl(EDI, Immediate(Smi::RawValue(1))); |
| - __ cmpl(EDI, Immediate(0)); |
| - __ j(LESS, &runtime_call, Assembler::kNearJump); |
| - // EDI is Smi therefore TIMES_2 instead of TIMES_4. |
| - // Get type from array. |
| - __ movl(ECX, FieldAddress(EBX, EDI, TIMES_2, Array::data_offset())); |
| - __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); |
| - TestClassAndJump(dst_type_class, &done); // Uses ECX. |
| - __ jmp(&loop, Assembler::kNearJump); |
| - // Fall through to runtime code. |
| - __ Bind(&fall_through); |
| + __ LoadObject(EDX, dst_type_class); |
| + // EAX: Instance (preserve). |
| + // EDX: test class |
| + __ pushl(EAX); |
| + __ call(&StubCode::IsSubTypeLabel()); |
| + __ movl(EDI, EAX); |
| + __ popl(EAX); |
| + __ cmpl(EDI, Immediate(1)); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + // Otherwise fallthrough |
| } |
| } |
| } |
| @@ -1645,10 +1626,35 @@ |
| __ movl(EDX, FieldAddress(EBX, Object::class_offset())); |
| __ CompareObject(EDX, Object::ZoneHandle(Object::type_arguments_class())); |
| __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
| + // EBX: Instance of TypeArguments. |
| __ movl(EDX, |
| FieldAddress(EBX, TypeArguments::type_at_offset(dst_type.Index()))); |
| + // EDX: concrete type of dst_type. |
| __ CompareObject(EDX, Type::ZoneHandle(Type::DynamicType())); |
| __ j(EQUAL, &done, Assembler::kNearJump); |
| + // Check if the type has type parameters, if not do the class comparison. |
| + Label not_smi; |
| + __ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi? |
| + __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
| + __ CompareObject(EDX, Type::ZoneHandle(Type::IntInterface())); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + __ CompareObject(EDX, Type::ZoneHandle(Type::NumberInterface())); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + __ Bind(¬_smi); |
| + __ movl(EDX, FieldAddress(EDX, Type::type_class_offset())); |
| + __ movl(ECX, FieldAddress(EDX, Class::type_parameters_offset())); |
| + // Check that class of dst_type has no type parameters. |
| + __ cmpl(ECX, raw_null); |
| + __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
| + // We have a non-parameterized class in EDX, compare with class of |
| + // value in EAX. |
| + __ pushl(EAX); |
| + __ call(&StubCode::IsSubTypeLabel()); |
| + __ movl(EDI, EAX); |
| + __ popl(EAX); |
| + __ cmpl(EDI, Immediate(1)); |
| + __ j(EQUAL, &done, Assembler::kNearJump); |
| + // Check superclasses. |
|
regis
2012/03/28 02:22:45
Is this comment left over?
srdjan
2012/03/28 15:42:15
Removed.
|
| __ Bind(&fall_through); |
| } |
| } |