| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 const AbstractType& type, | 262 const AbstractType& type, |
| 263 Label* is_instance_lbl, | 263 Label* is_instance_lbl, |
| 264 Label* is_not_instance_lbl) { | 264 Label* is_not_instance_lbl) { |
| 265 __ Comment("InstantiatedTypeWithArgumentsTest"); | 265 __ Comment("InstantiatedTypeWithArgumentsTest"); |
| 266 ASSERT(type.IsInstantiated()); | 266 ASSERT(type.IsInstantiated()); |
| 267 const Class& type_class = Class::ZoneHandle(zone(), type.type_class()); | 267 const Class& type_class = Class::ZoneHandle(zone(), type.type_class()); |
| 268 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass()); | 268 ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass()); |
| 269 const Register kInstanceReg = EAX; | 269 const Register kInstanceReg = EAX; |
| 270 Error& malformed_error = Error::Handle(zone()); | 270 Error& malformed_error = Error::Handle(zone()); |
| 271 const Type& int_type = Type::Handle(zone(), Type::IntType()); | 271 const Type& int_type = Type::Handle(zone(), Type::IntType()); |
| 272 const bool smi_is_ok = int_type.IsSubtypeOf(type, &malformed_error); | 272 const bool smi_is_ok = |
| 273 int_type.IsSubtypeOf(type, &malformed_error, Heap::kOld); |
| 273 // Malformed type should have been handled at graph construction time. | 274 // Malformed type should have been handled at graph construction time. |
| 274 ASSERT(smi_is_ok || malformed_error.IsNull()); | 275 ASSERT(smi_is_ok || malformed_error.IsNull()); |
| 275 __ testl(kInstanceReg, Immediate(kSmiTagMask)); | 276 __ testl(kInstanceReg, Immediate(kSmiTagMask)); |
| 276 if (smi_is_ok) { | 277 if (smi_is_ok) { |
| 277 __ j(ZERO, is_instance_lbl); | 278 __ j(ZERO, is_instance_lbl); |
| 278 } else { | 279 } else { |
| 279 __ j(ZERO, is_not_instance_lbl); | 280 __ j(ZERO, is_not_instance_lbl); |
| 280 } | 281 } |
| 281 const intptr_t num_type_args = type_class.NumTypeArguments(); | 282 const intptr_t num_type_args = type_class.NumTypeArguments(); |
| 282 const intptr_t num_type_params = type_class.NumTypeParameters(); | 283 const intptr_t num_type_params = type_class.NumTypeParameters(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 302 } | 303 } |
| 303 // If one type argument only, check if type argument is Object or dynamic. | 304 // If one type argument only, check if type argument is Object or dynamic. |
| 304 if (type_arguments.Length() == 1) { | 305 if (type_arguments.Length() == 1) { |
| 305 const AbstractType& tp_argument = AbstractType::ZoneHandle( | 306 const AbstractType& tp_argument = AbstractType::ZoneHandle( |
| 306 zone(), type_arguments.TypeAt(0)); | 307 zone(), type_arguments.TypeAt(0)); |
| 307 ASSERT(!tp_argument.IsMalformed()); | 308 ASSERT(!tp_argument.IsMalformed()); |
| 308 if (tp_argument.IsType()) { | 309 if (tp_argument.IsType()) { |
| 309 ASSERT(tp_argument.HasResolvedTypeClass()); | 310 ASSERT(tp_argument.HasResolvedTypeClass()); |
| 310 // Check if type argument is dynamic or Object. | 311 // Check if type argument is dynamic or Object. |
| 311 const Type& object_type = Type::Handle(zone(), Type::ObjectType()); | 312 const Type& object_type = Type::Handle(zone(), Type::ObjectType()); |
| 312 if (object_type.IsSubtypeOf(tp_argument, NULL)) { | 313 if (object_type.IsSubtypeOf(tp_argument, NULL, Heap::kOld)) { |
| 313 // Instance class test only necessary. | 314 // Instance class test only necessary. |
| 314 return GenerateSubtype1TestCacheLookup( | 315 return GenerateSubtype1TestCacheLookup( |
| 315 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); | 316 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); |
| 316 } | 317 } |
| 317 } | 318 } |
| 318 } | 319 } |
| 319 } | 320 } |
| 320 // Regular subtype test cache involving instance's type arguments. | 321 // Regular subtype test cache involving instance's type arguments. |
| 321 const Register kTypeArgumentsReg = kNoRegister; | 322 const Register kTypeArgumentsReg = kNoRegister; |
| 322 const Register kTempReg = EDI; | 323 const Register kTempReg = EDI; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 const Class& type_class = Class::Handle(zone(), type.type_class()); | 357 const Class& type_class = Class::Handle(zone(), type.type_class()); |
| 357 ASSERT(type_class.NumTypeArguments() == 0); | 358 ASSERT(type_class.NumTypeArguments() == 0); |
| 358 | 359 |
| 359 const Register kInstanceReg = EAX; | 360 const Register kInstanceReg = EAX; |
| 360 __ testl(kInstanceReg, Immediate(kSmiTagMask)); | 361 __ testl(kInstanceReg, Immediate(kSmiTagMask)); |
| 361 // If instance is Smi, check directly. | 362 // If instance is Smi, check directly. |
| 362 const Class& smi_class = Class::Handle(zone(), Smi::Class()); | 363 const Class& smi_class = Class::Handle(zone(), Smi::Class()); |
| 363 if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()), | 364 if (smi_class.IsSubtypeOf(TypeArguments::Handle(zone()), |
| 364 type_class, | 365 type_class, |
| 365 TypeArguments::Handle(zone()), | 366 TypeArguments::Handle(zone()), |
| 366 NULL)) { | 367 NULL, |
| 368 Heap::kOld)) { |
| 367 __ j(ZERO, is_instance_lbl); | 369 __ j(ZERO, is_instance_lbl); |
| 368 } else { | 370 } else { |
| 369 __ j(ZERO, is_not_instance_lbl); | 371 __ j(ZERO, is_not_instance_lbl); |
| 370 } | 372 } |
| 371 // Compare if the classes are equal. | 373 // Compare if the classes are equal. |
| 372 const Register kClassIdReg = ECX; | 374 const Register kClassIdReg = ECX; |
| 373 __ LoadClassId(kClassIdReg, kInstanceReg); | 375 __ LoadClassId(kClassIdReg, kInstanceReg); |
| 374 __ cmpl(kClassIdReg, Immediate(type_class.id())); | 376 __ cmpl(kClassIdReg, Immediate(type_class.id())); |
| 375 __ j(EQUAL, is_instance_lbl); | 377 __ j(EQUAL, is_instance_lbl); |
| 376 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted | 378 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted |
| 377 // interfaces. | 379 // interfaces. |
| 378 // Bool interface can be implemented only by core class Bool. | 380 // Bool interface can be implemented only by core class Bool. |
| 379 if (type.IsBoolType()) { | 381 if (type.IsBoolType()) { |
| 380 __ cmpl(kClassIdReg, Immediate(kBoolCid)); | 382 __ cmpl(kClassIdReg, Immediate(kBoolCid)); |
| 381 __ j(EQUAL, is_instance_lbl); | 383 __ j(EQUAL, is_instance_lbl); |
| 382 __ jmp(is_not_instance_lbl); | 384 __ jmp(is_not_instance_lbl); |
| 383 return false; | 385 return false; |
| 384 } | 386 } |
| 385 if (type.IsFunctionType()) { | 387 if (type.IsFunctionType()) { |
| 386 // Check if instance is a closure. | 388 // Check if instance is a closure. |
| 387 const Immediate& raw_null = | 389 const Immediate& raw_null = |
| 388 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 390 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 389 __ LoadClassById(EDI, kClassIdReg); | 391 __ LoadClassById(EDI, kClassIdReg); |
| 390 __ movl(EDI, FieldAddress(EDI, Class::signature_function_offset())); | 392 __ movl(EDI, FieldAddress(EDI, Class::signature_function_offset())); |
| 391 __ cmpl(EDI, raw_null); | 393 __ cmpl(EDI, raw_null); |
| 392 __ j(NOT_EQUAL, is_instance_lbl); | 394 __ j(NOT_EQUAL, is_instance_lbl); |
| 393 } | 395 } |
| 394 // Custom checking for numbers (Smi, Mint, Bigint and Double). | 396 // Custom checking for numbers (Smi, Mint, Bigint and Double). |
| 395 // Note that instance is not Smi (checked above). | 397 // Note that instance is not Smi (checked above). |
| 396 if (type.IsSubtypeOf(Type::Handle(zone(), Type::Number()), NULL)) { | 398 if (type.IsSubtypeOf( |
| 399 Type::Handle(zone(), Type::Number()), NULL, Heap::kOld)) { |
| 397 GenerateNumberTypeCheck( | 400 GenerateNumberTypeCheck( |
| 398 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); | 401 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); |
| 399 return false; | 402 return false; |
| 400 } | 403 } |
| 401 if (type.IsStringType()) { | 404 if (type.IsStringType()) { |
| 402 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); | 405 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); |
| 403 return false; | 406 return false; |
| 404 } | 407 } |
| 405 // Otherwise fallthrough. | 408 // Otherwise fallthrough. |
| 406 return true; | 409 return true; |
| (...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1822 __ movups(reg, Address(ESP, 0)); | 1825 __ movups(reg, Address(ESP, 0)); |
| 1823 __ addl(ESP, Immediate(kFpuRegisterSize)); | 1826 __ addl(ESP, Immediate(kFpuRegisterSize)); |
| 1824 } | 1827 } |
| 1825 | 1828 |
| 1826 | 1829 |
| 1827 #undef __ | 1830 #undef __ |
| 1828 | 1831 |
| 1829 } // namespace dart | 1832 } // namespace dart |
| 1830 | 1833 |
| 1831 #endif // defined TARGET_ARCH_IA32 | 1834 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |