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_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/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 | 81 |
82 // RAX: new growable array object start as a tagged pointer. | 82 // RAX: new growable array object start as a tagged pointer. |
83 // Store the type argument field in the growable array object. | 83 // Store the type argument field in the growable array object. |
84 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); // type argument. | 84 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); // type argument. |
85 __ StoreIntoObjectNoBarrier( | 85 __ StoreIntoObjectNoBarrier( |
86 RAX, | 86 RAX, |
87 FieldAddress(RAX, GrowableObjectArray::type_arguments_offset()), | 87 FieldAddress(RAX, GrowableObjectArray::type_arguments_offset()), |
88 RCX); | 88 RCX); |
89 | 89 |
90 // Set the length field in the growable array object to 0. | 90 // Set the length field in the growable array object to 0. |
91 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), | 91 __ ZeroSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset())); |
92 Immediate(0)); | |
93 __ ret(); // returns the newly allocated object in RAX. | 92 __ ret(); // returns the newly allocated object in RAX. |
94 | 93 |
95 __ Bind(&fall_through); | 94 __ Bind(&fall_through); |
96 } | 95 } |
97 | 96 |
98 | 97 |
99 // Access growable object array at specified index. | 98 // Access growable object array at specified index. |
100 // On stack: growable array (+2), index (+1), return-address (+0). | 99 // On stack: growable array (+2), index (+1), return-address (+0). |
101 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | 100 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { |
102 Label fall_through; | 101 Label fall_through; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 146 |
148 // Set length of growable object array. The length cannot | 147 // Set length of growable object array. The length cannot |
149 // be greater than the length of the data container. | 148 // be greater than the length of the data container. |
150 // On stack: growable array (+2), length (+1), return-address (+0). | 149 // On stack: growable array (+2), length (+1), return-address (+0). |
151 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { | 150 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { |
152 Label fall_through; | 151 Label fall_through; |
153 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. | 152 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Growable array. |
154 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value. | 153 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Length value. |
155 __ testq(RCX, Immediate(kSmiTagMask)); | 154 __ testq(RCX, Immediate(kSmiTagMask)); |
156 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. | 155 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. |
157 __ movq(FieldAddress(RAX, GrowableObjectArray::length_offset()), RCX); | 156 FieldAddress length_field(RAX, GrowableObjectArray::length_offset()); |
| 157 __ StoreIntoSmiField(length_field, RCX); |
158 __ ret(); | 158 __ ret(); |
159 __ Bind(&fall_through); | 159 __ Bind(&fall_through); |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 // Set data of growable object array. | 163 // Set data of growable object array. |
164 // On stack: growable array (+2), data (+1), return-address (+0). | 164 // On stack: growable array (+2), data (+1), return-address (+0). |
165 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { | 165 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { |
166 if (FLAG_enable_type_checks) { | 166 if (FLAG_enable_type_checks) { |
167 return; | 167 return; |
(...skipping 21 matching lines...) Expand all Loading... |
189 if (FLAG_enable_type_checks) return; | 189 if (FLAG_enable_type_checks) return; |
190 Label fall_through; | 190 Label fall_through; |
191 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. | 191 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Array. |
192 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); | 192 __ movq(RCX, FieldAddress(RAX, GrowableObjectArray::length_offset())); |
193 // RCX: length. | 193 // RCX: length. |
194 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); | 194 __ movq(RDX, FieldAddress(RAX, GrowableObjectArray::data_offset())); |
195 // RDX: data. | 195 // RDX: data. |
196 // Compare length with capacity. | 196 // Compare length with capacity. |
197 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); | 197 __ cmpq(RCX, FieldAddress(RDX, Array::length_offset())); |
198 __ j(EQUAL, &fall_through); // Must grow data. | 198 __ j(EQUAL, &fall_through); // Must grow data. |
199 const Immediate& value_one = | |
200 Immediate(reinterpret_cast<int64_t>(Smi::New(1))); | |
201 // len = len + 1; | 199 // len = len + 1; |
202 __ addq(FieldAddress(RAX, GrowableObjectArray::length_offset()), value_one); | 200 __ IncrementSmiField(FieldAddress(RAX, GrowableObjectArray::length_offset()), |
| 201 1); |
203 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value | 202 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Value |
204 ASSERT(kSmiTagShift == 1); | 203 ASSERT(kSmiTagShift == 1); |
205 __ StoreIntoObject(RDX, | 204 __ StoreIntoObject(RDX, |
206 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), | 205 FieldAddress(RDX, RCX, TIMES_4, Array::data_offset()), |
207 RAX); | 206 RAX); |
208 __ LoadObject(RAX, Object::null_object(), PP); | 207 __ LoadObject(RAX, Object::null_object(), PP); |
209 __ ret(); | 208 __ ret(); |
210 __ Bind(&fall_through); | 209 __ Bind(&fall_through); |
211 } | 210 } |
212 | 211 |
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1684 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); | 1683 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); |
1685 __ andl(RAX, | 1684 __ andl(RAX, |
1686 Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1))); | 1685 Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1))); |
1687 | 1686 |
1688 // return hash_ == 0 ? 1 : hash_; | 1687 // return hash_ == 0 ? 1 : hash_; |
1689 __ cmpq(RAX, Immediate(0)); | 1688 __ cmpq(RAX, Immediate(0)); |
1690 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); | 1689 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); |
1691 __ incq(RAX); | 1690 __ incq(RAX); |
1692 __ Bind(&set_hash_code); | 1691 __ Bind(&set_hash_code); |
1693 __ SmiTag(RAX); | 1692 __ SmiTag(RAX); |
1694 __ movq(FieldAddress(RBX, String::hash_offset()), RAX); | 1693 __ StoreIntoSmiField(FieldAddress(RBX, String::hash_offset()), RAX); |
1695 __ ret(); | 1694 __ ret(); |
1696 } | 1695 } |
1697 | 1696 |
1698 | 1697 |
1699 // Allocates one-byte string of length 'end - start'. The content is not | 1698 // Allocates one-byte string of length 'end - start'. The content is not |
1700 // initialized. 'length-reg' contains tagged length. | 1699 // initialized. 'length-reg' contains tagged length. |
1701 // Returns new string as tagged pointer in RAX. | 1700 // Returns new string as tagged pointer in RAX. |
1702 static void TryAllocateOnebyteString(Assembler* assembler, | 1701 static void TryAllocateOnebyteString(Assembler* assembler, |
1703 Label* ok, | 1702 Label* ok, |
1704 Label* failure, | 1703 Label* failure, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid))); | 1757 __ orq(RDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
1759 __ movq(FieldAddress(RAX, String::tags_offset()), RDI); // Tags. | 1758 __ movq(FieldAddress(RAX, String::tags_offset()), RDI); // Tags. |
1760 } | 1759 } |
1761 | 1760 |
1762 // Set the length field. | 1761 // Set the length field. |
1763 __ popq(RDI); | 1762 __ popq(RDI); |
1764 __ StoreIntoObjectNoBarrier(RAX, | 1763 __ StoreIntoObjectNoBarrier(RAX, |
1765 FieldAddress(RAX, String::length_offset()), | 1764 FieldAddress(RAX, String::length_offset()), |
1766 RDI); | 1765 RDI); |
1767 // Clear hash. | 1766 // Clear hash. |
1768 __ movq(FieldAddress(RAX, String::hash_offset()), Immediate(0)); | 1767 __ ZeroSmiField(FieldAddress(RAX, String::hash_offset())); |
1769 __ jmp(ok, Assembler::kNearJump); | 1768 __ jmp(ok, Assembler::kNearJump); |
1770 | 1769 |
1771 __ Bind(&pop_and_fail); | 1770 __ Bind(&pop_and_fail); |
1772 __ popq(RDI); | 1771 __ popq(RDI); |
1773 __ jmp(failure); | 1772 __ jmp(failure); |
1774 } | 1773 } |
1775 | 1774 |
1776 | 1775 |
1777 // Arg0: OneByteString (receiver). | 1776 // Arg0: OneByteString (receiver). |
1778 // Arg1: Start index as Smi. | 1777 // Arg1: Start index as Smi. |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1957 // Set return value to Isolate::current_tag_. | 1956 // Set return value to Isolate::current_tag_. |
1958 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); | 1957 __ movq(RAX, Address(RBX, Isolate::current_tag_offset())); |
1959 __ ret(); | 1958 __ ret(); |
1960 } | 1959 } |
1961 | 1960 |
1962 #undef __ | 1961 #undef __ |
1963 | 1962 |
1964 } // namespace dart | 1963 } // namespace dart |
1965 | 1964 |
1966 #endif // defined TARGET_ARCH_X64 | 1965 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |