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