OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 ARM cross-compile only supported on Linux | 18 #error ARM 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, print_stop_message, true, "Print stop message."); | 24 DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
24 DECLARE_FLAG(bool, inline_alloc); | 25 DECLARE_FLAG(bool, inline_alloc); |
25 | 26 |
26 // Instruction encoding bits. | 27 // Instruction encoding bits. |
27 enum { | 28 enum { |
28 H = 1 << 5, // halfword (or byte) | 29 H = 1 << 5, // halfword (or byte) |
29 L = 1 << 20, // load (or store) | 30 L = 1 << 20, // load (or store) |
30 S = 1 << 20, // set condition code (or leave unchanged) | 31 S = 1 << 20, // set condition code (or leave unchanged) |
31 W = 1 << 21, // writeback base register (or leave unchanged) | 32 W = 1 << 21, // writeback base register (or leave unchanged) |
32 A = 1 << 21, // accumulate in multiply instruction (or not) | 33 A = 1 << 21, // accumulate in multiply instruction (or not) |
(...skipping 1543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 // Load common VM constants from the thread. This works also in places where | 1577 // Load common VM constants from the thread. This works also in places where |
1577 // no constant pool is set up (e.g. intrinsic code). | 1578 // no constant pool is set up (e.g. intrinsic code). |
1578 if (Thread::CanLoadFromThread(object)) { | 1579 if (Thread::CanLoadFromThread(object)) { |
1579 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); | 1580 ldr(rd, Address(THR, Thread::OffsetFromThread(object)), cond); |
1580 return; | 1581 return; |
1581 } | 1582 } |
1582 // Smis and VM heap objects are never relocated; do not use object pool. | 1583 // Smis and VM heap objects are never relocated; do not use object pool. |
1583 if (object.IsSmi()) { | 1584 if (object.IsSmi()) { |
1584 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); | 1585 LoadImmediate(rd, reinterpret_cast<int32_t>(object.raw()), cond); |
1585 } else if (object.InVMHeap() || !constant_pool_allowed()) { | 1586 } else if (object.InVMHeap() || !constant_pool_allowed()) { |
| 1587 ASSERT(FLAG_allow_absolute_addresses); |
1586 // Make sure that class CallPattern is able to decode this load immediate. | 1588 // Make sure that class CallPattern is able to decode this load immediate. |
1587 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); | 1589 const int32_t object_raw = reinterpret_cast<int32_t>(object.raw()); |
1588 LoadImmediate(rd, object_raw, cond); | 1590 LoadImmediate(rd, object_raw, cond); |
1589 } else { | 1591 } else { |
1590 // Make sure that class CallPattern is able to decode this load from the | 1592 // Make sure that class CallPattern is able to decode this load from the |
1591 // object pool. | 1593 // object pool. |
1592 const int32_t offset = ObjectPool::element_offset( | 1594 const int32_t offset = ObjectPool::element_offset( |
1593 is_unique ? object_pool_wrapper_.AddObject(object) | 1595 is_unique ? object_pool_wrapper_.AddObject(object) |
1594 : object_pool_wrapper_.FindObject(object)); | 1596 : object_pool_wrapper_.FindObject(object)); |
1595 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); | 1597 LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 b(&ok, EQ); | 1762 b(&ok, EQ); |
1761 Stop("Expected heap object or Smi"); | 1763 Stop("Expected heap object or Smi"); |
1762 break; | 1764 break; |
1763 case kEmptyOrSmiOrNull: | 1765 case kEmptyOrSmiOrNull: |
1764 b(&ok, EQ); // Smi is OK. | 1766 b(&ok, EQ); // Smi is OK. |
1765 // Non-smi case: Check for the special zap word or null. | 1767 // Non-smi case: Check for the special zap word or null. |
1766 // Note: Cannot use CompareImmediate, since IP may be in use. | 1768 // Note: Cannot use CompareImmediate, since IP may be in use. |
1767 LoadImmediate(temp, Heap::kZap32Bits); | 1769 LoadImmediate(temp, Heap::kZap32Bits); |
1768 cmp(old_value, Operand(temp)); | 1770 cmp(old_value, Operand(temp)); |
1769 b(&ok, EQ); | 1771 b(&ok, EQ); |
1770 LoadImmediate(temp, reinterpret_cast<uint32_t>(Object::null())); | 1772 LoadObject(temp, Object::null_object()); |
1771 cmp(old_value, Operand(temp)); | 1773 cmp(old_value, Operand(temp)); |
1772 b(&ok, EQ); | 1774 b(&ok, EQ); |
1773 Stop("Expected zapped, Smi or null"); | 1775 Stop("Expected zapped, Smi or null"); |
1774 break; | 1776 break; |
1775 default: | 1777 default: |
1776 UNREACHABLE(); | 1778 UNREACHABLE(); |
1777 } | 1779 } |
1778 Bind(&ok); | 1780 Bind(&ok); |
1779 if (VerifiedMemory::enabled()) { | 1781 if (VerifiedMemory::enabled()) { |
1780 Operand shadow_offset(GetVerifiedMemoryShadow()); | 1782 Operand shadow_offset(GetVerifiedMemoryShadow()); |
(...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3370 | 3372 |
3371 | 3373 |
3372 void Assembler::LoadAllocationStatsAddress(Register dest, | 3374 void Assembler::LoadAllocationStatsAddress(Register dest, |
3373 intptr_t cid, | 3375 intptr_t cid, |
3374 bool inline_isolate) { | 3376 bool inline_isolate) { |
3375 ASSERT(dest != kNoRegister); | 3377 ASSERT(dest != kNoRegister); |
3376 ASSERT(dest != TMP); | 3378 ASSERT(dest != TMP); |
3377 ASSERT(cid > 0); | 3379 ASSERT(cid > 0); |
3378 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); | 3380 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); |
3379 if (inline_isolate) { | 3381 if (inline_isolate) { |
| 3382 ASSERT(FLAG_allow_absolute_addresses); |
3380 ClassTable* class_table = Isolate::Current()->class_table(); | 3383 ClassTable* class_table = Isolate::Current()->class_table(); |
3381 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 3384 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
3382 if (cid < kNumPredefinedCids) { | 3385 if (cid < kNumPredefinedCids) { |
3383 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); | 3386 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); |
3384 } else { | 3387 } else { |
3385 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); | 3388 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); |
3386 ldr(dest, Address(dest, 0)); | 3389 ldr(dest, Address(dest, 0)); |
3387 AddImmediate(dest, class_offset); | 3390 AddImmediate(dest, class_offset); |
3388 } | 3391 } |
3389 } else { | 3392 } else { |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3653 | 3656 |
3654 | 3657 |
3655 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3658 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
3656 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3659 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
3657 return fpu_reg_names[reg]; | 3660 return fpu_reg_names[reg]; |
3658 } | 3661 } |
3659 | 3662 |
3660 } // namespace dart | 3663 } // namespace dart |
3661 | 3664 |
3662 #endif // defined TARGET_ARCH_ARM | 3665 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |