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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 __ SmiUntag(R2); \ | 290 __ SmiUntag(R2); \ |
291 /* Check for maximum allowed length. */ \ | 291 /* Check for maximum allowed length. */ \ |
292 /* R2: untagged array length. */ \ | 292 /* R2: untagged array length. */ \ |
293 __ CompareImmediate(R2, max_len, kNoPP); \ | 293 __ CompareImmediate(R2, max_len, kNoPP); \ |
294 __ b(&fall_through, GT); \ | 294 __ b(&fall_through, GT); \ |
295 __ LslImmediate(R2, R2, scale_shift); \ | 295 __ LslImmediate(R2, R2, scale_shift); \ |
296 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ | 296 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ |
297 __ AddImmediate(R2, R2, fixed_size, kNoPP); \ | 297 __ AddImmediate(R2, R2, fixed_size, kNoPP); \ |
298 __ andi(R2, R2, ~(kObjectAlignment - 1)); \ | 298 __ andi(R2, R2, ~(kObjectAlignment - 1)); \ |
299 Heap* heap = Isolate::Current()->heap(); \ | 299 Heap* heap = Isolate::Current()->heap(); \ |
300 \ | 300 Heap::Space space = heap->SpaceForAllocation(cid); \ |
301 __ LoadImmediate(R0, heap->TopAddress(), kNoPP); \ | 301 __ LoadImmediate(R0, heap->TopAddress(space), kNoPP); \ |
302 __ ldr(R0, Address(R0, 0)); \ | 302 __ ldr(R0, Address(R0, 0)); \ |
303 \ | 303 \ |
304 /* R2: allocation size. */ \ | 304 /* R2: allocation size. */ \ |
305 __ add(R1, R0, Operand(R2)); \ | 305 __ add(R1, R0, Operand(R2)); \ |
306 __ b(&fall_through, VS); \ | 306 __ b(&fall_through, VS); \ |
307 \ | 307 \ |
308 /* Check if the allocation fits into the remaining space. */ \ | 308 /* Check if the allocation fits into the remaining space. */ \ |
309 /* R0: potential new object start. */ \ | 309 /* R0: potential new object start. */ \ |
310 /* R1: potential next object start. */ \ | 310 /* R1: potential next object start. */ \ |
311 /* R2: allocation size. */ \ | 311 /* R2: allocation size. */ \ |
312 __ LoadImmediate(R3, heap->EndAddress(), kNoPP); \ | 312 __ LoadImmediate(R3, heap->EndAddress(space), kNoPP); \ |
313 __ ldr(R3, Address(R3, 0)); \ | 313 __ ldr(R3, Address(R3, 0)); \ |
314 __ cmp(R1, Operand(R3)); \ | 314 __ cmp(R1, Operand(R3)); \ |
315 __ b(&fall_through, CS); \ | 315 __ b(&fall_through, CS); \ |
316 \ | 316 \ |
317 /* Successfully allocated the object(s), now update top to point to */ \ | 317 /* Successfully allocated the object(s), now update top to point to */ \ |
318 /* next object start and initialize the object. */ \ | 318 /* next object start and initialize the object. */ \ |
319 __ LoadImmediate(R3, heap->TopAddress(), kNoPP); \ | 319 __ LoadImmediate(R3, heap->TopAddress(space), kNoPP); \ |
320 __ str(R1, Address(R3, 0)); \ | 320 __ str(R1, Address(R3, 0)); \ |
321 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \ | 321 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \ |
322 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP); \ | 322 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space); \ |
323 /* Initialize the tags. */ \ | 323 /* Initialize the tags. */ \ |
324 /* R0: new object start as a tagged pointer. */ \ | 324 /* R0: new object start as a tagged pointer. */ \ |
325 /* R1: new object end address. */ \ | 325 /* R1: new object end address. */ \ |
326 /* R2: allocation size. */ \ | 326 /* R2: allocation size. */ \ |
327 { \ | 327 { \ |
328 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \ | 328 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \ |
329 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \ | 329 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \ |
330 __ csel(R2, ZR, R2, HI); \ | 330 __ csel(R2, ZR, R2, HI); \ |
331 \ | 331 \ |
332 /* Get the class index and insert it into the tags. */ \ | 332 /* Get the class index and insert it into the tags. */ \ |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 Label fail; | 1269 Label fail; |
1270 | 1270 |
1271 __ mov(R6, length_reg); // Save the length register. | 1271 __ mov(R6, length_reg); // Save the length register. |
1272 __ SmiUntag(length_reg); | 1272 __ SmiUntag(length_reg); |
1273 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; | 1273 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; |
1274 __ AddImmediate(length_reg, length_reg, fixed_size, kNoPP); | 1274 __ AddImmediate(length_reg, length_reg, fixed_size, kNoPP); |
1275 __ andi(length_reg, length_reg, ~(kObjectAlignment - 1)); | 1275 __ andi(length_reg, length_reg, ~(kObjectAlignment - 1)); |
1276 | 1276 |
1277 Isolate* isolate = Isolate::Current(); | 1277 Isolate* isolate = Isolate::Current(); |
1278 Heap* heap = isolate->heap(); | 1278 Heap* heap = isolate->heap(); |
1279 | 1279 const intptr_t cid = kOneByteStringCid; |
1280 __ LoadImmediate(R3, heap->TopAddress(), kNoPP); | 1280 Heap::Space space = heap->SpaceForAllocation(cid); |
| 1281 __ LoadImmediate(R3, heap->TopAddress(space), kNoPP); |
1281 __ ldr(R0, Address(R3)); | 1282 __ ldr(R0, Address(R3)); |
1282 | 1283 |
1283 // length_reg: allocation size. | 1284 // length_reg: allocation size. |
1284 __ adds(R1, R0, Operand(length_reg)); | 1285 __ adds(R1, R0, Operand(length_reg)); |
1285 __ b(&fail, VS); // Fail on overflow. | 1286 __ b(&fail, VS); // Fail on overflow. |
1286 | 1287 |
1287 // Check if the allocation fits into the remaining space. | 1288 // Check if the allocation fits into the remaining space. |
1288 // R0: potential new object start. | 1289 // R0: potential new object start. |
1289 // R1: potential next object start. | 1290 // R1: potential next object start. |
1290 // R2: allocation size. | 1291 // R2: allocation size. |
1291 // R3: heap->Top->Address(). | 1292 // R3: heap->TopAddress(space). |
1292 __ LoadImmediate(R7, heap->EndAddress(), kNoPP); | 1293 __ LoadImmediate(R7, heap->EndAddress(space), kNoPP); |
1293 __ ldr(R7, Address(R7)); | 1294 __ ldr(R7, Address(R7)); |
1294 __ cmp(R1, Operand(R7)); | 1295 __ cmp(R1, Operand(R7)); |
1295 __ b(&fail, CS); | 1296 __ b(&fail, CS); |
1296 | 1297 |
1297 // Successfully allocated the object(s), now update top to point to | 1298 // Successfully allocated the object(s), now update top to point to |
1298 // next object start and initialize the object. | 1299 // next object start and initialize the object. |
1299 __ str(R1, Address(R3)); | 1300 __ str(R1, Address(R3)); |
1300 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); | 1301 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); |
1301 __ UpdateAllocationStatsWithSize(kOneByteStringCid, R2, kNoPP); | 1302 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP, space); |
1302 | 1303 |
1303 // Initialize the tags. | 1304 // Initialize the tags. |
1304 // R0: new object start as a tagged pointer. | 1305 // R0: new object start as a tagged pointer. |
1305 // R1: new object end address. | 1306 // R1: new object end address. |
1306 // R2: allocation size. | 1307 // R2: allocation size. |
1307 { | 1308 { |
1308 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; | 1309 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; |
1309 const Class& cls = | |
1310 Class::Handle(isolate->object_store()->one_byte_string_class()); | |
1311 | 1310 |
1312 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); | 1311 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); |
1313 __ LslImmediate(R2, R2, shift); | 1312 __ LslImmediate(R2, R2, shift); |
1314 __ csel(R2, R2, ZR, LS); | 1313 __ csel(R2, R2, ZR, LS); |
1315 | 1314 |
1316 // Get the class index and insert it into the tags. | 1315 // Get the class index and insert it into the tags. |
1317 // R2: size and bit tags. | 1316 // R2: size and bit tags. |
1318 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id()), kNoPP); | 1317 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid), kNoPP); |
1319 __ orr(R2, R2, Operand(TMP)); | 1318 __ orr(R2, R2, Operand(TMP)); |
1320 __ str(R2, FieldAddress(R0, String::tags_offset())); // Store tags. | 1319 __ str(R2, FieldAddress(R0, String::tags_offset())); // Store tags. |
1321 } | 1320 } |
1322 | 1321 |
1323 // Set the length field using the saved length (R6). | 1322 // Set the length field using the saved length (R6). |
1324 __ StoreIntoObjectNoBarrier(R0, | 1323 __ StoreIntoObjectNoBarrier(R0, |
1325 FieldAddress(R0, String::length_offset()), | 1324 FieldAddress(R0, String::length_offset()), |
1326 R6); | 1325 R6); |
1327 // Clear hash. | 1326 // Clear hash. |
1328 __ mov(TMP, ZR); | 1327 __ mov(TMP, ZR); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 Isolate* isolate = Isolate::Current(); | 1527 Isolate* isolate = Isolate::Current(); |
1529 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); | 1528 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); |
1530 // Set return value to Isolate::current_tag_. | 1529 // Set return value to Isolate::current_tag_. |
1531 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); | 1530 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); |
1532 __ ret(); | 1531 __ ret(); |
1533 } | 1532 } |
1534 | 1533 |
1535 } // namespace dart | 1534 } // namespace dart |
1536 | 1535 |
1537 #endif // defined TARGET_ARCH_ARM64 | 1536 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |