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

Unified Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 10458031: In generated code for x64 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Eliminate CoreClass helpers on ia32/x64 and use class ids for array classes. 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler_x64.cc
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index ba2fc440c8c05102b6a981b28b2b22a7e8186945..e47557e3b36f1d8effc3562a205fcf2eeb491979 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -136,15 +136,6 @@ void FlowGraphCompiler::Bailout(const char* reason) {
}
-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;
-}
-
-
#define __ assembler_->
@@ -172,18 +163,18 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
if (is_raw_type) {
// Dynamic type argument, check only classes.
// List is a very common case.
- __ movq(R10, FieldAddress(RAX, Object::class_offset()));
+ __ LoadClassId(R10, RAX);
if (!type_class.is_interface()) {
- __ CompareObject(R10, type_class);
+ __ cmpl(R10, Immediate(type_class.index()));
__ j(EQUAL, is_instance_lbl);
}
if (type.IsListInterface()) {
Label unknown;
- GrowableArray<const Class*> args;
- args.Add(CoreClass("ObjectArray"));
- args.Add(CoreClass("GrowableObjectArray"));
- args.Add(CoreClass("ImmutableArray"));
- CheckClasses(args, is_instance_lbl, &unknown);
+ GrowableArray<intptr_t> args;
+ args.Add(kArray);
+ args.Add(kGrowableObjectArray);
+ args.Add(kImmutableArray);
+ CheckClassIds(args, is_instance_lbl, &unknown);
__ Bind(&unknown);
}
return GenerateSubtype1TestCacheLookup(
@@ -235,12 +226,12 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
}
-// R10: instance class to check.
-void FlowGraphCompiler::CheckClasses(const GrowableArray<const Class*>& classes,
+// R10: instance class id to check.
+void FlowGraphCompiler::CheckClassIds(const GrowableArray<intptr_t>& class_ids,
Label* is_instance_lbl,
Label* is_not_instance_lbl) {
- for (intptr_t i = 0; i < classes.length(); i++) {
- __ CompareObject(R10, *classes[i]);
+ for (intptr_t i = 0; i < class_ids.length(); i++) {
+ __ cmpl(R10, Immediate(class_ids[i]));
__ j(EQUAL, is_instance_lbl);
}
__ jmp(is_not_instance_lbl);
@@ -277,21 +268,19 @@ void FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
__ jmp(is_not_instance_lbl);
}
- ObjectStore* object_store = Isolate::Current()->object_store();
// Compare if the classes are equal. Instance is not Smi.
__ Bind(&compare_classes);
- __ movq(R10, FieldAddress(RAX, Object::class_offset()));
+ __ LoadClassId(R10, RAX);
// If type is an interface, we can skip the class equality check.
if (!type_class.is_interface()) {
- __ CompareObject(R10, type_class);
+ __ cmpl(R10, Immediate(type_class.index()));
__ j(EQUAL, is_instance_lbl);
}
// Check for interfaces that cannot be implemented by user.
// (see ClassFinalizer::ResolveInterfaces for list of restricted interfaces).
// Bool interface can be implemented only by core class Bool.
if (type.IsBoolInterface()) {
- const Class& bool_class = Class::ZoneHandle(object_store->bool_class());
- __ CompareObject(R10, bool_class);
+ __ cmpl(R10, Immediate(kBool));
__ j(EQUAL, is_instance_lbl);
__ jmp(is_not_instance_lbl);
return;
@@ -300,8 +289,9 @@ void FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
// Check if instance is a closure.
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ movq(R10, FieldAddress(R10, Class::signature_function_offset()));
- __ cmpq(R10, raw_null);
+ __ LoadClassById(R13, R10);
+ __ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
+ __ cmpq(R13, raw_null);
__ j(NOT_EQUAL, is_instance_lbl);
__ jmp(is_not_instance_lbl);
return;
@@ -310,44 +300,29 @@ void FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
// Note that instance is not Smi(checked above).
if (type.IsSubtypeOf(
Type::Handle(Type::NumberInterface()), &malformed_error)) {
- const Class& mint_class = Class::ZoneHandle(object_store->mint_class());
- const Class& bigint_class = Class::ZoneHandle(object_store->bigint_class());
- const Class& double_class = Class::ZoneHandle(object_store->double_class());
- GrowableArray<const Class*> args;
+ GrowableArray<intptr_t> args;
if (type.IsNumberInterface()) {
- args.Add(&double_class);
- args.Add(&mint_class);
- args.Add(&bigint_class);
+ args.Add(kDouble);
+ args.Add(kMint);
+ args.Add(kBigint);
} else if (type.IsIntInterface()) {
- args.Add(&mint_class);
- args.Add(&bigint_class);
+ args.Add(kMint);
+ args.Add(kBigint);
} else if (type.IsDoubleInterface()) {
- args.Add(&double_class);
+ args.Add(kDouble);
}
- CheckClasses(args, is_instance_lbl, is_not_instance_lbl);
+ CheckClassIds(args, is_instance_lbl, is_not_instance_lbl);
return;
}
if (type.IsStringInterface()) {
- const Class& one_byte_string_class =
- Class::ZoneHandle(object_store->one_byte_string_class());
- const Class& two_byte_string_class =
- Class::ZoneHandle(object_store->two_byte_string_class());
- const Class& four_byte_string_class =
- Class::ZoneHandle(object_store->four_byte_string_class());
- const Class& external_one_byte_string_class =
- Class::ZoneHandle(object_store->external_one_byte_string_class());
- const Class& external_two_byte_string_class =
- Class::ZoneHandle(object_store->external_two_byte_string_class());
- const Class& external_four_byte_string_class =
- Class::ZoneHandle(object_store->external_four_byte_string_class());
- GrowableArray<const Class*> args;
- args.Add(&one_byte_string_class);
- args.Add(&two_byte_string_class);
- args.Add(&four_byte_string_class);
- args.Add(&external_one_byte_string_class);
- args.Add(&external_two_byte_string_class);
- args.Add(&external_four_byte_string_class);
- CheckClasses(args, is_instance_lbl, is_not_instance_lbl);
+ GrowableArray<intptr_t> args;
+ args.Add(kOneByteString);
+ args.Add(kTwoByteString);
+ args.Add(kFourByteString);
+ args.Add(kExternalOneByteString);
+ args.Add(kExternalTwoByteString);
+ args.Add(kExternalFourByteString);
+ CheckClassIds(args, is_instance_lbl, is_not_instance_lbl);
return;
}
// Otherwise fallthrough.
@@ -368,7 +343,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
const Bool& bool_true = Bool::ZoneHandle(Bool::True());
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ movq(R10, FieldAddress(RAX, Object::class_offset()));
+ __ LoadClass(R10, RAX);
// Check immediate superclass equality.
__ movq(R13, FieldAddress(R10, Class::super_type_offset()));
__ movq(R13, FieldAddress(R13, Type::type_class_offset()));
@@ -417,8 +392,7 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
// Can handle only type arguments that are instances of TypeArguments.
// (runtime checks canonicalize type arguments).
Label fall_through;
- __ movq(R10, FieldAddress(RDX, Object::class_offset()));
- __ CompareObject(R10, Object::ZoneHandle(Object::type_arguments_class()));
+ __ CompareClassId(RDX, kTypeArguments);
__ j(NOT_EQUAL, &fall_through);
__ movq(RDI,
FieldAddress(RDX, TypeArguments::type_at_offset(type.Index())));
@@ -1016,8 +990,7 @@ void FlowGraphCompiler::VisitExtractConstructorTypeArguments(
// No need to check the instantiator (RAX) for null here, because a null
// instantiator will have the wrong class (Null instead of TypeArguments).
Label type_arguments_uninstantiated;
- __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
- __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
+ __ CompareClassId(RAX, kTypeArguments);
__ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
Immediate arguments_length =
Immediate(Smi::RawValue(comp->type_arguments().Length()));
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698