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

Unified Diff: runtime/vm/code_generator_ia32.cc

Issue 8503034: Add type check tracing (--trace_type_checks). Inline type checks with class types that have only ... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years, 1 month 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
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator_ia32.cc
===================================================================
--- runtime/vm/code_generator_ia32.cc (revision 1367)
+++ 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).
@@ -1534,10 +1539,33 @@
// checking whether the assigned instance is a Smi.
if (dst_type.IsInstantiated()) {
const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class());
- const bool dst_has_type_arguments = dst_type_class.HasTypeArguments();
+ const bool dst_class_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.
- if (!dst_has_type_arguments) {
+ // A class equality check is only applicable with a dst type of a
+ // non-parameterized class or with a raw dst type of a parameterized class.
+ if (dst_class_has_type_arguments) {
+ const TypeArguments& dst_type_arguments =
+ TypeArguments::Handle(dst_type.arguments());
+ const bool is_raw_dst_type = dst_type_arguments.IsNull() ||
+ dst_type_arguments.IsDynamicTypes(dst_type_arguments.Length());
+ if (is_raw_dst_type) {
+ // 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 +1587,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 +1595,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 +1603,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()));
« no previous file with comments | « runtime/vm/code_generator_ia32.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698