| 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" | 5 #include "vm/globals.h" |
| 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 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 | 1220 |
| 1221 void Assembler::LeaveStubFrame() { | 1221 void Assembler::LeaveStubFrame() { |
| 1222 // Restore and untag PP. | 1222 // Restore and untag PP. |
| 1223 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize, kNoPP); | 1223 LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize, kNoPP); |
| 1224 sub(PP, PP, Operand(kHeapObjectTag)); | 1224 sub(PP, PP, Operand(kHeapObjectTag)); |
| 1225 LeaveFrame(); | 1225 LeaveFrame(); |
| 1226 } | 1226 } |
| 1227 | 1227 |
| 1228 | 1228 |
| 1229 void Assembler::UpdateAllocationStats(intptr_t cid, | 1229 void Assembler::UpdateAllocationStats(intptr_t cid, |
| 1230 Register temp_reg, | |
| 1231 Register pp, | 1230 Register pp, |
| 1232 Heap::Space space) { | 1231 Heap::Space space) { |
| 1233 ASSERT(temp_reg != kNoRegister); | |
| 1234 ASSERT(temp_reg != TMP); | |
| 1235 ASSERT(cid > 0); | 1232 ASSERT(cid > 0); |
| 1236 Isolate* isolate = Isolate::Current(); | 1233 Isolate* isolate = Isolate::Current(); |
| 1237 ClassTable* class_table = isolate->class_table(); | 1234 ClassTable* class_table = isolate->class_table(); |
| 1238 if (cid < kNumPredefinedCids) { | 1235 if (cid < kNumPredefinedCids) { |
| 1239 const uword class_heap_stats_table_address = | 1236 const uword class_heap_stats_table_address = |
| 1240 class_table->PredefinedClassHeapStatsTableAddress(); | 1237 class_table->PredefinedClassHeapStatsTableAddress(); |
| 1241 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 1238 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 1242 const uword count_field_offset = (space == Heap::kNew) ? | 1239 const uword count_field_offset = (space == Heap::kNew) ? |
| 1243 ClassHeapStats::allocated_since_gc_new_space_offset() : | 1240 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 1244 ClassHeapStats::allocated_since_gc_old_space_offset(); | 1241 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 1245 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset, pp); | 1242 LoadImmediate(TMP2, class_heap_stats_table_address + class_offset, pp); |
| 1246 const Address& count_address = Address(temp_reg, count_field_offset); | 1243 const Address& count_address = Address(TMP2, count_field_offset); |
| 1247 ldr(TMP, count_address); | 1244 ldr(TMP, count_address); |
| 1248 AddImmediate(TMP, TMP, 1, pp); | 1245 AddImmediate(TMP, TMP, 1, pp); |
| 1249 str(TMP, count_address); | 1246 str(TMP, count_address); |
| 1250 } else { | 1247 } else { |
| 1251 ASSERT(temp_reg != kNoRegister); | |
| 1252 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 1248 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 1253 const uword count_field_offset = (space == Heap::kNew) ? | 1249 const uword count_field_offset = (space == Heap::kNew) ? |
| 1254 ClassHeapStats::allocated_since_gc_new_space_offset() : | 1250 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 1255 ClassHeapStats::allocated_since_gc_old_space_offset(); | 1251 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 1256 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress(), pp); | 1252 LoadImmediate(TMP2, class_table->ClassStatsTableAddress(), pp); |
| 1257 ldr(temp_reg, Address(temp_reg)); | 1253 ldr(TMP, Address(TMP2)); |
| 1258 AddImmediate(temp_reg, temp_reg, class_offset, pp); | 1254 AddImmediate(TMP2, TMP, class_offset, pp); |
| 1259 ldr(TMP, Address(temp_reg, count_field_offset)); | 1255 ldr(TMP, Address(TMP2, count_field_offset)); |
| 1260 AddImmediate(TMP, TMP, 1, pp); | 1256 AddImmediate(TMP, TMP, 1, pp); |
| 1261 str(TMP, Address(temp_reg, count_field_offset)); | 1257 str(TMP, Address(TMP2, count_field_offset)); |
| 1262 } | 1258 } |
| 1263 } | 1259 } |
| 1264 | 1260 |
| 1265 | 1261 |
| 1266 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, | 1262 void Assembler::UpdateAllocationStatsWithSize(intptr_t cid, |
| 1267 Register size_reg, | 1263 Register size_reg, |
| 1268 Register temp_reg, | |
| 1269 Register pp, | 1264 Register pp, |
| 1270 Heap::Space space) { | 1265 Heap::Space space) { |
| 1271 ASSERT(temp_reg != kNoRegister); | |
| 1272 ASSERT(temp_reg != TMP); | |
| 1273 ASSERT(cid > 0); | 1266 ASSERT(cid > 0); |
| 1274 Isolate* isolate = Isolate::Current(); | 1267 Isolate* isolate = Isolate::Current(); |
| 1275 ClassTable* class_table = isolate->class_table(); | 1268 ClassTable* class_table = isolate->class_table(); |
| 1276 if (cid < kNumPredefinedCids) { | 1269 if (cid < kNumPredefinedCids) { |
| 1277 const uword class_heap_stats_table_address = | 1270 const uword class_heap_stats_table_address = |
| 1278 class_table->PredefinedClassHeapStatsTableAddress(); | 1271 class_table->PredefinedClassHeapStatsTableAddress(); |
| 1279 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 1272 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 1280 const uword count_field_offset = (space == Heap::kNew) ? | 1273 const uword count_field_offset = (space == Heap::kNew) ? |
| 1281 ClassHeapStats::allocated_since_gc_new_space_offset() : | 1274 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 1282 ClassHeapStats::allocated_since_gc_old_space_offset(); | 1275 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 1283 const uword size_field_offset = (space == Heap::kNew) ? | 1276 const uword size_field_offset = (space == Heap::kNew) ? |
| 1284 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | 1277 ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| 1285 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 1278 ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| 1286 LoadImmediate(temp_reg, class_heap_stats_table_address + class_offset, pp); | 1279 LoadImmediate(TMP2, class_heap_stats_table_address + class_offset, pp); |
| 1287 const Address& count_address = Address(temp_reg, count_field_offset); | 1280 const Address& count_address = Address(TMP2, count_field_offset); |
| 1288 const Address& size_address = Address(temp_reg, size_field_offset); | 1281 const Address& size_address = Address(TMP2, size_field_offset); |
| 1289 ldr(TMP, count_address); | 1282 ldr(TMP, count_address); |
| 1290 AddImmediate(TMP, TMP, 1, pp); | 1283 AddImmediate(TMP, TMP, 1, pp); |
| 1291 str(TMP, count_address); | 1284 str(TMP, count_address); |
| 1292 ldr(TMP, size_address); | 1285 ldr(TMP, size_address); |
| 1293 add(TMP, TMP, Operand(size_reg)); | 1286 add(TMP, TMP, Operand(size_reg)); |
| 1294 str(TMP, size_address); | 1287 str(TMP, size_address); |
| 1295 } else { | 1288 } else { |
| 1296 ASSERT(temp_reg != kNoRegister); | |
| 1297 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT | 1289 const uword class_offset = cid * sizeof(ClassHeapStats); // NOLINT |
| 1298 const uword count_field_offset = (space == Heap::kNew) ? | 1290 const uword count_field_offset = (space == Heap::kNew) ? |
| 1299 ClassHeapStats::allocated_since_gc_new_space_offset() : | 1291 ClassHeapStats::allocated_since_gc_new_space_offset() : |
| 1300 ClassHeapStats::allocated_since_gc_old_space_offset(); | 1292 ClassHeapStats::allocated_since_gc_old_space_offset(); |
| 1301 const uword size_field_offset = (space == Heap::kNew) ? | 1293 const uword size_field_offset = (space == Heap::kNew) ? |
| 1302 ClassHeapStats::allocated_size_since_gc_new_space_offset() : | 1294 ClassHeapStats::allocated_size_since_gc_new_space_offset() : |
| 1303 ClassHeapStats::allocated_size_since_gc_old_space_offset(); | 1295 ClassHeapStats::allocated_size_since_gc_old_space_offset(); |
| 1304 LoadImmediate(temp_reg, class_table->ClassStatsTableAddress(), pp); | 1296 LoadImmediate(TMP2, class_table->ClassStatsTableAddress(), pp); |
| 1305 ldr(temp_reg, Address(temp_reg)); | 1297 ldr(TMP, Address(TMP2)); |
| 1306 AddImmediate(temp_reg, temp_reg, class_offset, pp); | 1298 AddImmediate(TMP2, TMP, class_offset, pp); |
| 1307 ldr(TMP, Address(temp_reg, count_field_offset)); | 1299 ldr(TMP, Address(TMP2, count_field_offset)); |
| 1308 AddImmediate(TMP, TMP, 1, pp); | 1300 AddImmediate(TMP, TMP, 1, pp); |
| 1309 str(TMP, Address(temp_reg, count_field_offset)); | 1301 str(TMP, Address(TMP2, count_field_offset)); |
| 1310 ldr(TMP, Address(temp_reg, size_field_offset)); | 1302 ldr(TMP, Address(TMP2, size_field_offset)); |
| 1311 add(TMP, TMP, Operand(size_reg)); | 1303 add(TMP, TMP, Operand(size_reg)); |
| 1312 str(TMP, Address(temp_reg, size_field_offset)); | 1304 str(TMP, Address(TMP2, size_field_offset)); |
| 1313 } | 1305 } |
| 1314 } | 1306 } |
| 1315 | 1307 |
| 1316 | 1308 |
| 1317 void Assembler::TryAllocate(const Class& cls, | 1309 void Assembler::TryAllocate(const Class& cls, |
| 1318 Label* failure, | 1310 Label* failure, |
| 1319 Register instance_reg, | 1311 Register instance_reg, |
| 1320 Register temp_reg, | |
| 1321 Register pp) { | 1312 Register pp) { |
| 1322 ASSERT(failure != NULL); | 1313 ASSERT(failure != NULL); |
| 1323 if (FLAG_inline_alloc) { | 1314 if (FLAG_inline_alloc) { |
| 1324 Heap* heap = Isolate::Current()->heap(); | 1315 Heap* heap = Isolate::Current()->heap(); |
| 1325 const intptr_t instance_size = cls.instance_size(); | 1316 const intptr_t instance_size = cls.instance_size(); |
| 1326 LoadImmediate(instance_reg, heap->TopAddress(), pp); | 1317 LoadImmediate(instance_reg, heap->TopAddress(), pp); |
| 1327 ldr(instance_reg, Address(instance_reg)); | 1318 ldr(instance_reg, Address(instance_reg)); |
| 1328 AddImmediate(instance_reg, instance_reg, instance_size, pp); | 1319 AddImmediate(instance_reg, instance_reg, instance_size, pp); |
| 1329 | 1320 |
| 1330 // instance_reg: potential next object start. | 1321 // instance_reg: potential next object start. |
| 1331 LoadImmediate(TMP, heap->EndAddress(), pp); | 1322 LoadImmediate(TMP, heap->EndAddress(), pp); |
| 1332 ldr(TMP, Address(TMP)); | 1323 ldr(TMP, Address(TMP)); |
| 1333 CompareRegisters(TMP, instance_reg); | 1324 CompareRegisters(TMP, instance_reg); |
| 1334 // fail if heap end unsigned less than or equal to instance_reg. | 1325 // fail if heap end unsigned less than or equal to instance_reg. |
| 1335 b(failure, LS); | 1326 b(failure, LS); |
| 1336 | 1327 |
| 1337 // Successfully allocated the object, now update top to point to | 1328 // Successfully allocated the object, now update top to point to |
| 1338 // next object start and store the class in the class field of object. | 1329 // next object start and store the class in the class field of object. |
| 1339 LoadImmediate(TMP, heap->TopAddress(), pp); | 1330 LoadImmediate(TMP, heap->TopAddress(), pp); |
| 1340 str(instance_reg, Address(TMP)); | 1331 str(instance_reg, Address(TMP)); |
| 1341 | 1332 |
| 1342 ASSERT(instance_size >= kHeapObjectTag); | 1333 ASSERT(instance_size >= kHeapObjectTag); |
| 1343 AddImmediate( | 1334 AddImmediate( |
| 1344 instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp); | 1335 instance_reg, instance_reg, -instance_size + kHeapObjectTag, pp); |
| 1345 UpdateAllocationStats(cls.id(), temp_reg, pp); | 1336 UpdateAllocationStats(cls.id(), pp); |
| 1346 | 1337 |
| 1347 uword tags = 0; | 1338 uword tags = 0; |
| 1348 tags = RawObject::SizeTag::update(instance_size, tags); | 1339 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1349 ASSERT(cls.id() != kIllegalCid); | 1340 ASSERT(cls.id() != kIllegalCid); |
| 1350 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1341 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
| 1351 LoadImmediate(TMP, tags, pp); | 1342 LoadImmediate(TMP, tags, pp); |
| 1352 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); | 1343 StoreFieldToOffset(TMP, instance_reg, Object::tags_offset(), pp); |
| 1353 } else { | 1344 } else { |
| 1354 b(failure); | 1345 b(failure); |
| 1355 } | 1346 } |
| 1356 } | 1347 } |
| 1357 | 1348 |
| 1358 } // namespace dart | 1349 } // namespace dart |
| 1359 | 1350 |
| 1360 #endif // defined TARGET_ARCH_ARM64 | 1351 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |