Chromium Code Reviews| Index: runtime/vm/code_generator_ia32.cc |
| =================================================================== |
| --- runtime/vm/code_generator_ia32.cc (revision 1334) |
| +++ runtime/vm/code_generator_ia32.cc (working copy) |
| @@ -1480,16 +1480,21 @@ |
| // Jumps to label if ECX equals the given class. |
| // Inputs: |
| // - ECX: tested class. |
| -// Destroys EDX. |
| -static void TestClassAndJump(Assembler* assembler, |
| - const Class& cls, |
| - Label *label) { |
| - assembler->LoadObject(EDX, cls); |
| - assembler->cmpl(EDX, ECX); |
| - assembler->j(EQUAL, label, Assembler::kNearJump); |
| +void CodeGenerator::TestClassAndJump(const Class& cls, Label *label) { |
| + __ CompareObject(ECX, cls); |
| + __ j(EQUAL, label, Assembler::kNearJump); |
| } |
| +static const Class* CoreClass(const char* c_name) { |
| + const String& class_name = String::Handle(String::NewSymbol(c_name)); |
| + const Class& cls = Class::ZoneHandle(Library::Handle( |
| + Library::CoreImplLibrary()).LookupClass(class_name)); |
| + ASSERT(!cls.IsNull()); |
| + return &cls; |
| +} |
| + |
| + |
| // Optimize assignable type check by adding inlined tests for: |
| // - NULL -> return NULL. |
| // - Smi -> compile time subtype check (only if dst class is not parameterized). |
| @@ -1537,7 +1542,29 @@ |
| const bool dst_has_type_arguments = dst_type_class.HasTypeArguments(); |
| // A Smi object cannot be the instance of a parameterized class. |
| // A class equality check is only applicable to a non-parameterized class. |
|
regis
2011/11/09 01:47:53
// A class equality check is only applicable with
srdjan
2011/11/09 19:36:30
Done.
|
| - if (!dst_has_type_arguments) { |
| + if (dst_has_type_arguments) { |
|
regis
2011/11/09 01:47:53
dst_class_has_type_arguments
srdjan
2011/11/09 19:36:30
Done.
|
| + const TypeArguments& arguments = |
|
regis
2011/11/09 01:47:53
arguments -> dst_type_arguments.
srdjan
2011/11/09 19:36:30
Done.
|
| + TypeArguments::Handle(dst_type.arguments()); |
| + bool no_type_arguments = arguments.IsNull() || |
|
regis
2011/11/09 01:47:53
Why the local? Make it const if you want to keep i
srdjan
2011/11/09 19:36:30
Made it a const. Giving it a name makes clear what
|
| + arguments.IsDynamicTypes(arguments.Length()); |
| + if (no_type_arguments) { |
| + // Dynamic type argument, check only classes. |
| + if (dst_type.IsListInterface()) { |
| + // TODO(srdjan) also accept List<Object>. |
| + __ testl(EAX, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &runtime_call, Assembler::kNearJump); |
| + __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| + TestClassAndJump(*CoreClass("ObjectArray"), &done); |
| + TestClassAndJump(*CoreClass("GrowableObjectArray"), &done); |
| + } else if (!dst_type_class.is_interface()) { |
| + __ testl(EAX, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &runtime_call, Assembler::kNearJump); |
| + __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| + TestClassAndJump(dst_type_class, &done); |
| + } |
| + // Fall through to runtime class. |
| + } |
| + } else { |
| Label compare_classes; |
| __ testl(EAX, Immediate(kSmiTagMask)); |
| __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); |
| @@ -1559,7 +1586,7 @@ |
| // because instances cannot be of an interface type. |
| if (!dst_type_class.is_interface()) { |
| __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| - TestClassAndJump(assembler_, dst_type_class, &done); |
| + TestClassAndJump(dst_type_class, &done); |
| } else { |
| // However, for specific core library interfaces, we can check for |
| // specific core library classes. |
| @@ -1567,7 +1594,7 @@ |
| __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| const Class& bool_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->bool_class()); |
| - TestClassAndJump(assembler_, bool_class, &done); |
| + TestClassAndJump(bool_class, &done); |
| } else if (dst_type.IsSubtypeOf( |
| Type::Handle(Type::NumberInterface()))) { |
| __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| @@ -1575,27 +1602,27 @@ |
| // We already checked for Smi above. |
| const Class& mint_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->mint_class()); |
| - TestClassAndJump(assembler_, mint_class, &done); |
| + TestClassAndJump(mint_class, &done); |
| const Class& bigint_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->bigint_class()); |
| - TestClassAndJump(assembler_, bigint_class, &done); |
| + TestClassAndJump(bigint_class, &done); |
| } |
| if (dst_type.IsDoubleInterface() || dst_type.IsNumberInterface()) { |
| const Class& double_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->double_class()); |
| - TestClassAndJump(assembler_, double_class, &done); |
| + TestClassAndJump(double_class, &done); |
| } |
| } else if (dst_type.IsStringInterface()) { |
| __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| const Class& one_byte_string_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->one_byte_string_class()); |
| - TestClassAndJump(assembler_, one_byte_string_class, &done); |
| + TestClassAndJump(one_byte_string_class, &done); |
| const Class& two_byte_string_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->two_byte_string_class()); |
| - TestClassAndJump(assembler_, two_byte_string_class, &done); |
| + TestClassAndJump(two_byte_string_class, &done); |
| const Class& four_byte_string_class = Class::ZoneHandle( |
| Isolate::Current()->object_store()->four_byte_string_class()); |
| - TestClassAndJump(assembler_, four_byte_string_class, &done); |
| + TestClassAndJump(four_byte_string_class, &done); |
| } else if (dst_type.IsFunctionInterface()) { |
| __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| __ movl(ECX, FieldAddress(ECX, Class::signature_function_offset())); |