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