Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Unified Diff: runtime/vm/code_generator_ia32.cc

Issue 10381045: Improve type checking, remove unused stub (removed also in x64 in preparation of porting the better… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/code_generator_ia32.cc
===================================================================
--- runtime/vm/code_generator_ia32.cc (revision 7391)
+++ runtime/vm/code_generator_ia32.cc (working copy)
@@ -1445,29 +1445,26 @@
GenerateSubtype1TestCacheLookup(node_id, token_index, type_class,
is_instance_lbl, is_not_instance_lbl);
}
- // Note that the test below must be synced with the tests in
- // CodeGenerator::UpdateTestCache.
- // Inline checks for one type argument only.
- if (type_arguments.Length() != 1) {
- return SubtypeTestCache::null();
+ // If one type argument only, quick check.
+ if (type_arguments.Length() == 1) {
+ const AbstractType& tp_argument = AbstractType::ZoneHandle(
+ type_arguments.TypeAt(0));
+ // Malformed type has been caught in the caller chain of this function.
+ ASSERT(tp_argument.HasResolvedTypeClass());
+ // Check if type argument is dynamic or Object.
+ const Type& object_type =
+ Type::Handle(Isolate::Current()->object_store()->object_type());
+ Error& malformed_error = Error::Handle();
+ if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) {
+ // Instance class test only necessary.
+ return GenerateSubtype1TestCacheLookup(
+ node_id,
+ token_index,
+ type_class,
+ is_instance_lbl,
+ is_not_instance_lbl);
+ }
}
- const AbstractType& tp_argument =
- AbstractType::ZoneHandle(type_arguments.TypeAt(0));
- if (!tp_argument.IsType()) {
- // E.g., it is a TypeParameter.
- return SubtypeTestCache::null();
- }
- // Malformed type has been caught in the caller chain of this function.
- ASSERT(tp_argument.HasResolvedTypeClass());
- // Check if type argument is dynamic or Object.
- const Type& object_type =
- Type::Handle(Isolate::Current()->object_store()->object_type());
- Error& malformed_error = Error::Handle();
- if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) {
- // Instance class test only necessary.
- return GenerateSubtype1TestCacheLookup(
- node_id, token_index, type_class, is_instance_lbl, is_not_instance_lbl);
- }
const SubtypeTestCache& type_test_cache =
SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
Label inlined_check, fall_through;
@@ -1613,24 +1610,27 @@
__ cmpl(EBX, raw_null);
__ j(EQUAL, is_instance_lbl);
+ // EBX: instantiator type arguments.
// For now handle only TypeArguments and bail out if InstantiatedTypeArgs.
+ // We expect that frequently checked objects wull have their type arguments
+ // converted into instance of TypeArguments.
__ 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(type.Index())));
// EDX: concrete type of type.
// Check if type argument is dynamic.
__ CompareObject(EDX, Type::ZoneHandle(Type::DynamicType()));
__ j(EQUAL, is_instance_lbl);
+ __ cmpl(EDX, raw_null);
+ __ j(EQUAL, is_instance_lbl);
- // Check if the type has type parameters, if not do the class comparison.
+ // For Smi check quickly against int and num interfaces.
Label not_smi;
__ testl(EAX, Immediate(kSmiTagMask)); // Value is Smi?
__ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
- // For Smi check quickly against int and num interfaces.
__ CompareObject(EDX, Type::ZoneHandle(Type::IntInterface()));
__ j(EQUAL, is_instance_lbl);
__ CompareObject(EDX, Type::ZoneHandle(Type::NumberInterface()));
@@ -1638,35 +1638,29 @@
__ jmp(&fall_through);
__ Bind(&not_smi);
+ // EBX: instantiator type arguments.
+ // EAX: instance
// The instantiated type parameter may not be a Type, but could be an
// InstantiatedType. It is therefore necessary to check its class.
- __ movl(ECX, FieldAddress(EDX, Object::class_offset()));
- __ CompareObject(ECX, Object::ZoneHandle(Object::type_class()));
- __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
-
- __ movl(EDX, FieldAddress(EDX, Type::type_class_offset()));
- __ movl(ECX, FieldAddress(EDX, Class::type_parameters_offset()));
- // Check that class of type has no type parameters.
+ const SubtypeTestCache& type_test_cache =
+ SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
+ __ LoadObject(ECX, type_test_cache);
+ __ pushl(ECX); // Subtype test cache.
+ __ pushl(EAX); // Instance.
+ __ pushl(EBX); // Instantator type arguments.
+ __ call(&StubCode::Subtype3TestCacheLabel());
+ __ popl(EDX); // Discard type arguments.
+ __ popl(EAX); // Restore receiver.
+ __ popl(EDX); // Discard subtype test cache.
+ // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
__ cmpl(ECX, raw_null);
- __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
- // EAX has non-parameterized class.
- // Check class equality
- __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
- __ movl(ECX, FieldAddress(ECX, Type::type_class_offset()));
- __ cmpl(ECX, EDX);
+ __ j(EQUAL, &fall_through, Assembler::kNearJump);
+ const Bool& bool_true = Bool::ZoneHandle(Bool::True());
+ __ CompareObject(ECX, bool_true);
__ j(EQUAL, is_instance_lbl);
-
- // We have a non-parameterized class in EDX, compare with class of
- // value in EAX. EAX, EDX are preserved in stub.
- __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
- __ call(&StubCode::IsRawSubTypeLabel());
- // Result in EBX: 1 is raw subtype.
- __ cmpl(EBX, Immediate(1));
- __ j(EQUAL, is_instance_lbl);
-
- // Test not conclusive.
+ __ jmp(is_not_instance_lbl);
__ Bind(&fall_through);
- return SubtypeTestCache::null();
+ return type_test_cache.raw();
}
if (type.IsType()) {
Label fall_through;

Powered by Google App Engine
This is Rietveld 408576698