| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 } | 185 } |
| 186 // If one type argument only, check if type argument is Object or Dynamic. | 186 // If one type argument only, check if type argument is Object or Dynamic. |
| 187 if (type_arguments.Length() == 1) { | 187 if (type_arguments.Length() == 1) { |
| 188 const AbstractType& tp_argument = AbstractType::ZoneHandle( | 188 const AbstractType& tp_argument = AbstractType::ZoneHandle( |
| 189 type_arguments.TypeAt(0)); | 189 type_arguments.TypeAt(0)); |
| 190 ASSERT(!tp_argument.IsMalformed()); | 190 ASSERT(!tp_argument.IsMalformed()); |
| 191 if (tp_argument.IsType()) { | 191 if (tp_argument.IsType()) { |
| 192 ASSERT(tp_argument.HasResolvedTypeClass()); | 192 ASSERT(tp_argument.HasResolvedTypeClass()); |
| 193 // Check if type argument is dynamic or Object. | 193 // Check if type argument is dynamic or Object. |
| 194 const Type& object_type = Type::Handle(Type::ObjectType()); | 194 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 195 Error& malformed_error = Error::Handle(); | 195 if (object_type.IsSubtypeOf(tp_argument, NULL)) { |
| 196 if (object_type.IsSubtypeOf(tp_argument, &malformed_error)) { | |
| 197 // Instance class test only necessary. | 196 // Instance class test only necessary. |
| 198 return GenerateSubtype1TestCacheLookup( | 197 return GenerateSubtype1TestCacheLookup( |
| 199 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); | 198 cid, token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 200 } | 199 } |
| 201 } | 200 } |
| 202 } | 201 } |
| 203 // Regular subtype test cache involving instance's type arguments. | 202 // Regular subtype test cache involving instance's type arguments. |
| 204 const Register kTypeArgumentsReg = kNoRegister; | 203 const Register kTypeArgumentsReg = kNoRegister; |
| 205 const Register kTempReg = R10; | 204 const Register kTempReg = R10; |
| 206 return GenerateCallSubtypeTestStub(kTestTypeTwoArgs, | 205 return GenerateCallSubtypeTestStub(kTestTypeTwoArgs, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 ASSERT(type.IsInstantiated()); | 237 ASSERT(type.IsInstantiated()); |
| 239 const Class& type_class = Class::Handle(type.type_class()); | 238 const Class& type_class = Class::Handle(type.type_class()); |
| 240 ASSERT(!type_class.HasTypeArguments()); | 239 ASSERT(!type_class.HasTypeArguments()); |
| 241 | 240 |
| 242 const Register kInstanceReg = RAX; | 241 const Register kInstanceReg = RAX; |
| 243 Label compare_classes; | 242 Label compare_classes; |
| 244 __ testq(kInstanceReg, Immediate(kSmiTagMask)); | 243 __ testq(kInstanceReg, Immediate(kSmiTagMask)); |
| 245 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); | 244 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); |
| 246 // Instance is Smi, check directly. | 245 // Instance is Smi, check directly. |
| 247 const Class& smi_class = Class::Handle(Smi::Class()); | 246 const Class& smi_class = Class::Handle(Smi::Class()); |
| 248 Error& malformed_error = Error::Handle(); | |
| 249 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), | 247 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), |
| 250 type_class, | 248 type_class, |
| 251 TypeArguments::Handle(), | 249 TypeArguments::Handle(), |
| 252 &malformed_error)) { | 250 NULL)) { |
| 253 __ jmp(is_instance_lbl); | 251 __ jmp(is_instance_lbl); |
| 254 } else { | 252 } else { |
| 255 __ jmp(is_not_instance_lbl); | 253 __ jmp(is_not_instance_lbl); |
| 256 } | 254 } |
| 257 // Compare if the classes are equal. | 255 // Compare if the classes are equal. |
| 258 __ Bind(&compare_classes); | 256 __ Bind(&compare_classes); |
| 259 const Register kClassIdReg = R10; | 257 const Register kClassIdReg = R10; |
| 260 __ LoadClassId(kClassIdReg, kInstanceReg); | 258 __ LoadClassId(kClassIdReg, kInstanceReg); |
| 261 // If type is an interface, we can skip the class equality check. | 259 // If type is an interface, we can skip the class equality check. |
| 262 if (!type_class.is_interface()) { | 260 if (!type_class.is_interface()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 277 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 275 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 278 __ LoadClassById(R13, kClassIdReg); | 276 __ LoadClassById(R13, kClassIdReg); |
| 279 __ movq(R13, FieldAddress(R13, Class::signature_function_offset())); | 277 __ movq(R13, FieldAddress(R13, Class::signature_function_offset())); |
| 280 __ cmpq(R13, raw_null); | 278 __ cmpq(R13, raw_null); |
| 281 __ j(NOT_EQUAL, is_instance_lbl); | 279 __ j(NOT_EQUAL, is_instance_lbl); |
| 282 __ jmp(is_not_instance_lbl); | 280 __ jmp(is_not_instance_lbl); |
| 283 return false; | 281 return false; |
| 284 } | 282 } |
| 285 // Custom checking for numbers (Smi, Mint, Bigint and Double). | 283 // Custom checking for numbers (Smi, Mint, Bigint and Double). |
| 286 // Note that instance is not Smi (checked above). | 284 // Note that instance is not Smi (checked above). |
| 287 if (type.IsSubtypeOf( | 285 if (type.IsSubtypeOf(Type::Handle(Type::NumberInterface()), NULL)) { |
| 288 Type::Handle(Type::NumberInterface()), &malformed_error)) { | |
| 289 GenerateNumberTypeCheck( | 286 GenerateNumberTypeCheck( |
| 290 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); | 287 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); |
| 291 return false; | 288 return false; |
| 292 } | 289 } |
| 293 if (type.IsStringInterface()) { | 290 if (type.IsStringInterface()) { |
| 294 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); | 291 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); |
| 295 return false; | 292 return false; |
| 296 } | 293 } |
| 297 // Otherwise fallthrough. | 294 // Otherwise fallthrough. |
| 298 return true; | 295 return true; |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { | 1229 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
| 1233 __ Exchange(mem1, mem2); | 1230 __ Exchange(mem1, mem2); |
| 1234 } | 1231 } |
| 1235 | 1232 |
| 1236 | 1233 |
| 1237 #undef __ | 1234 #undef __ |
| 1238 | 1235 |
| 1239 } // namespace dart | 1236 } // namespace dart |
| 1240 | 1237 |
| 1241 #endif // defined TARGET_ARCH_X64 | 1238 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |