| 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 __ InitializeFieldNoBarrier( | 135 __ InitializeFieldNoBarrier( |
| 136 R0, | 136 R0, |
| 137 FieldAddress(R0, GrowableObjectArray::length_offset()), | 137 FieldAddress(R0, GrowableObjectArray::length_offset()), |
| 138 R1); | 138 R1); |
| 139 __ Ret(); // Returns the newly allocated object in R0. | 139 __ Ret(); // Returns the newly allocated object in R0. |
| 140 | 140 |
| 141 __ Bind(&fall_through); | 141 __ Bind(&fall_through); |
| 142 } | 142 } |
| 143 | 143 |
| 144 | 144 |
| 145 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | |
| 146 Label fall_through; | |
| 147 | |
| 148 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index | |
| 149 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array | |
| 150 | |
| 151 __ tst(R0, Operand(kSmiTagMask)); | |
| 152 __ b(&fall_through, NE); // Index is not an smi, fall through | |
| 153 | |
| 154 // Range check. | |
| 155 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::length_offset())); | |
| 156 __ cmp(R0, Operand(R6)); | |
| 157 | |
| 158 ASSERT(kSmiTagShift == 1); | |
| 159 // array element at R6 + R0 * 2 + Array::data_offset - 1 | |
| 160 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::data_offset()), CC); // data | |
| 161 __ add(R6, R6, Operand(R0, LSL, 1), CC); | |
| 162 __ ldr(R0, FieldAddress(R6, Array::data_offset()), CC); | |
| 163 __ bx(LR, CC); | |
| 164 __ Bind(&fall_through); | |
| 165 } | |
| 166 | |
| 167 | |
| 168 // Set value into growable object array at specified index. | |
| 169 // On stack: growable array (+2), index (+1), value (+0). | |
| 170 void Intrinsifier::GrowableArraySetIndexed(Assembler* assembler) { | |
| 171 if (FLAG_enable_type_checks) { | |
| 172 return; | |
| 173 } | |
| 174 Label fall_through; | |
| 175 __ ldr(R1, Address(SP, 1 * kWordSize)); // Index. | |
| 176 __ ldr(R0, Address(SP, 2 * kWordSize)); // GrowableArray. | |
| 177 __ tst(R1, Operand(kSmiTagMask)); | |
| 178 __ b(&fall_through, NE); // Non-smi index. | |
| 179 // Range check using _length field. | |
| 180 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::length_offset())); | |
| 181 __ cmp(R1, Operand(R2)); | |
| 182 // Runtime throws exception. | |
| 183 __ b(&fall_through, CS); | |
| 184 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset())); // data. | |
| 185 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. | |
| 186 // Note that R1 is Smi, i.e, times 2. | |
| 187 ASSERT(kSmiTagShift == 1); | |
| 188 __ add(R1, R0, Operand(R1, LSL, 1)); | |
| 189 __ StoreIntoObject(R0, FieldAddress(R1, Array::data_offset()), R2); | |
| 190 __ Ret(); | |
| 191 __ Bind(&fall_through); | |
| 192 } | |
| 193 | |
| 194 | |
| 195 // Set length of growable object array. The length cannot | |
| 196 // be greater than the length of the data container. | |
| 197 // On stack: growable array (+1), length (+0). | |
| 198 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { | |
| 199 Label fall_through; | |
| 200 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. | |
| 201 __ ldr(R1, Address(SP, 0 * kWordSize)); // Length value. | |
| 202 __ tst(R1, Operand(kSmiTagMask)); | |
| 203 __ b(&fall_through, NE); // Non-smi length. | |
| 204 __ StoreIntoSmiField(FieldAddress(R0, GrowableObjectArray::length_offset()), | |
| 205 R1); | |
| 206 __ Ret(); | |
| 207 __ Bind(&fall_through); | |
| 208 } | |
| 209 | |
| 210 | |
| 211 // Set data of growable object array. | |
| 212 // On stack: growable array (+1), data (+0). | |
| 213 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { | |
| 214 if (FLAG_enable_type_checks) { | |
| 215 return; | |
| 216 } | |
| 217 Label fall_through; | |
| 218 __ ldr(R1, Address(SP, 0 * kWordSize)); // Data. | |
| 219 // Check that data is an ObjectArray. | |
| 220 __ tst(R1, Operand(kSmiTagMask)); | |
| 221 __ b(&fall_through, EQ); // Data is Smi. | |
| 222 __ CompareClassId(R1, kArrayCid, R0); | |
| 223 __ b(&fall_through, NE); | |
| 224 __ ldr(R0, Address(SP, 1 * kWordSize)); // Growable array. | |
| 225 __ StoreIntoObject(R0, | |
| 226 FieldAddress(R0, GrowableObjectArray::data_offset()), | |
| 227 R1); | |
| 228 __ Ret(); | |
| 229 __ Bind(&fall_through); | |
| 230 } | |
| 231 | |
| 232 | |
| 233 // Add an element to growable array if it doesn't need to grow, otherwise | 145 // Add an element to growable array if it doesn't need to grow, otherwise |
| 234 // call into regular code. | 146 // call into regular code. |
| 235 // On stack: growable array (+1), value (+0). | 147 // On stack: growable array (+1), value (+0). |
| 236 void Intrinsifier::GrowableArray_add(Assembler* assembler) { | 148 void Intrinsifier::GrowableArray_add(Assembler* assembler) { |
| 237 // In checked mode we need to type-check the incoming argument. | 149 // In checked mode we need to type-check the incoming argument. |
| 238 if (FLAG_enable_type_checks) { | 150 if (FLAG_enable_type_checks) { |
| 239 return; | 151 return; |
| 240 } | 152 } |
| 241 Label fall_through; | 153 Label fall_through; |
| 242 // R0: Array. | 154 // R0: Array. |
| (...skipping 1819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2062 Isolate* isolate = Isolate::Current(); | 1974 Isolate* isolate = Isolate::Current(); |
| 2063 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); | 1975 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate)); |
| 2064 // Set return value to Isolate::current_tag_. | 1976 // Set return value to Isolate::current_tag_. |
| 2065 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 1977 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
| 2066 __ Ret(); | 1978 __ Ret(); |
| 2067 } | 1979 } |
| 2068 | 1980 |
| 2069 } // namespace dart | 1981 } // namespace dart |
| 2070 | 1982 |
| 2071 #endif // defined TARGET_ARCH_ARM | 1983 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |