| 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 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 bool is_unique) { | 424 bool is_unique) { |
| 424 if (Thread::CanLoadFromThread(object)) { | 425 if (Thread::CanLoadFromThread(object)) { |
| 425 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); | 426 ldr(dst, Address(THR, Thread::OffsetFromThread(object))); |
| 426 } else if (CanLoadFromObjectPool(object)) { | 427 } else if (CanLoadFromObjectPool(object)) { |
| 427 const int32_t offset = ObjectPool::element_offset( | 428 const int32_t offset = ObjectPool::element_offset( |
| 428 is_unique ? object_pool_wrapper_.AddObject(object) | 429 is_unique ? object_pool_wrapper_.AddObject(object) |
| 429 : object_pool_wrapper_.FindObject(object)); | 430 : object_pool_wrapper_.FindObject(object)); |
| 430 LoadWordFromPoolOffset(dst, offset); | 431 LoadWordFromPoolOffset(dst, offset); |
| 431 } else { | 432 } else { |
| 432 ASSERT(object.IsSmi() || object.InVMHeap()); | 433 ASSERT(object.IsSmi() || object.InVMHeap()); |
| 434 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 433 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw())); | 435 LoadDecodableImmediate(dst, reinterpret_cast<int64_t>(object.raw())); |
| 434 } | 436 } |
| 435 } | 437 } |
| 436 | 438 |
| 437 | 439 |
| 438 void Assembler::LoadFunctionFromCalleePool(Register dst, | 440 void Assembler::LoadFunctionFromCalleePool(Register dst, |
| 439 const Function& function, | 441 const Function& function, |
| 440 Register new_pp) { | 442 Register new_pp) { |
| 441 ASSERT(!constant_pool_allowed()); | 443 ASSERT(!constant_pool_allowed()); |
| 442 ASSERT(new_pp != PP); | 444 ASSERT(new_pp != PP); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 458 | 460 |
| 459 | 461 |
| 460 void Assembler::CompareObject(Register reg, const Object& object) { | 462 void Assembler::CompareObject(Register reg, const Object& object) { |
| 461 if (Thread::CanLoadFromThread(object)) { | 463 if (Thread::CanLoadFromThread(object)) { |
| 462 ldr(TMP, Address(THR, Thread::OffsetFromThread(object))); | 464 ldr(TMP, Address(THR, Thread::OffsetFromThread(object))); |
| 463 CompareRegisters(reg, TMP); | 465 CompareRegisters(reg, TMP); |
| 464 } else if (CanLoadFromObjectPool(object)) { | 466 } else if (CanLoadFromObjectPool(object)) { |
| 465 LoadObject(TMP, object); | 467 LoadObject(TMP, object); |
| 466 CompareRegisters(reg, TMP); | 468 CompareRegisters(reg, TMP); |
| 467 } else { | 469 } else { |
| 470 ASSERT(object.IsSmi() || FLAG_allow_absolute_addresses); |
| 468 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw())); | 471 CompareImmediate(reg, reinterpret_cast<int64_t>(object.raw())); |
| 469 } | 472 } |
| 470 } | 473 } |
| 471 | 474 |
| 472 | 475 |
| 473 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) { | 476 void Assembler::LoadDecodableImmediate(Register reg, int64_t imm) { |
| 474 if (constant_pool_allowed()) { | 477 if (constant_pool_allowed()) { |
| 475 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); | 478 const int32_t offset = ObjectPool::element_offset(FindImmediate(imm)); |
| 476 LoadWordFromPoolOffset(reg, offset); | 479 LoadWordFromPoolOffset(reg, offset); |
| 477 } else { | 480 } else { |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 } | 1249 } |
| 1247 | 1250 |
| 1248 | 1251 |
| 1249 void Assembler::UpdateAllocationStats(intptr_t cid, | 1252 void Assembler::UpdateAllocationStats(intptr_t cid, |
| 1250 Heap::Space space, | 1253 Heap::Space space, |
| 1251 bool inline_isolate) { | 1254 bool inline_isolate) { |
| 1252 ASSERT(cid > 0); | 1255 ASSERT(cid > 0); |
| 1253 intptr_t counter_offset = | 1256 intptr_t counter_offset = |
| 1254 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); | 1257 ClassTable::CounterOffsetFor(cid, space == Heap::kNew); |
| 1255 if (inline_isolate) { | 1258 if (inline_isolate) { |
| 1259 ASSERT(FLAG_allow_absolute_addresses); |
| 1256 ClassTable* class_table = Isolate::Current()->class_table(); | 1260 ClassTable* class_table = Isolate::Current()->class_table(); |
| 1257 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 1261 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
| 1258 if (cid < kNumPredefinedCids) { | 1262 if (cid < kNumPredefinedCids) { |
| 1259 LoadImmediate( | 1263 LoadImmediate( |
| 1260 TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset); | 1264 TMP2, reinterpret_cast<uword>(*table_ptr) + counter_offset); |
| 1261 } else { | 1265 } else { |
| 1262 LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr)); | 1266 LoadImmediate(TMP2, reinterpret_cast<uword>(table_ptr)); |
| 1263 ldr(TMP, Address(TMP2)); | 1267 ldr(TMP, Address(TMP2)); |
| 1264 AddImmediate(TMP2, TMP, counter_offset); | 1268 AddImmediate(TMP2, TMP, counter_offset); |
| 1265 } | 1269 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1315 } | 1319 } |
| 1316 | 1320 |
| 1317 | 1321 |
| 1318 void Assembler::MaybeTraceAllocation(intptr_t cid, | 1322 void Assembler::MaybeTraceAllocation(intptr_t cid, |
| 1319 Register temp_reg, | 1323 Register temp_reg, |
| 1320 Label* trace, | 1324 Label* trace, |
| 1321 bool inline_isolate) { | 1325 bool inline_isolate) { |
| 1322 ASSERT(cid > 0); | 1326 ASSERT(cid > 0); |
| 1323 intptr_t state_offset = ClassTable::StateOffsetFor(cid); | 1327 intptr_t state_offset = ClassTable::StateOffsetFor(cid); |
| 1324 if (inline_isolate) { | 1328 if (inline_isolate) { |
| 1329 ASSERT(FLAG_allow_absolute_addresses); |
| 1325 ClassTable* class_table = Isolate::Current()->class_table(); | 1330 ClassTable* class_table = Isolate::Current()->class_table(); |
| 1326 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 1331 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
| 1327 if (cid < kNumPredefinedCids) { | 1332 if (cid < kNumPredefinedCids) { |
| 1328 LoadImmediate( | 1333 LoadImmediate( |
| 1329 temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset); | 1334 temp_reg, reinterpret_cast<uword>(*table_ptr) + state_offset); |
| 1330 } else { | 1335 } else { |
| 1331 LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr)); | 1336 LoadImmediate(temp_reg, reinterpret_cast<uword>(table_ptr)); |
| 1332 ldr(temp_reg, Address(temp_reg, 0)); | 1337 ldr(temp_reg, Address(temp_reg, 0)); |
| 1333 AddImmediate(temp_reg, temp_reg, state_offset); | 1338 AddImmediate(temp_reg, temp_reg, state_offset); |
| 1334 } | 1339 } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 add(base, array, Operand(index, LSL, shift)); | 1478 add(base, array, Operand(index, LSL, shift)); |
| 1474 } | 1479 } |
| 1475 const OperandSize size = Address::OperandSizeFor(cid); | 1480 const OperandSize size = Address::OperandSizeFor(cid); |
| 1476 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); | 1481 ASSERT(Address::CanHoldOffset(offset, Address::Offset, size)); |
| 1477 return Address(base, offset, Address::Offset, size); | 1482 return Address(base, offset, Address::Offset, size); |
| 1478 } | 1483 } |
| 1479 | 1484 |
| 1480 } // namespace dart | 1485 } // namespace dart |
| 1481 | 1486 |
| 1482 #endif // defined TARGET_ARCH_ARM64 | 1487 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |