| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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, kNoPP); | 134 __ LoadImmediate(R1, 0, kNoPP); |
| 135 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); | 135 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); |
| 136 __ ret(); // Returns the newly allocated object in R0. | 136 __ ret(); // Returns the newly allocated object in R0. |
| 137 | 137 |
| 138 __ Bind(&fall_through); | 138 __ Bind(&fall_through); |
| 139 } | 139 } |
| 140 | 140 |
| 141 | 141 |
| 142 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | |
| 143 Label fall_through; | |
| 144 | |
| 145 __ ldr(R0, Address(SP, + 0 * kWordSize)); // Index | |
| 146 __ ldr(R1, Address(SP, + 1 * kWordSize)); // Array | |
| 147 | |
| 148 __ tsti(R0, Immediate(kSmiTagMask)); | |
| 149 __ b(&fall_through, NE); // Index is not an smi, fall through. | |
| 150 | |
| 151 // Range check. | |
| 152 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::length_offset())); | |
| 153 __ cmp(R0, Operand(R6)); | |
| 154 __ b(&fall_through, CS); | |
| 155 | |
| 156 ASSERT(kSmiTagShift == 1); | |
| 157 // array element at R6 + R0 * 4 + Array::data_offset - 1 | |
| 158 __ ldr(R6, FieldAddress(R1, GrowableObjectArray::data_offset())); // Data | |
| 159 __ add(R6, R6, Operand(R0, LSL, 2)); | |
| 160 __ ldr(R0, FieldAddress(R6, Array::data_offset())); | |
| 161 __ ret(); | |
| 162 __ Bind(&fall_through); | |
| 163 } | |
| 164 | |
| 165 | |
| 166 // Set value into growable object array at specified index. | |
| 167 // On stack: growable array (+2), index (+1), value (+0). | |
| 168 void Intrinsifier::GrowableArraySetIndexed(Assembler* assembler) { | |
| 169 if (FLAG_enable_type_checks) { | |
| 170 return; | |
| 171 } | |
| 172 Label fall_through; | |
| 173 __ ldr(R1, Address(SP, 1 * kWordSize)); // Index. | |
| 174 __ ldr(R0, Address(SP, 2 * kWordSize)); // GrowableArray. | |
| 175 __ tsti(R1, Immediate(kSmiTagMask)); | |
| 176 __ b(&fall_through, NE); // Non-smi index. | |
| 177 // Range check using _length field. | |
| 178 __ ldr(R2, FieldAddress(R0, GrowableObjectArray::length_offset())); | |
| 179 __ cmp(R1, Operand(R2)); | |
| 180 // Runtime throws exception. | |
| 181 __ b(&fall_through, CS); | |
| 182 __ ldr(R0, FieldAddress(R0, GrowableObjectArray::data_offset())); // data. | |
| 183 __ ldr(R2, Address(SP, 0 * kWordSize)); // Value. | |
| 184 // Note that R1 is Smi, i.e, times 2. | |
| 185 ASSERT(kSmiTagShift == 1); | |
| 186 __ add(R1, R0, Operand(R1, LSL, 2)); | |
| 187 __ StoreIntoObject(R0, | |
| 188 FieldAddress(R1, Array::data_offset()), | |
| 189 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 __ tsti(R1, Immediate(kSmiTagMask)); // Check for Smi. | |
| 203 __ b(&fall_through, NE); | |
| 204 __ str(R1, FieldAddress(R0, GrowableObjectArray::length_offset())); | |
| 205 __ ret(); | |
| 206 __ Bind(&fall_through); | |
| 207 // Fall through on non-Smi. | |
| 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 __ tsti(R1, Immediate(kSmiTagMask)); | |
| 221 __ b(&fall_through, EQ); // Data is Smi. | |
| 222 __ CompareClassId(R1, kArrayCid, kNoPP); | |
| 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 | 142 // Add an element to growable array if it doesn't need to grow, otherwise |
| 234 // call into regular code. | 143 // call into regular code. |
| 235 // On stack: growable array (+1), value (+0). | 144 // On stack: growable array (+1), value (+0). |
| 236 void Intrinsifier::GrowableArray_add(Assembler* assembler) { | 145 void Intrinsifier::GrowableArray_add(Assembler* assembler) { |
| 237 // In checked mode we need to type-check the incoming argument. | 146 // In checked mode we need to type-check the incoming argument. |
| 238 if (FLAG_enable_type_checks) { | 147 if (FLAG_enable_type_checks) { |
| 239 return; | 148 return; |
| 240 } | 149 } |
| 241 Label fall_through; | 150 Label fall_through; |
| 242 // R0: Array. | 151 // R0: Array. |
| (...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2117 Isolate* isolate = Isolate::Current(); | 2026 Isolate* isolate = Isolate::Current(); |
| 2118 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); | 2027 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); |
| 2119 // Set return value to Isolate::current_tag_. | 2028 // Set return value to Isolate::current_tag_. |
| 2120 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 2029 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
| 2121 __ ret(); | 2030 __ ret(); |
| 2122 } | 2031 } |
| 2123 | 2032 |
| 2124 } // namespace dart | 2033 } // namespace dart |
| 2125 | 2034 |
| 2126 #endif // defined TARGET_ARCH_ARM64 | 2035 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |