Chromium Code Reviews| Index: runtime/vm/intrinsifier_ia32.cc |
| =================================================================== |
| --- runtime/vm/intrinsifier_ia32.cc (revision 5847) |
| +++ runtime/vm/intrinsifier_ia32.cc (working copy) |
| @@ -214,13 +214,58 @@ |
| } |
| +static intptr_t ComputeObjectArrayTypeArgumentsOffset() { |
| + const String& class_name = String::Handle(String::NewSymbol("ObjectArray")); |
| + const Class& cls = Class::Handle( |
| + Library::Handle(Library::CoreImplLibrary()).LookupClass(class_name)); |
| + ASSERT(!cls.IsNull()); |
| + ASSERT(cls.HasTypeArguments()); |
| + ASSERT(cls.NumTypeParameters() == 1); |
|
regis
2012/03/26 22:30:29
You actually want to make sure that the full type
srdjan
2012/03/26 22:43:51
Done.
|
| + intptr_t field_offset = cls.type_arguments_instance_field_offset(); |
| + ASSERT(field_offset != Class::kNoTypeArguments); |
| + return field_offset; |
| +} |
| + |
| + |
| // Intrinsify only for Smi value and index. Non-smi values need a store buffer |
| // update. Array length is always a Smi. |
| static bool Array_setIndexed(Assembler* assembler) { |
| + Label fall_through; |
| if (FLAG_enable_type_checks) { |
| - return false; |
| + intptr_t type_args_field_offset = ComputeObjectArrayTypeArgumentsOffset(); |
| + ASSERT(type_args_field_offset >= 0); |
| + // Inline simple tests (Smi, null), fallthrough if not positive. |
| + const Immediate raw_null = |
| + Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| + Label checked_ok; |
| + __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
|
regis
2012/03/26 22:30:29
I guess you are accessing the last argument, i.e.
srdjan
2012/03/26 22:43:51
Done.
|
| + __ cmpl(EAX, raw_null); |
| + __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| + __ testl(EAX, Immediate(kSmiTagMask)); |
| + __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi value. |
| + |
| + // Check if generic type is OK. |
| + __ movl(EBX, Address(ESP, + 3 * kWordSize)); // Array. |
| + __ movl(EBX, FieldAddress(EBX, type_args_field_offset)); |
| + // EBX: Type arguments of array. |
| + __ movl(EAX, FieldAddress(EBX, Object::class_offset())); |
| + // Check if it's Dynamic, int, or num. |
| + __ cmpl(EAX, raw_null); // Dynamic? |
| + __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| + // For now handle only TypeArguments and bail out if InstantiatedTypeArgs. |
| + __ CompareObject(EAX, Object::ZoneHandle(Object::type_arguments_class())); |
| + __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
| + // Get type at index 0. |
| + __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0))); |
| + __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType())); |
| + __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| + __ CompareObject(EAX, Type::ZoneHandle(Type::IntInterface())); |
| + __ j(EQUAL, &checked_ok, Assembler::kNearJump); |
| + __ CompareObject(EAX, Type::ZoneHandle(Type::NumberInterface())); |
| + __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump); |
| + // TODO(srdjan): Check classes. |
|
regis
2012/03/26 22:30:29
What do you mean by "Check classes"?
srdjan
2012/03/26 22:43:51
Removed.
|
| + __ Bind(&checked_ok); |
| } |
| - Label fall_through; |
| __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
| __ testl(EBX, Immediate(kSmiTagMask)); |
| // Index not Smi. |