Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1408 __ PushObject(negate_result ? bool_true : bool_false); | 1408 __ PushObject(negate_result ? bool_true : bool_false); |
| 1409 __ jmp(&done, Assembler::kNearJump); | 1409 __ jmp(&done, Assembler::kNearJump); |
| 1410 | 1410 |
| 1411 __ Bind(&non_null); | 1411 __ Bind(&non_null); |
| 1412 // If type is instantiated and non-parameterized, we can inline code | 1412 // If type is instantiated and non-parameterized, we can inline code |
| 1413 // checking whether the tested instance is a Smi. | 1413 // checking whether the tested instance is a Smi. |
| 1414 if (type.IsInstantiated()) { | 1414 if (type.IsInstantiated()) { |
| 1415 const Class& type_class = Class::ZoneHandle(type.type_class()); | 1415 const Class& type_class = Class::ZoneHandle(type.type_class()); |
| 1416 const bool requires_type_arguments = type_class.HasTypeArguments(); | 1416 const bool requires_type_arguments = type_class.HasTypeArguments(); |
| 1417 // A Smi object cannot be the instance of a parameterized class. | 1417 // A Smi object cannot be the instance of a parameterized class. |
| 1418 // A class equality check is only applicable to a non-parameterized class. | 1418 // A class equality check is only applicable with a dst type of a |
| 1419 // non-parameterized class or with a raw dst type of a parameterized class. | |
| 1419 // TODO(regis): Should we still inline a Smi type check when checking for a | 1420 // TODO(regis): Should we still inline a Smi type check when checking for a |
|
regis
2011/11/10 03:09:51
I think you can remove this TODO now.
srdjan
2011/11/10 17:24:41
Done.
| |
| 1420 // parameterized type and return false for a Smi's without calling the | 1421 // parameterized type and return false for a Smi's without calling the |
| 1421 // runtime? | 1422 // runtime? |
| 1422 if (!requires_type_arguments) { | 1423 if (requires_type_arguments) { |
| 1424 const TypeArguments& type_arguments = | |
| 1425 TypeArguments::Handle(type.arguments()); | |
| 1426 const bool is_raw_type = type_arguments.IsNull() || | |
| 1427 type_arguments.IsDynamicTypes(type_arguments.Length()); | |
| 1428 if (is_raw_type) { | |
| 1429 if (!type_class.is_interface()) { | |
| 1430 Label runtime_call; | |
| 1431 __ testl(EAX, Immediate(kSmiTagMask)); | |
| 1432 __ j(ZERO, &runtime_call, Assembler::kNearJump); | |
|
regis
2011/11/10 03:09:51
Can't you perform this Smi check even if the type
srdjan
2011/11/10 17:24:41
Done.
| |
| 1433 // Object not Smi. | |
| 1434 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | |
| 1435 __ CompareObject(ECX, type_class); | |
| 1436 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); | |
| 1437 __ PushObject(negate_result ? bool_false : bool_true); | |
| 1438 __ jmp(&done, Assembler::kNearJump); | |
| 1439 __ Bind(&runtime_call); | |
| 1440 // Fall through to runtime call. | |
| 1441 } | |
| 1442 } | |
| 1443 } else { | |
| 1423 Label compare_classes; | 1444 Label compare_classes; |
| 1424 __ testl(EAX, Immediate(kSmiTagMask)); | 1445 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1425 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); | 1446 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); |
| 1426 // Object is Smi. | 1447 // Object is Smi. |
| 1427 const Class& smi_class = Class::Handle(Smi::Class()); | 1448 const Class& smi_class = Class::Handle(Smi::Class()); |
| 1428 // TODO(regis): We should introduce a SmiType. | 1449 // TODO(regis): We should introduce a SmiType. |
| 1429 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), | 1450 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), |
| 1430 type_class, | 1451 type_class, |
| 1431 TypeArguments::Handle())) { | 1452 TypeArguments::Handle())) { |
| 1432 __ PushObject(negate_result ? bool_false : bool_true); | 1453 __ PushObject(negate_result ? bool_false : bool_true); |
| 1433 } else { | 1454 } else { |
| 1434 __ PushObject(negate_result ? bool_true : bool_false); | 1455 __ PushObject(negate_result ? bool_true : bool_false); |
| 1435 } | 1456 } |
| 1436 __ jmp(&done, Assembler::kNearJump); | 1457 __ jmp(&done, Assembler::kNearJump); |
| 1437 | 1458 |
| 1438 // Compare if the classes are equal. | 1459 // Compare if the classes are equal. |
| 1439 __ Bind(&compare_classes); | 1460 __ Bind(&compare_classes); |
| 1440 // If type is an interface, we can skip the class equality check, | 1461 if (type_class.is_interface()) { |
| 1441 // because instances cannot be of an interface type. | 1462 if (type.IsStringInterface()) { |
| 1442 if (!type_class.is_interface()) { | 1463 Label runtime_call; |
| 1464 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | |
| 1465 const Class& one_byte_string_class = Class::ZoneHandle( | |
| 1466 Isolate::Current()->object_store()->one_byte_string_class()); | |
| 1467 __ CompareObject(ECX, one_byte_string_class); | |
| 1468 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); | |
| 1469 __ PushObject(negate_result ? bool_false : bool_true); | |
| 1470 __ jmp(&done, Assembler::kNearJump); | |
| 1471 __ Bind(&runtime_call); | |
| 1472 } | |
| 1473 } else { // type_class is not an interface. | |
| 1443 Label runtime_call; | 1474 Label runtime_call; |
| 1444 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | 1475 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 1445 __ CompareObject(ECX, type_class); | 1476 __ CompareObject(ECX, type_class); |
| 1446 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); | 1477 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); |
| 1447 __ PushObject(negate_result ? bool_false : bool_true); | 1478 __ PushObject(negate_result ? bool_false : bool_true); |
| 1448 __ jmp(&done, Assembler::kNearJump); | 1479 __ jmp(&done, Assembler::kNearJump); |
| 1449 __ Bind(&runtime_call); | 1480 __ Bind(&runtime_call); |
| 1450 } | 1481 } |
| 1451 } | 1482 } |
| 1452 } | 1483 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1558 TestClassAndJump(*CoreClass("ObjectArray"), &done); | 1589 TestClassAndJump(*CoreClass("ObjectArray"), &done); |
| 1559 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done); | 1590 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done); |
| 1560 } else if (!dst_type_class.is_interface()) { | 1591 } else if (!dst_type_class.is_interface()) { |
| 1561 __ testl(EAX, Immediate(kSmiTagMask)); | 1592 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1562 __ j(ZERO, &runtime_call, Assembler::kNearJump); | 1593 __ j(ZERO, &runtime_call, Assembler::kNearJump); |
| 1563 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | 1594 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 1564 TestClassAndJump(dst_type_class, &done); | 1595 TestClassAndJump(dst_type_class, &done); |
| 1565 } | 1596 } |
| 1566 // Fall through to runtime class. | 1597 // Fall through to runtime class. |
| 1567 } | 1598 } |
| 1568 } else { | 1599 } else { // dst_type has NO type parameters. |
|
regis
2011/11/10 03:09:51
Sorry to be picky, but "type parameters" is the wr
srdjan
2011/11/10 17:24:41
Done.
| |
| 1569 Label compare_classes; | 1600 Label compare_classes; |
| 1570 __ testl(EAX, Immediate(kSmiTagMask)); | 1601 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1571 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); | 1602 __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); |
| 1572 // Object is Smi. | 1603 // Object is Smi. |
| 1573 const Class& smi_class = Class::Handle(Smi::Class()); | 1604 const Class& smi_class = Class::Handle(Smi::Class()); |
| 1574 // TODO(regis): We should introduce a SmiType. | 1605 // TODO(regis): We should introduce a SmiType. |
| 1575 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), | 1606 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), |
| 1576 dst_type_class, | 1607 dst_type_class, |
| 1577 TypeArguments::Handle())) { | 1608 TypeArguments::Handle())) { |
| 1578 // Successful assignable type check: return object in EAX. | 1609 // Successful assignable type check: return object in EAX. |
| (...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2708 const Class& cls = Class::Handle(parsed_function_.function().owner()); | 2739 const Class& cls = Class::Handle(parsed_function_.function().owner()); |
| 2709 const Script& script = Script::Handle(cls.script()); | 2740 const Script& script = Script::Handle(cls.script()); |
| 2710 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); | 2741 Parser::ReportMsg(script, token_index, "Error", error_msg, format, args); |
| 2711 Isolate::Current()->long_jump_base()->Jump(1, error_msg); | 2742 Isolate::Current()->long_jump_base()->Jump(1, error_msg); |
| 2712 UNREACHABLE(); | 2743 UNREACHABLE(); |
| 2713 } | 2744 } |
| 2714 | 2745 |
| 2715 } // namespace dart | 2746 } // namespace dart |
| 2716 | 2747 |
| 2717 #endif // defined TARGET_ARCH_IA32 | 2748 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |