Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: runtime/vm/assembler_arm64.cc

Issue 1263513002: VM: Load allocation-top and -end via Thread. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: arm, arm64 and mips Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698