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

Unified Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 18807007: Fix wrong type test optimization when testing against a signature class: we must always consider th… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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_mips.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_compiler_x64.cc
===================================================================
--- runtime/vm/flow_graph_compiler_x64.cc (revision 24952)
+++ runtime/vm/flow_graph_compiler_x64.cc (working copy)
@@ -227,12 +227,12 @@
__ Comment("InstantiatedTypeWithArgumentsTest");
ASSERT(type.IsInstantiated());
const Class& type_class = Class::ZoneHandle(type.type_class());
- ASSERT(type_class.HasTypeArguments());
+ ASSERT(type_class.HasTypeArguments() || type_class.IsSignatureClass());
const Register kInstanceReg = RAX;
Error& malformed_error = Error::Handle();
const Type& int_type = Type::Handle(Type::IntType());
const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error);
- // Malforrmed type should have been handled at graph construction time.
+ // Malformed type should have been handled at graph construction time.
ASSERT(smi_is_ok || malformed_error.IsNull());
__ testq(kInstanceReg, Immediate(kSmiTagMask));
if (smi_is_ok) {
@@ -244,32 +244,35 @@
AbstractTypeArguments::ZoneHandle(type.arguments());
const bool is_raw_type = type_arguments.IsNull() ||
type_arguments.IsRaw(type_arguments.Length());
- if (is_raw_type) {
- const Register kClassIdReg = R10;
- // dynamic type argument, check only classes.
- __ LoadClassId(kClassIdReg, kInstanceReg);
- __ cmpl(kClassIdReg, Immediate(type_class.id()));
- __ j(EQUAL, is_instance_lbl);
- // List is a very common case.
- if (IsListClass(type_class)) {
- GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
+ // Signature class is an instantiated parameterized type.
+ if (!type_class.IsSignatureClass()) {
+ if (is_raw_type) {
+ const Register kClassIdReg = R10;
+ // dynamic type argument, check only classes.
+ __ LoadClassId(kClassIdReg, kInstanceReg);
+ __ cmpl(kClassIdReg, Immediate(type_class.id()));
+ __ j(EQUAL, is_instance_lbl);
+ // List is a very common case.
+ if (IsListClass(type_class)) {
+ GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
+ }
+ return GenerateSubtype1TestCacheLookup(
+ token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
}
- return GenerateSubtype1TestCacheLookup(
- token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
- }
- // If one type argument only, check if type argument is Object or dynamic.
- if (type_arguments.Length() == 1) {
- const AbstractType& tp_argument = AbstractType::ZoneHandle(
- type_arguments.TypeAt(0));
- ASSERT(!tp_argument.IsMalformed());
- if (tp_argument.IsType()) {
- ASSERT(tp_argument.HasResolvedTypeClass());
- // Check if type argument is dynamic or Object.
- const Type& object_type = Type::Handle(Type::ObjectType());
- if (object_type.IsSubtypeOf(tp_argument, NULL)) {
- // Instance class test only necessary.
- return GenerateSubtype1TestCacheLookup(
- token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+ // If one type argument only, check if type argument is Object or dynamic.
+ if (type_arguments.Length() == 1) {
+ const AbstractType& tp_argument = AbstractType::ZoneHandle(
+ type_arguments.TypeAt(0));
+ ASSERT(!tp_argument.IsMalformed());
+ if (tp_argument.IsType()) {
+ ASSERT(tp_argument.HasResolvedTypeClass());
+ // Check if type argument is dynamic or Object.
+ const Type& object_type = Type::Handle(Type::ObjectType());
+ if (object_type.IsSubtypeOf(tp_argument, NULL)) {
+ // Instance class test only necessary.
+ return GenerateSubtype1TestCacheLookup(
+ token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
+ }
}
}
}
@@ -519,8 +522,9 @@
if (type.IsInstantiated()) {
const Class& type_class = Class::ZoneHandle(type.type_class());
// 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 (type_class.HasTypeArguments()) {
+ // non-parameterized class, non-signature class, or with a raw dst type of
+ // a parameterized class.
+ if (type_class.IsSignatureClass() || type_class.HasTypeArguments()) {
return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
type,
is_instance_lbl,
« no previous file with comments | « runtime/vm/flow_graph_compiler_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698