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" // NOLINT | 5 #include "vm/globals.h" // NOLINT |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 void Assembler::TryAllocate(const Class& cls, | 1324 void Assembler::TryAllocate(const Class& cls, |
1325 Label* failure, | 1325 Label* failure, |
1326 Register instance_reg, | 1326 Register instance_reg, |
1327 Register temp_reg, | 1327 Register temp_reg, |
1328 Register pp) { | 1328 Register pp) { |
1329 ASSERT(failure != NULL); | 1329 ASSERT(failure != NULL); |
1330 if (FLAG_inline_alloc) { | 1330 if (FLAG_inline_alloc) { |
1331 // If this allocation is traced, program will jump to failure path | 1331 // If this allocation is traced, program will jump to failure path |
1332 // (i.e. the allocation stub) which will allocate the object and trace the | 1332 // (i.e. the allocation stub) which will allocate the object and trace the |
1333 // allocation call site. | 1333 // allocation call site. |
1334 MaybeTraceAllocation(cls.id(), temp_reg, pp, failure); | 1334 MaybeTraceAllocation(cls.id(), temp_reg, pp, failure, |
| 1335 /* inline_isolate = */ false); |
1335 const intptr_t instance_size = cls.instance_size(); | 1336 const intptr_t instance_size = cls.instance_size(); |
1336 Heap* heap = Isolate::Current()->heap(); | 1337 Heap::Space space = Heap::SpaceForAllocation(cls.id()); |
1337 Heap::Space space = heap->SpaceForAllocation(cls.id()); | 1338 ldr(temp_reg, Address(THR, Thread::heap_offset())); |
1338 const uword top_address = heap->TopAddress(space); | 1339 ldr(instance_reg, Address(temp_reg, Heap::TopOffset(space))); |
1339 LoadImmediate(temp_reg, top_address, pp); | |
1340 ldr(instance_reg, Address(temp_reg)); | |
1341 // TODO(koda): Protect against unsigned overflow here. | 1340 // TODO(koda): Protect against unsigned overflow here. |
1342 AddImmediateSetFlags(instance_reg, instance_reg, instance_size, pp); | 1341 AddImmediateSetFlags(instance_reg, instance_reg, instance_size, pp); |
1343 | 1342 |
1344 // instance_reg: potential next object start. | 1343 // instance_reg: potential next object start. |
1345 const uword end_address = heap->EndAddress(space); | 1344 ldr(TMP, Address(temp_reg, Heap::EndOffset(space))); |
1346 ASSERT(top_address < end_address); | |
1347 // Could use ldm to load (top, end), but no benefit seen experimentally. | |
1348 ldr(TMP, Address(temp_reg, end_address - top_address)); | |
1349 CompareRegisters(TMP, instance_reg); | 1345 CompareRegisters(TMP, instance_reg); |
1350 // fail if heap end unsigned less than or equal to instance_reg. | 1346 // fail if heap end unsigned less than or equal to instance_reg. |
1351 b(failure, LS); | 1347 b(failure, LS); |
1352 | 1348 |
1353 // Successfully allocated the object, now update top to point to | 1349 // Successfully allocated the object, now update top to point to |
1354 // next object start and store the class in the class field of object. | 1350 // next object start and store the class in the class field of object. |
1355 str(instance_reg, Address(temp_reg)); | 1351 str(instance_reg, Address(temp_reg, Heap::TopOffset(space))); |
1356 | 1352 |
1357 ASSERT(instance_size >= kHeapObjectTag); | 1353 ASSERT(instance_size >= kHeapObjectTag); |
1358 AddImmediate( | 1354 AddImmediate( |
1359 instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp); | 1355 instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp); |
1360 UpdateAllocationStats(cls.id(), pp, space); | 1356 UpdateAllocationStats(cls.id(), pp, space, /* inline_isolate = */ false); |
1361 | 1357 |
1362 uword tags = 0; | 1358 uword tags = 0; |
1363 tags = RawObject::SizeTag::update(instance_size, tags); | 1359 tags = RawObject::SizeTag::update(instance_size, tags); |
1364 ASSERT(cls.id() != kIllegalCid); | 1360 ASSERT(cls.id() != kIllegalCid); |
1365 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1361 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1366 LoadImmediate(TMP, tags, pp); | 1362 LoadImmediate(TMP, tags, pp); |
1367 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); | 1363 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); |
1368 } else { | 1364 } else { |
1369 b(failure); | 1365 b(failure); |
1370 } | 1366 } |
1371 } | 1367 } |
1372 | 1368 |
1373 | 1369 |
1374 void Assembler::TryAllocateArray(intptr_t cid, | 1370 void Assembler::TryAllocateArray(intptr_t cid, |
1375 intptr_t instance_size, | 1371 intptr_t instance_size, |
1376 Label* failure, | 1372 Label* failure, |
1377 Register instance, | 1373 Register instance, |
1378 Register end_address, | 1374 Register end_address, |
1379 Register temp1, | 1375 Register temp1, |
1380 Register temp2) { | 1376 Register temp2) { |
1381 if (FLAG_inline_alloc) { | 1377 if (FLAG_inline_alloc) { |
1382 // If this allocation is traced, program will jump to failure path | 1378 // If this allocation is traced, program will jump to failure path |
1383 // (i.e. the allocation stub) which will allocate the object and trace the | 1379 // (i.e. the allocation stub) which will allocate the object and trace the |
1384 // allocation call site. | 1380 // allocation call site. |
1385 MaybeTraceAllocation(cid, temp1, PP, failure); | 1381 MaybeTraceAllocation(cid, temp1, PP, failure, /* inline_isolate = */ false); |
1386 Isolate* isolate = Isolate::Current(); | 1382 Heap::Space space = Heap::SpaceForAllocation(cid); |
1387 Heap* heap = isolate->heap(); | 1383 ldr(temp1, Address(THR, Thread::heap_offset())); |
1388 Heap::Space space = heap->SpaceForAllocation(cid); | 1384 // Potential new object start. |
1389 LoadImmediate(temp1, heap->TopAddress(space), PP); | 1385 ldr(instance, Address(temp1, Heap::TopOffset(space))); |
1390 ldr(instance, Address(temp1, 0)); // Potential new object start. | |
1391 AddImmediateSetFlags(end_address, instance, instance_size, PP); | 1386 AddImmediateSetFlags(end_address, instance, instance_size, PP); |
1392 b(failure, CS); // Fail on unsigned overflow. | 1387 b(failure, CS); // Fail on unsigned overflow. |
1393 | 1388 |
1394 // Check if the allocation fits into the remaining space. | 1389 // Check if the allocation fits into the remaining space. |
1395 // instance: potential new object start. | 1390 // instance: potential new object start. |
1396 // end_address: potential next object start. | 1391 // end_address: potential next object start. |
1397 LoadImmediate(temp2, heap->EndAddress(space), PP); | 1392 ldr(temp2, Address(temp1, Heap::EndOffset(space))); |
1398 ldr(temp2, Address(temp2, 0)); | |
1399 cmp(end_address, Operand(temp2)); | 1393 cmp(end_address, Operand(temp2)); |
1400 b(failure, CS); | 1394 b(failure, CS); |
1401 | 1395 |
1402 // Successfully allocated the object(s), now update top to point to | 1396 // Successfully allocated the object(s), now update top to point to |
1403 // next object start and initialize the object. | 1397 // next object start and initialize the object. |
1404 str(end_address, Address(temp1, 0)); | 1398 str(end_address, Address(temp1, Heap::TopOffset(space))); |
1405 add(instance, instance, Operand(kHeapObjectTag)); | 1399 add(instance, instance, Operand(kHeapObjectTag)); |
1406 LoadImmediate(temp2, instance_size, PP); | 1400 LoadImmediate(temp2, instance_size, PP); |
1407 UpdateAllocationStatsWithSize(cid, temp2, PP, space); | 1401 UpdateAllocationStatsWithSize(cid, temp2, PP, space, |
| 1402 /* inline_isolate = */ false); |
1408 | 1403 |
1409 // Initialize the tags. | 1404 // Initialize the tags. |
1410 // instance: new object start as a tagged pointer. | 1405 // instance: new object start as a tagged pointer. |
1411 uword tags = 0; | 1406 uword tags = 0; |
1412 tags = RawObject::ClassIdTag::update(cid, tags); | 1407 tags = RawObject::ClassIdTag::update(cid, tags); |
1413 tags = RawObject::SizeTag::update(instance_size, tags); | 1408 tags = RawObject::SizeTag::update(instance_size, tags); |
1414 LoadImmediate(temp2, tags, PP); | 1409 LoadImmediate(temp2, tags, PP); |
1415 str(temp2, FieldAddress(instance, Array::tags_offset())); // Store tags. | 1410 str(temp2, FieldAddress(instance, Array::tags_offset())); // Store tags. |
1416 } else { | 1411 } else { |
1417 b(failure); | 1412 b(failure); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 add(base, array, Operand(index, LSL, shift)); | 1450 add(base, array, Operand(index, LSL, shift)); |
1456 } | 1451 } |
1457 const OperandSize size = Address::OperandSizeFor(cid); | 1452 const OperandSize size = Address::OperandSizeFor(cid); |
1458 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1453 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1459 return Address(base, offset, Address::Offset, size); | 1454 return Address(base, offset, Address::Offset, size); |
1460 } | 1455 } |
1461 | 1456 |
1462 } // namespace dart | 1457 } // namespace dart |
1463 | 1458 |
1464 #endif // defined TARGET_ARCH_ARM64 | 1459 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |