| 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 |