| 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 b(&ok, EQ); | 1772 b(&ok, EQ); |
| 1771 Stop("Expected heap object or Smi"); | 1773 Stop("Expected heap object or Smi"); |
| 1772 break; | 1774 break; |
| 1773 case kEmptyOrSmiOrNull: | 1775 case kEmptyOrSmiOrNull: |
| 1774 b(&ok, EQ); // Smi is OK. | 1776 b(&ok, EQ); // Smi is OK. |
| 1775 // Non-smi case: Check for the special zap word or null. | 1777 // Non-smi case: Check for the special zap word or null. |
| 1776 // Note: Cannot use CompareImmediate, since IP may be in use. | 1778 // Note: Cannot use CompareImmediate, since IP may be in use. |
| 1777 LoadImmediate(temp, Heap::kZap32Bits); | 1779 LoadImmediate(temp, Heap::kZap32Bits); |
| 1778 cmp(old_value, Operand(temp)); | 1780 cmp(old_value, Operand(temp)); |
| 1779 b(&ok, EQ); | 1781 b(&ok, EQ); |
| 1780 LoadImmediate(temp, reinterpret_cast<uint32_t>(Object::null())); | 1782 LoadObject(temp, Object::null_object()); |
| 1781 cmp(old_value, Operand(temp)); | 1783 cmp(old_value, Operand(temp)); |
| 1782 b(&ok, EQ); | 1784 b(&ok, EQ); |
| 1783 Stop("Expected zapped, Smi or null"); | 1785 Stop("Expected zapped, Smi or null"); |
| 1784 break; | 1786 break; |
| 1785 default: | 1787 default: |
| 1786 UNREACHABLE(); | 1788 UNREACHABLE(); |
| 1787 } | 1789 } |
| 1788 Bind(&ok); | 1790 Bind(&ok); |
| 1789 if (VerifiedMemory::enabled()) { | 1791 if (VerifiedMemory::enabled()) { |
| 1790 Operand shadow_offset(GetVerifiedMemoryShadow()); | 1792 Operand shadow_offset(GetVerifiedMemoryShadow()); |
| (...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3380 | 3382 |
| 3381 | 3383 |
| 3382 void Assembler::LoadAllocationStatsAddress(Register dest, | 3384 void Assembler::LoadAllocationStatsAddress(Register dest, |
| 3383 intptr_t cid, | 3385 intptr_t cid, |
| 3384 bool inline_isolate) { | 3386 bool inline_isolate) { |
| 3385 ASSERT(dest != kNoRegister); | 3387 ASSERT(dest != kNoRegister); |
| 3386 ASSERT(dest != TMP); | 3388 ASSERT(dest != TMP); |
| 3387 ASSERT(cid > 0); | 3389 ASSERT(cid > 0); |
| 3388 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); | 3390 const intptr_t class_offset = ClassTable::ClassOffsetFor(cid); |
| 3389 if (inline_isolate) { | 3391 if (inline_isolate) { |
| 3392 ASSERT(FLAG_allow_absolute_addresses); |
| 3390 ClassTable* class_table = Isolate::Current()->class_table(); | 3393 ClassTable* class_table = Isolate::Current()->class_table(); |
| 3391 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); | 3394 ClassHeapStats** table_ptr = class_table->TableAddressFor(cid); |
| 3392 if (cid < kNumPredefinedCids) { | 3395 if (cid < kNumPredefinedCids) { |
| 3393 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); | 3396 LoadImmediate(dest, reinterpret_cast<uword>(*table_ptr) + class_offset); |
| 3394 } else { | 3397 } else { |
| 3395 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); | 3398 LoadImmediate(dest, reinterpret_cast<uword>(table_ptr)); |
| 3396 ldr(dest, Address(dest, 0)); | 3399 ldr(dest, Address(dest, 0)); |
| 3397 AddImmediate(dest, class_offset); | 3400 AddImmediate(dest, class_offset); |
| 3398 } | 3401 } |
| 3399 } else { | 3402 } else { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3663 | 3666 |
| 3664 | 3667 |
| 3665 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3668 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
| 3666 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3669 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
| 3667 return fpu_reg_names[reg]; | 3670 return fpu_reg_names[reg]; |
| 3668 } | 3671 } |
| 3669 | 3672 |
| 3670 } // namespace dart | 3673 } // namespace dart |
| 3671 | 3674 |
| 3672 #endif // defined TARGET_ARCH_ARM | 3675 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |