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_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 // R0: new growable array object start as a tagged pointer. | 125 // R0: new growable array object start as a tagged pointer. |
126 // Store the type argument field in the growable array object. | 126 // Store the type argument field in the growable array object. |
127 __ ldr(R1, Address(SP, kTypeArgumentsOffset)); // Type argument. | 127 __ ldr(R1, Address(SP, kTypeArgumentsOffset)); // Type argument. |
128 __ StoreIntoObjectNoBarrier( | 128 __ StoreIntoObjectNoBarrier( |
129 R0, | 129 R0, |
130 FieldAddress(R0, GrowableObjectArray::type_arguments_offset()), | 130 FieldAddress(R0, GrowableObjectArray::type_arguments_offset()), |
131 R1); | 131 R1); |
132 | 132 |
133 // Set the length field in the growable array object to 0. | 133 // Set the length field in the growable array object to 0. |
134 __ LoadImmediate(R1, 0); | 134 __ LoadImmediate(R1, 0); |
135 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); | 135 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), |
| 136 R1); |
136 __ Ret(); // Returns the newly allocated object in R0. | 137 __ Ret(); // Returns the newly allocated object in R0. |
137 | 138 |
138 __ Bind(&fall_through); | 139 __ Bind(&fall_through); |
139 } | 140 } |
140 | 141 |
141 | 142 |
142 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | 143 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { |
143 Label fall_through; | 144 Label fall_through; |
144 | 145 |
145 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index | 146 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 __ StoreIntoObject(R0, FieldAddress(R1, Array::data_offset()), R2); | 187 __ StoreIntoObject(R0, FieldAddress(R1, Array::data_offset()), R2); |
187 __ Ret(); | 188 __ Ret(); |
188 __ Bind(&fall_through); | 189 __ Bind(&fall_through); |
189 } | 190 } |
190 | 191 |
191 | 192 |
192 // Set length of growable object array. The length cannot | 193 // Set length of growable object array. The length cannot |
193 // be greater than the length of the data container. | 194 // be greater than the length of the data container. |
194 // On stack: growable array (+1), length (+0). | 195 // On stack: growable array (+1), length (+0). |
195 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { | 196 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { |
| 197 Label fall_through; |
196 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. | 198 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. |
197 __ ldr(R1, Address(SP, 0 * kWordSize)); // Length value. | 199 __ ldr(R1, Address(SP, 0 * kWordSize)); // Length value. |
198 __ tst(R1, Operand(kSmiTagMask)); // Check for Smi. | 200 __ tst(R1, Operand(kSmiTagMask)); |
199 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset()), EQ); | 201 __ b(&fall_through, NE); // Non-smi length. |
200 __ bx(LR, EQ); | 202 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), |
201 // Fall through on non-Smi. | 203 R1); |
| 204 __ Ret(); |
| 205 __ Bind(&fall_through); |
202 } | 206 } |
203 | 207 |
204 | 208 |
205 // Set data of growable object array. | 209 // Set data of growable object array. |
206 // On stack: growable array (+1), data (+0). | 210 // On stack: growable array (+1), data (+0). |
207 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { | 211 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { |
208 if (FLAG_enable_type_checks) { | 212 if (FLAG_enable_type_checks) { |
209 return; | 213 return; |
210 } | 214 } |
211 Label fall_through; | 215 Label fall_through; |
(...skipping 28 matching lines...) Expand all Loading... |
240 // R2: data. | 244 // R2: data. |
241 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::data_offset())); | 245 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::data_offset())); |
242 // R3: capacity. | 246 // R3: capacity. |
243 __ ldr(R3, FieldAddress(R2, Array::length_offset())); | 247 __ ldr(R3, FieldAddress(R2, Array::length_offset())); |
244 // Compare length with capacity. | 248 // Compare length with capacity. |
245 __ cmp(R1, Operand(R3)); | 249 __ cmp(R1, Operand(R3)); |
246 __ b(&fall_through, EQ); // Must grow data. | 250 __ b(&fall_through, EQ); // Must grow data. |
247 const int32_t value_one = reinterpret_cast<int32_t>(Smi::New(1)); | 251 const int32_t value_one = reinterpret_cast<int32_t>(Smi::New(1)); |
248 // len = len + 1; | 252 // len = len + 1; |
249 __ add(R3, R1, Operand(value_one)); | 253 __ add(R3, R1, Operand(value_one)); |
250 __ str(R3, FieldAddress(R0, GrowableObjectArray::length_offset())); | 254 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), |
| 255 R3); |
251 __ ldr(R0, Address(SP, 0 * kWordSize)); // Value. | 256 __ ldr(R0, Address(SP, 0 * kWordSize)); // Value. |
252 ASSERT(kSmiTagShift == 1); | 257 ASSERT(kSmiTagShift == 1); |
253 __ add(R1, R2, Operand(R1, LSL, 1)); | 258 __ add(R1, R2, Operand(R1, LSL, 1)); |
254 __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0); | 259 __ StoreIntoObject(R2, FieldAddress(R1, Array::data_offset()), R0); |
255 const int32_t raw_null = reinterpret_cast<int32_t>(Object::null()); | 260 const int32_t raw_null = reinterpret_cast<int32_t>(Object::null()); |
256 __ LoadImmediate(R0, raw_null); | 261 __ LoadImmediate(R0, raw_null); |
257 __ Ret(); | 262 __ Ret(); |
258 __ Bind(&fall_through); | 263 __ Bind(&fall_through); |
259 } | 264 } |
260 | 265 |
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1732 __ eor(R0, R0, Operand(R0, LSR, 11)); | 1737 __ eor(R0, R0, Operand(R0, LSR, 11)); |
1733 __ add(R0, R0, Operand(R0, LSL, 15)); | 1738 __ add(R0, R0, Operand(R0, LSL, 15)); |
1734 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); | 1739 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); |
1735 __ LoadImmediate(R2, (static_cast<intptr_t>(1) << String::kHashBits) - 1); | 1740 __ LoadImmediate(R2, (static_cast<intptr_t>(1) << String::kHashBits) - 1); |
1736 __ and_(R0, R0, Operand(R2)); | 1741 __ and_(R0, R0, Operand(R2)); |
1737 __ cmp(R0, Operand(0)); | 1742 __ cmp(R0, Operand(0)); |
1738 // return hash_ == 0 ? 1 : hash_; | 1743 // return hash_ == 0 ? 1 : hash_; |
1739 __ Bind(&done); | 1744 __ Bind(&done); |
1740 __ mov(R0, Operand(1), EQ); | 1745 __ mov(R0, Operand(1), EQ); |
1741 __ SmiTag(R0); | 1746 __ SmiTag(R0); |
1742 __ str(R0, FieldAddress(R1, String::hash_offset())); | 1747 __ StoreIntoSmiField(FieldAddress(R1, String::hash_offset()), R0); |
1743 __ Ret(); | 1748 __ Ret(); |
1744 } | 1749 } |
1745 | 1750 |
1746 | 1751 |
1747 // Allocates one-byte string of length 'end - start'. The content is not | 1752 // Allocates one-byte string of length 'end - start'. The content is not |
1748 // initialized. | 1753 // initialized. |
1749 // 'length-reg' (R2) contains tagged length. | 1754 // 'length-reg' (R2) contains tagged length. |
1750 // Returns new string as tagged pointer in R0. | 1755 // Returns new string as tagged pointer in R0. |
1751 static void TryAllocateOnebyteString(Assembler* assembler, | 1756 static void TryAllocateOnebyteString(Assembler* assembler, |
1752 Label* ok, | 1757 Label* ok, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 __ orr(R3, R3, Operand(TMP)); | 1810 __ orr(R3, R3, Operand(TMP)); |
1806 __ str(R3, FieldAddress(R0, String::tags_offset())); // Store tags. | 1811 __ str(R3, FieldAddress(R0, String::tags_offset())); // Store tags. |
1807 } | 1812 } |
1808 | 1813 |
1809 // Set the length field using the saved length (R6). | 1814 // Set the length field using the saved length (R6). |
1810 __ StoreIntoObjectNoBarrier(R0, | 1815 __ StoreIntoObjectNoBarrier(R0, |
1811 FieldAddress(R0, String::length_offset()), | 1816 FieldAddress(R0, String::length_offset()), |
1812 R6); | 1817 R6); |
1813 // Clear hash. | 1818 // Clear hash. |
1814 __ LoadImmediate(TMP, 0); | 1819 __ LoadImmediate(TMP, 0); |
1815 __ str(TMP, FieldAddress(R0, String::hash_offset())); | 1820 __ StoreIntoSmiField(FieldAddress(R0, String::hash_offset()), TMP); |
1816 | 1821 |
1817 __ IncrementAllocationStatsWithSize(R4, R2, cid, space); | 1822 __ IncrementAllocationStatsWithSize(R4, R2, cid, space); |
1818 __ b(ok); | 1823 __ b(ok); |
1819 | 1824 |
1820 __ Bind(&fail); | 1825 __ Bind(&fail); |
1821 __ b(failure); | 1826 __ b(failure); |
1822 } | 1827 } |
1823 | 1828 |
1824 | 1829 |
1825 // Arg0: OneByteString (receiver). | 1830 // Arg0: OneByteString (receiver). |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2049 Isolate* isolate = Isolate::Current(); | 2054 Isolate* isolate = Isolate::Current(); |
2050 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); | 2055 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); |
2051 // Set return value to Isolate::current_tag_. | 2056 // Set return value to Isolate::current_tag_. |
2052 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 2057 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
2053 __ Ret(); | 2058 __ Ret(); |
2054 } | 2059 } |
2055 | 2060 |
2056 } // namespace dart | 2061 } // namespace dart |
2057 | 2062 |
2058 #endif // defined TARGET_ARCH_ARM | 2063 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |