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 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 // Finally, tag the result. | 1028 // Finally, tag the result. |
1029 SmiTag(result); | 1029 SmiTag(result); |
1030 } | 1030 } |
1031 | 1031 |
1032 | 1032 |
1033 // Frame entry and exit. | 1033 // Frame entry and exit. |
1034 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { | 1034 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) { |
1035 // Reserve space for arguments and align frame before entering | 1035 // Reserve space for arguments and align frame before entering |
1036 // the C++ world. | 1036 // the C++ world. |
1037 if (frame_space != 0) { | 1037 if (frame_space != 0) { |
1038 AddImmediate(SP, SP, -frame_space); | 1038 AddImmediate(SP, -frame_space); |
1039 } | 1039 } |
1040 if (OS::ActivationFrameAlignment() > 1) { | 1040 if (OS::ActivationFrameAlignment() > 1) { |
1041 andi(SP, SP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 1041 andi(SP, SP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
1042 } | 1042 } |
1043 } | 1043 } |
1044 | 1044 |
1045 | 1045 |
1046 void Assembler::RestoreCodePointer() { | 1046 void Assembler::RestoreCodePointer() { |
1047 ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize)); | 1047 ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize)); |
1048 CheckCodePointer(); | 1048 CheckCodePointer(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 // Load the pool pointer. | 1126 // Load the pool pointer. |
1127 if (new_pp == kNoRegister) { | 1127 if (new_pp == kNoRegister) { |
1128 LoadPoolPointer(); | 1128 LoadPoolPointer(); |
1129 } else { | 1129 } else { |
1130 mov(PP, new_pp); | 1130 mov(PP, new_pp); |
1131 set_constant_pool_allowed(true); | 1131 set_constant_pool_allowed(true); |
1132 } | 1132 } |
1133 | 1133 |
1134 // Reserve space. | 1134 // Reserve space. |
1135 if (frame_size > 0) { | 1135 if (frame_size > 0) { |
1136 AddImmediate(SP, SP, -frame_size); | 1136 AddImmediate(SP, -frame_size); |
1137 } | 1137 } |
1138 } | 1138 } |
1139 | 1139 |
1140 | 1140 |
1141 // On entry to a function compiled for OSR, the caller's frame pointer, the | 1141 // On entry to a function compiled for OSR, the caller's frame pointer, the |
1142 // stack locals, and any copied parameters are already in place. The frame | 1142 // stack locals, and any copied parameters are already in place. The frame |
1143 // pointer is already set up. The PC marker is not correct for the | 1143 // pointer is already set up. The PC marker is not correct for the |
1144 // optimized function and there may be extra space for spill slots to | 1144 // optimized function and there may be extra space for spill slots to |
1145 // allocate. We must also set up the pool pointer for the function. | 1145 // allocate. We must also set up the pool pointer for the function. |
1146 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { | 1146 void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) { |
1147 ASSERT(!constant_pool_allowed()); | 1147 ASSERT(!constant_pool_allowed()); |
1148 Comment("EnterOsrFrame"); | 1148 Comment("EnterOsrFrame"); |
1149 RestoreCodePointer(); | 1149 RestoreCodePointer(); |
1150 LoadPoolPointer(); | 1150 LoadPoolPointer(); |
1151 | 1151 |
1152 if (extra_size > 0) { | 1152 if (extra_size > 0) { |
1153 AddImmediate(SP, SP, -extra_size); | 1153 AddImmediate(SP, -extra_size); |
1154 } | 1154 } |
1155 } | 1155 } |
1156 | 1156 |
1157 | 1157 |
1158 void Assembler::LeaveDartFrame(RestorePP restore_pp) { | 1158 void Assembler::LeaveDartFrame(RestorePP restore_pp) { |
1159 if (restore_pp == kRestoreCallerPP) { | 1159 if (restore_pp == kRestoreCallerPP) { |
1160 set_constant_pool_allowed(false); | 1160 set_constant_pool_allowed(false); |
1161 // Restore and untag PP. | 1161 // Restore and untag PP. |
1162 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); | 1162 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize); |
1163 sub(PP, PP, Operand(kHeapObjectTag)); | 1163 sub(PP, PP, Operand(kHeapObjectTag)); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 #ifndef PRODUCT | 1275 #ifndef PRODUCT |
1276 void Assembler::MaybeTraceAllocation(intptr_t cid, | 1276 void Assembler::MaybeTraceAllocation(intptr_t cid, |
1277 Register temp_reg, | 1277 Register temp_reg, |
1278 Label* trace) { | 1278 Label* trace) { |
1279 ASSERT(cid > 0); | 1279 ASSERT(cid > 0); |
1280 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 1280 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
1281 LoadIsolate(temp_reg); | 1281 LoadIsolate(temp_reg); |
1282 intptr_t table_offset = | 1282 intptr_t table_offset = |
1283 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 1283 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
1284 ldr(temp_reg, Address(temp_reg, table_offset)); | 1284 ldr(temp_reg, Address(temp_reg, table_offset)); |
1285 AddImmediate(temp_reg, temp_reg, state_offset); | 1285 AddImmediate(temp_reg, state_offset); |
1286 ldr(temp_reg, Address(temp_reg, 0)); | 1286 ldr(temp_reg, Address(temp_reg, 0)); |
1287 tsti(temp_reg, Immediate(ClassHeapStats::TraceAllocationMask())); | 1287 tsti(temp_reg, Immediate(ClassHeapStats::TraceAllocationMask())); |
1288 b(trace, NE); | 1288 b(trace, NE); |
1289 } | 1289 } |
1290 | 1290 |
1291 | 1291 |
1292 void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) { | 1292 void Assembler::UpdateAllocationStats(intptr_t cid, Heap::Space space) { |
1293 ASSERT(cid > 0); | 1293 ASSERT(cid > 0); |
1294 intptr_t counter_offset = | 1294 intptr_t counter_offset = |
1295 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); | 1295 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); |
1296 LoadIsolate(TMP2); | 1296 LoadIsolate(TMP2); |
1297 intptr_t table_offset = | 1297 intptr_t table_offset = |
1298 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 1298 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
1299 ldr(TMP, Address(TMP2, table_offset)); | 1299 ldr(TMP, Address(TMP2, table_offset)); |
1300 AddImmediate(TMP2, TMP, counter_offset); | 1300 AddImmediate(TMP2, TMP, counter_offset); |
1301 ldr(TMP, Address(TMP2, 0)); | 1301 ldr(TMP, Address(TMP2, 0)); |
1302 AddImmediate(TMP, TMP, 1); | 1302 AddImmediate(TMP, 1); |
1303 str(TMP, Address(TMP2, 0)); | 1303 str(TMP, Address(TMP2, 0)); |
1304 } | 1304 } |
1305 | 1305 |
1306 | 1306 |
1307 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, | 1307 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
1308 Register size_reg, | 1308 Register size_reg, |
1309 Heap::Space space) { | 1309 Heap::Space space) { |
1310 ASSERT(cid > 0); | 1310 ASSERT(cid > 0); |
1311 const uword class_offset = ClassTable::ClassOffsetFor(cid); | 1311 const uword class_offset = ClassTable::ClassOffsetFor(cid); |
1312 const uword count_field_offset = | 1312 const uword count_field_offset = |
1313 (space == Heap::kNew) | 1313 (space == Heap::kNew) |
1314 ? ClassHeapStats::allocated_since_gc_new_space_offset() | 1314 ? ClassHeapStats::allocated_since_gc_new_space_offset() |
1315 : ClassHeapStats::allocated_since_gc_old_space_offset(); | 1315 : ClassHeapStats::allocated_since_gc_old_space_offset(); |
1316 const uword size_field_offset = | 1316 const uword size_field_offset = |
1317 (space == Heap::kNew) | 1317 (space == Heap::kNew) |
1318 ? ClassHeapStats::allocated_size_since_gc_new_space_offset() | 1318 ? ClassHeapStats::allocated_size_since_gc_new_space_offset() |
1319 : ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 1319 : ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
1320 LoadIsolate(TMP2); | 1320 LoadIsolate(TMP2); |
1321 intptr_t table_offset = | 1321 intptr_t table_offset = |
1322 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); | 1322 Isolate::class_table_offset() + ClassTable::TableOffsetFor(cid); |
1323 ldr(TMP, Address(TMP2, table_offset)); | 1323 ldr(TMP, Address(TMP2, table_offset)); |
1324 AddImmediate(TMP2, TMP, class_offset); | 1324 AddImmediate(TMP2, TMP, class_offset); |
1325 ldr(TMP, Address(TMP2, count_field_offset)); | 1325 ldr(TMP, Address(TMP2, count_field_offset)); |
1326 AddImmediate(TMP, TMP, 1); | 1326 AddImmediate(TMP, 1); |
1327 str(TMP, Address(TMP2, count_field_offset)); | 1327 str(TMP, Address(TMP2, count_field_offset)); |
1328 ldr(TMP, Address(TMP2, size_field_offset)); | 1328 ldr(TMP, Address(TMP2, size_field_offset)); |
1329 add(TMP, TMP, Operand(size_reg)); | 1329 add(TMP, TMP, Operand(size_reg)); |
1330 str(TMP, Address(TMP2, size_field_offset)); | 1330 str(TMP, Address(TMP2, size_field_offset)); |
1331 } | 1331 } |
1332 #endif // !PRODUCT | 1332 #endif // !PRODUCT |
1333 | 1333 |
1334 | 1334 |
1335 void Assembler::TryAllocate(const Class& cls, | 1335 void Assembler::TryAllocate(const Class& cls, |
1336 Label* failure, | 1336 Label* failure, |
(...skipping 16 matching lines...) Expand all Loading... |
1353 ldr(TMP, Address(temp_reg, Heap::EndOffset(space))); | 1353 ldr(TMP, Address(temp_reg, Heap::EndOffset(space))); |
1354 CompareRegisters(TMP, instance_reg); | 1354 CompareRegisters(TMP, instance_reg); |
1355 // fail if heap end unsigned less than or equal to instance_reg. | 1355 // fail if heap end unsigned less than or equal to instance_reg. |
1356 b(failure, LS); | 1356 b(failure, LS); |
1357 | 1357 |
1358 // Successfully allocated the object, now update top to point to | 1358 // Successfully allocated the object, now update top to point to |
1359 // next object start and store the class in the class field of object. | 1359 // next object start and store the class in the class field of object. |
1360 str(instance_reg, Address(temp_reg, Heap::TopOffset(space))); | 1360 str(instance_reg, Address(temp_reg, Heap::TopOffset(space))); |
1361 | 1361 |
1362 ASSERT(instance_size >= kHeapObjectTag); | 1362 ASSERT(instance_size >= kHeapObjectTag); |
1363 AddImmediate(instance_reg, instance_reg, -instance_size + kHeapObjectTag); | 1363 AddImmediate(instance_reg, -instance_size + kHeapObjectTag); |
1364 NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), space)); | 1364 NOT_IN_PRODUCT(UpdateAllocationStats(cls.id(), space)); |
1365 | 1365 |
1366 uword tags = 0; | 1366 uword tags = 0; |
1367 tags = RawObject::SizeTag::update(instance_size, tags); | 1367 tags = RawObject::SizeTag::update(instance_size, tags); |
1368 ASSERT(cls.id() != kIllegalCid); | 1368 ASSERT(cls.id() != kIllegalCid); |
1369 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1369 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1370 LoadImmediate(TMP, tags); | 1370 LoadImmediate(TMP, tags); |
1371 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset()); | 1371 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset()); |
1372 } else { | 1372 } else { |
1373 b(failure); | 1373 b(failure); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); | 1489 is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag); |
1490 if (shift == 0) { | 1490 if (shift == 0) { |
1491 add(address, array, Operand(index)); | 1491 add(address, array, Operand(index)); |
1492 } else if (shift < 0) { | 1492 } else if (shift < 0) { |
1493 ASSERT(shift == -1); | 1493 ASSERT(shift == -1); |
1494 add(address, array, Operand(index, ASR, 1)); | 1494 add(address, array, Operand(index, ASR, 1)); |
1495 } else { | 1495 } else { |
1496 add(address, array, Operand(index, LSL, shift)); | 1496 add(address, array, Operand(index, LSL, shift)); |
1497 } | 1497 } |
1498 if (offset != 0) { | 1498 if (offset != 0) { |
1499 AddImmediate(address, address, offset); | 1499 AddImmediate(address, offset); |
1500 } | 1500 } |
1501 } | 1501 } |
1502 | 1502 |
1503 | 1503 |
1504 void Assembler::LoadUnaligned(Register dst, | 1504 void Assembler::LoadUnaligned(Register dst, |
1505 Register addr, | 1505 Register addr, |
1506 Register tmp, | 1506 Register tmp, |
1507 OperandSize sz) { | 1507 OperandSize sz) { |
1508 ASSERT(dst != addr); | 1508 ASSERT(dst != addr); |
1509 ldr(dst, Address(addr, 0), kUnsignedByte); | 1509 ldr(dst, Address(addr, 0), kUnsignedByte); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 str(tmp, Address(addr, 7), kUnsignedByte); | 1571 str(tmp, Address(addr, 7), kUnsignedByte); |
1572 if (sz == kDoubleWord) { | 1572 if (sz == kDoubleWord) { |
1573 return; | 1573 return; |
1574 } | 1574 } |
1575 UNIMPLEMENTED(); | 1575 UNIMPLEMENTED(); |
1576 } | 1576 } |
1577 | 1577 |
1578 } // namespace dart | 1578 } // namespace dart |
1579 | 1579 |
1580 #endif // defined TARGET_ARCH_ARM64 | 1580 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |