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" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 702 __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
703 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 703 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
704 __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 704 __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
705 __ jmp(&done); | 705 __ jmp(&done); |
706 | 706 |
707 __ Bind(&size_tag_overflow); | 707 __ Bind(&size_tag_overflow); |
708 __ movl(ECX, Immediate(0)); | 708 __ movl(ECX, Immediate(0)); |
709 __ Bind(&done); | 709 __ Bind(&done); |
710 | 710 |
711 // Get the class index and insert it into the tags. | 711 // Get the class index and insert it into the tags. |
712 __ orl(ECX, Immediate(RawObject::ClassIdTag::encode(kArray))); | 712 __ orl(ECX, Immediate(RawObject::ClassIdTag::encode(kArrayCid))); |
713 __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); | 713 __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); |
714 } | 714 } |
715 | 715 |
716 // Initialize all array elements to raw_null. | 716 // Initialize all array elements to raw_null. |
717 // EAX: new object start as a tagged pointer. | 717 // EAX: new object start as a tagged pointer. |
718 // EBX: new object end address. | 718 // EBX: new object end address. |
719 // EDX: Array length as Smi. | 719 // EDX: Array length as Smi. |
720 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 720 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); |
721 // ECX: iterator which initially points to the start of the variable | 721 // ECX: iterator which initially points to the start of the variable |
722 // data area to be initialized. | 722 // data area to be initialized. |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 // EDI: new object type arguments. | 1242 // EDI: new object type arguments. |
1243 } | 1243 } |
1244 | 1244 |
1245 // EAX: new object start. | 1245 // EAX: new object start. |
1246 // EBX: next object start. | 1246 // EBX: next object start. |
1247 // EDI: new object type arguments (if is_cls_parameterized). | 1247 // EDI: new object type arguments (if is_cls_parameterized). |
1248 __ LoadObject(EDX, cls); // Load class of object to be allocated. | 1248 __ LoadObject(EDX, cls); // Load class of object to be allocated. |
1249 // Set the tags. | 1249 // Set the tags. |
1250 uword tags = 0; | 1250 uword tags = 0; |
1251 tags = RawObject::SizeTag::update(instance_size, tags); | 1251 tags = RawObject::SizeTag::update(instance_size, tags); |
1252 ASSERT(cls.id() != kIllegalObjectKind); | 1252 ASSERT(cls.id() != kIllegalCid); |
1253 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1253 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1254 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); | 1254 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
1255 | 1255 |
1256 // Initialize the remaining words of the object. | 1256 // Initialize the remaining words of the object. |
1257 const Immediate raw_null = | 1257 const Immediate raw_null = |
1258 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1258 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1259 | 1259 |
1260 // EAX: new object start. | 1260 // EAX: new object start. |
1261 // EBX: next object start. | 1261 // EBX: next object start. |
1262 // EDX: class of the object to be allocated. | 1262 // EDX: class of the object to be allocated. |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 // EBX: points directly to the first ic data array element. | 1635 // EBX: points directly to the first ic data array element. |
1636 Label loop, found; | 1636 Label loop, found; |
1637 if (num_args == 1) { | 1637 if (num_args == 1) { |
1638 __ call(&get_class_id_as_smi); | 1638 __ call(&get_class_id_as_smi); |
1639 // EAX: receiver's class id Smi. | 1639 // EAX: receiver's class id Smi. |
1640 __ Bind(&loop); | 1640 __ Bind(&loop); |
1641 __ movl(EDI, Address(EBX, 0)); // Get class id (Smi) to check. | 1641 __ movl(EDI, Address(EBX, 0)); // Get class id (Smi) to check. |
1642 __ cmpl(EAX, EDI); // Class id match? | 1642 __ cmpl(EAX, EDI); // Class id match? |
1643 __ j(EQUAL, &found, Assembler::kNearJump); | 1643 __ j(EQUAL, &found, Assembler::kNearJump); |
1644 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). | 1644 __ addl(EBX, Immediate(kWordSize * 2)); // Next element (class + target). |
1645 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalObjectKind))); // Done? | 1645 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1646 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1646 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1647 } else if (num_args == 2) { | 1647 } else if (num_args == 2) { |
1648 // EDI: class to check. | 1648 // EDI: class to check. |
1649 Label no_match; | 1649 Label no_match; |
1650 __ Bind(&loop); | 1650 __ Bind(&loop); |
1651 // Get class id from IC data to check. | 1651 // Get class id from IC data to check. |
1652 // Get receiver using argument descriptor in EDX. | 1652 // Get receiver using argument descriptor in EDX. |
1653 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1653 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
1654 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi. | 1654 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (arg. count) is Smi. |
1655 __ call(&get_class_id_as_smi); | 1655 __ call(&get_class_id_as_smi); |
1656 __ movl(EDI, Address(EBX, 0)); | 1656 __ movl(EDI, Address(EBX, 0)); |
1657 __ cmpl(EAX, EDI); // Class id match? | 1657 __ cmpl(EAX, EDI); // Class id match? |
1658 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); | 1658 __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); |
1659 // Check second class/argument. | 1659 // Check second class/argument. |
1660 // Get class id from IC data to check. | 1660 // Get class id from IC data to check. |
1661 // Get next argument. | 1661 // Get next argument. |
1662 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1662 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
1663 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); | 1663 __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); |
1664 // EAX (argument count) is Smi. | 1664 // EAX (argument count) is Smi. |
1665 __ call(&get_class_id_as_smi); | 1665 __ call(&get_class_id_as_smi); |
1666 __ movl(EDI, Address(EBX, kWordSize)); | 1666 __ movl(EDI, Address(EBX, kWordSize)); |
1667 __ cmpl(EAX, EDI); // Class id match? | 1667 __ cmpl(EAX, EDI); // Class id match? |
1668 __ j(EQUAL, &found, Assembler::kNearJump); | 1668 __ j(EQUAL, &found, Assembler::kNearJump); |
1669 __ Bind(&no_match); | 1669 __ Bind(&no_match); |
1670 // Each test entry has (1 + num_args) array elements. | 1670 // Each test entry has (1 + num_args) array elements. |
1671 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. | 1671 __ addl(EBX, Immediate(kWordSize * (1 + num_args))); // Next element. |
1672 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalObjectKind))); // Done? | 1672 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1673 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1673 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1674 } | 1674 } |
1675 | 1675 |
1676 __ Bind(&ic_miss); | 1676 __ Bind(&ic_miss); |
1677 // Compute address of arguments (first read number of arguments from argument | 1677 // Compute address of arguments (first read number of arguments from argument |
1678 // descriptor array and then compute address on the stack). | 1678 // descriptor array and then compute address on the stack). |
1679 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1679 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); |
1680 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. | 1680 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. |
1681 // Create a stub frame as we are pushing some objects on the stack before | 1681 // Create a stub frame as we are pushing some objects on the stack before |
1682 // calling into the runtime. | 1682 // calling into the runtime. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1719 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); | 1719 __ movl(EAX, FieldAddress(EAX, Function::code_offset())); |
1720 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 1720 __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); |
1721 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1721 __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1722 __ jmp(EAX); | 1722 __ jmp(EAX); |
1723 | 1723 |
1724 __ Bind(&get_class_id_as_smi); | 1724 __ Bind(&get_class_id_as_smi); |
1725 Label not_smi; | 1725 Label not_smi; |
1726 // Test if Smi -> load Smi class for comparison. | 1726 // Test if Smi -> load Smi class for comparison. |
1727 __ testl(EAX, Immediate(kSmiTagMask)); | 1727 __ testl(EAX, Immediate(kSmiTagMask)); |
1728 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 1728 __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
1729 __ movl(EAX, Immediate(Smi::RawValue(kSmi))); | 1729 __ movl(EAX, Immediate(Smi::RawValue(kSmiCid))); |
1730 __ ret(); | 1730 __ ret(); |
1731 | 1731 |
1732 __ Bind(¬_smi); | 1732 __ Bind(¬_smi); |
1733 __ LoadClassId(EAX, EAX); | 1733 __ LoadClassId(EAX, EAX); |
1734 __ SmiTag(EAX); | 1734 __ SmiTag(EAX); |
1735 __ ret(); | 1735 __ ret(); |
1736 } | 1736 } |
1737 | 1737 |
1738 | 1738 |
1739 // Use inline cache data array to invoke the target or continue in inline | 1739 // Use inline cache data array to invoke the target or continue in inline |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 __ movl(EAX, Address(ESP, 4 * kWordSize)); // Load error object. | 1974 __ movl(EAX, Address(ESP, 4 * kWordSize)); // Load error object. |
1975 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. | 1975 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. |
1976 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. | 1976 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. |
1977 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. | 1977 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. |
1978 __ jmp(EBX); // Jump to the exception handler code. | 1978 __ jmp(EBX); // Jump to the exception handler code. |
1979 } | 1979 } |
1980 | 1980 |
1981 } // namespace dart | 1981 } // namespace dart |
1982 | 1982 |
1983 #endif // defined TARGET_ARCH_IA32 | 1983 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |