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" |
11 #include "vm/runtime_entry.h" | 11 #include "vm/runtime_entry.h" |
12 #include "vm/simulator.h" | 12 #include "vm/simulator.h" |
13 #include "vm/stack_frame.h" | 13 #include "vm/stack_frame.h" |
14 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
15 | 15 |
16 // An extra check since we are assuming the existence of /proc/cpuinfo below. | 16 // An extra check since we are assuming the existence of /proc/cpuinfo below. |
17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) | 17 #if !defined(USING_SIMULATOR) && !defined(__linux__) && !defined(ANDROID) |
18 #error ARM64 cross-compile only supported on Linux | 18 #error ARM64 cross-compile only supported on Linux |
19 #endif | 19 #endif |
20 | 20 |
21 namespace dart { | 21 namespace dart { |
22 | 22 |
| 23 DECLARE_FLAG(bool, allow_absolute_addresses); |
23 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); | 24 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches"); |
24 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); | 25 DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
25 DECLARE_FLAG(bool, inline_alloc); | 26 DECLARE_FLAG(bool, inline_alloc); |
26 | 27 |
27 | 28 |
28 Assembler::Assembler(bool use_far_branches) | 29 Assembler::Assembler(bool use_far_branches) |
29 : buffer_(), | 30 : buffer_(), |
30 prologue_offset_(-1), | 31 prologue_offset_(-1), |
31 use_far_branches_(use_far_branches), | 32 use_far_branches_(use_far_branches), |
32 comments_(), | 33 comments_(), |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 bool is_unique) { | 416 bool is_unique) { |
416 if (Thread::CanLoadFromThread(object)) { | 417 if (Thread::CanLoadFromThread(object)) { |
417 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); | 418 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); |
418 } else if (CanLoadFromObjectPool(object)) { | 419 } else if (CanLoadFromObjectPool(object)) { |
419 const int32_t offset = ObjectPool::element_offset( | 420 const int32_t offset = ObjectPool::element_offset( |
420 is_unique ? object_pool_wrapper_.AddObject(object) | 421 is_unique ? object_pool_wrapper_.AddObject(object) |
421 : object_pool_wrapper_.FindObject(object)); | 422 : object_pool_wrapper_.FindObject(object)); |
422 LoadWordFromPoolOffset(dst, offset); | 423 LoadWordFromPoolOffset(dst, offset); |
423 } else { | 424 } else { |
424 ASSERT(object.IsSmi() || object.InVMHeap()); | 425 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 426 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
425 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw())); | 427 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw())); |
426 } | 428 } |
427 } | 429 } |
428 | 430 |
429 | 431 |
430 void Assembler::LoadFunctionFromCalleePool(Register dst, | 432 void Assembler::LoadFunctionFromCalleePool(Register dst, |
431 const Function& function, | 433 const Function& function, |
432 Register new_pp) { | 434 Register new_pp) { |
433 ASSERT(!constant_pool_allowed()); | 435 ASSERT(!constant_pool_allowed()); |
434 ASSERT(new_pp != PP); | 436 ASSERT(new_pp != PP); |
(...skipping 15 matching lines...) Expand all Loading... |
450 | 452 |
451 | 453 |
452 void Assembler::CompareObject(Register reg, const Object& object) { | 454 void Assembler::CompareObject(Register reg, const Object& object) { |
453 if (Thread::CanLoadFromThread(object)) { | 455 if (Thread::CanLoadFromThread(object)) { |
454 ldr(TMP, Address(THR, Thread::OffsetFromThread(object))); | 456 ldr(TMP, Address(THR, Thread::OffsetFromThread(object))); |
455 CompareRegisters(reg, TMP); | 457 CompareRegisters(reg, TMP); |
456 } else if (CanLoadFromObjectPool(object)) { | 458 } else if (CanLoadFromObjectPool(object)) { |
457 LoadObject(TMP, object); | 459 LoadObject(TMP, object); |
458 CompareRegisters(reg, TMP); | 460 CompareRegisters(reg, TMP); |
459 } else { | 461 } else { |
| 462 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
460 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw())); | 463 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw())); |
461 } | 464 } |
462 } | 465 } |
463 | 466 |
464 | 467 |
465 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) { | 468 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) { |
466 if (constant_pool_allowed()) { | 469 if (constant_pool_allowed()) { |
467 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); | 470 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); |
468 LoadWordFromPoolOffset(reg, offset); | 471 LoadWordFromPoolOffset(reg, offset); |
469 } else { | 472 } else { |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 } | 1241 } |
1239 | 1242 |
1240 | 1243 |
1241 void Assembler::UpdateAllocationStats(intptr_t cid, | 1244 void Assembler::UpdateAllocationStats(intptr_t cid, |
1242 Heap::Space space, | 1245 Heap::Space space, |
1243 bool inline_isolate) { | 1246 bool inline_isolate) { |
1244 ASSERT(cid > 0); | 1247 ASSERT(cid > 0); |
1245 intptr_t counter_offset = | 1248 intptr_t counter_offset = |
1246 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); | 1249 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); |
1247 if (inline_isolate) { | 1250 if (inline_isolate) { |
| 1251 ASSERT(FLAG_allow_absolute_addresses); |
1248 ClassTable* class_table = Isolate::Current()->class_table(); | 1252 ClassTable* class_table = Isolate::Current()->class_table(); |
1249 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 1253 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
1250 if (cid < kNumPredefinedCids) { | 1254 if (cid < kNumPredefinedCids) { |
1251 LoadImmediate( | 1255 LoadImmediate( |
1252 TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset); | 1256 TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset); |
1253 } else { | 1257 } else { |
1254 LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr)); | 1258 LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr)); |
1255 ldr(TMP, Address(TMP2)); | 1259 ldr(TMP, Address(TMP2)); |
1256 AddImmediate(TMP2, TMP, counter_offset); | 1260 AddImmediate(TMP2, TMP, counter_offset); |
1257 } | 1261 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 } | 1311 } |
1308 | 1312 |
1309 | 1313 |
1310 void Assembler::MaybeTraceAllocation(intptr_t cid, | 1314 void Assembler::MaybeTraceAllocation(intptr_t cid, |
1311 Register temp_reg, | 1315 Register temp_reg, |
1312 Label* trace, | 1316 Label* trace, |
1313 bool inline_isolate) { | 1317 bool inline_isolate) { |
1314 ASSERT(cid > 0); | 1318 ASSERT(cid > 0); |
1315 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 1319 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
1316 if (inline_isolate) { | 1320 if (inline_isolate) { |
| 1321 ASSERT(FLAG_allow_absolute_addresses); |
1317 ClassTable* class_table = Isolate::Current()->class_table(); | 1322 ClassTable* class_table = Isolate::Current()->class_table(); |
1318 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 1323 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
1319 if (cid < kNumPredefinedCids) { | 1324 if (cid < kNumPredefinedCids) { |
1320 LoadImmediate( | 1325 LoadImmediate( |
1321 temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset); | 1326 temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset); |
1322 } else { | 1327 } else { |
1323 LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr)); | 1328 LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr)); |
1324 ldr(temp_reg, Address(temp_reg, 0)); | 1329 ldr(temp_reg, Address(temp_reg, 0)); |
1325 AddImmediate(temp_reg, temp_reg, state_offset); | 1330 AddImmediate(temp_reg, temp_reg, state_offset); |
1326 } | 1331 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 add(base, array, Operand(index, LSL, shift)); | 1470 add(base, array, Operand(index, LSL, shift)); |
1466 } | 1471 } |
1467 const OperandSize size = Address::OperandSizeFor(cid); | 1472 const OperandSize size = Address::OperandSizeFor(cid); |
1468 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1473 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
1469 return Address(base, offset, Address::Offset, size); | 1474 return Address(base, offset, Address::Offset, size); |
1470 } | 1475 } |
1471 | 1476 |
1472 } // namespace dart | 1477 } // namespace dart |
1473 | 1478 |
1474 #endif // defined TARGET_ARCH_ARM64 | 1479 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |