assembler-arm-inl.h revision 8b112d2025046f85ef7f6be087c6129c872ebad2
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright (c) 1994-2006 Sun Microsystems Inc. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// All Rights Reserved. 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// are met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistributions of source code must retain the above copyright notice, 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Redistribution in binary form must reproduce the above copyright 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer in the 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// documentation and/or other materials provided with the 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// distribution. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// - Neither the name of Sun Microsystems or the names of contributors may 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// be used to endorse or promote products derived from this software without 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// specific prior written permission. 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THE POSSIBILITY OF SUCH DAMAGE. 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The original source code covered by the above license above has been modified 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// significantly by Google Inc. 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 the V8 project authors. All rights reserved. 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ARM_ASSEMBLER_ARM_INL_H_ 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ARM_ASSEMBLER_ARM_INL_H_ 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/assembler-arm.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h" 42f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "debug.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsInternalReference(rmode_)) { 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // absolute code pointer inside code object moves with the code object. 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += delta; // relocate entry 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We do not use pc relative addressing on ARM, so there is 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // nothing else to do. 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() { 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Assembler::target_address_at(pc_); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() { 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_)); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() { 73f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke return Assembler::kExternalTargetSize; 74f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 75f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 76f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_address(Address target) { 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, target); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_at(Assembler::target_address_address_at(pc_)); 863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 89d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_)); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() { 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_)); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_target_object(Object* target) { 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() { 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode_ == EXTERNAL_REFERENCE); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_)); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = Memory::Address_at(pc_); 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return Handle<JSGlobalPropertyCell>( 117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<JSGlobalPropertyCell**>(address)); 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochJSGlobalPropertyCell* RelocInfo::target_cell() { 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = Memory::Address_at(pc_); 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* object = HeapObject::FromAddress( 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch address - JSGlobalPropertyCell::kValueOffset); 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<JSGlobalPropertyCell*>(object); 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell) { 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = cell->address() + JSGlobalPropertyCell::kValueOffset; 133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Memory::Address_at(pc_) = address; 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() { 1387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The 2 instructions offset assumes patched debug break slot or return 1397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // sequence. 1407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 1417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) { 147bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 148bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() { 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *call_object_address(); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 158bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochvoid RelocInfo::set_call_object(Object* target) { 159bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch *call_object_address() = target; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochObject** RelocInfo::call_object_address() { 164bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 165bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 166bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() { 1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Instr current_instr = Assembler::instr_at(pc_); 1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize); 1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef USE_BLX 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // A patched return sequence is: 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // ldr ip, [pc, #0] 1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // blx ip 1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return ((current_instr & kLdrPCMask) == kLdrPCPattern) 1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && ((next_instr & kBlxRegMask) == kBlxRegPattern); 1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else 1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // A patched return sequence is: 1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // mov lr, pc 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // ldr pc, [pc, #-4] 1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return (current_instr == kMovLrPc) 1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && ((next_instr & kLdrPCMask) == kLdrPCPattern); 1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool RelocInfo::IsPatchedDebugBreakSlotSequence() { 1907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Instr current_instr = Assembler::instr_at(pc_); 1918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP); 1927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 1937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 195f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid RelocInfo::Visit(ObjectVisitor* visitor) { 196f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke RelocInfo::Mode mode = rmode(); 197f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (mode == RelocInfo::EMBEDDED_OBJECT) { 198f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitPointer(target_object_address()); 199f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (RelocInfo::IsCodeTarget(mode)) { 200f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitCodeTarget(this); 2011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 2021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block visitor->VisitGlobalPropertyCell(this); 203f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 204f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitExternalReference(target_reference_address()); 205f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): Get a cached isolate below. 20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (((RelocInfo::IsJSReturn(mode) && 2087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch IsPatchedReturnSequence()) || 2097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (RelocInfo::IsDebugBreakSlot(mode) && 21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block IsPatchedDebugBreakSlotSequence())) && 21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debug()->has_break_points()) { 212f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitDebugTarget(this); 213f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif 214f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (mode == RelocInfo::RUNTIME_ENTRY) { 215f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitRuntimeEntry(this); 216f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor> 22144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) { 222756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick RelocInfo::Mode mode = rmode(); 223756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (mode == RelocInfo::EMBEDDED_OBJECT) { 22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block StaticVisitor::VisitPointer(heap, target_object_address()); 225756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (RelocInfo::IsCodeTarget(mode)) { 2268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitCodeTarget(heap, this); 2271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 2288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitGlobalPropertyCell(heap, this); 229756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 230756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticVisitor::VisitExternalReference(target_reference_address()); 231756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (heap->isolate()->debug()->has_break_points() && 233756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ((RelocInfo::IsJSReturn(mode) && 234756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick IsPatchedReturnSequence()) || 235756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick (RelocInfo::IsDebugBreakSlot(mode) && 236756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick IsPatchedDebugBreakSlotSequence()))) { 2378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitDebugTarget(heap, this); 238756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif 239756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (mode == RelocInfo::RUNTIME_ENTRY) { 240756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticVisitor::VisitRuntimeEntry(this); 241756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 242756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 243756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 244756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 245f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeOperand::Operand(int32_t immediate, RelocInfo::Mode rmode) { 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 247f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke imm32_ = immediate; 248f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke rmode_ = rmode; 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(const ExternalReference& f) { 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(f.address()); 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EXTERNAL_REFERENCE; 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Smi* value) { 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<intptr_t>(value); 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register rm) { 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = rm; 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_ = no_reg; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ = LSL; 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ = 0; 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg() const { 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return rm_.is_valid() && 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_.is(no_reg) && 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ == LSL && 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ == 0; 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::CheckBuffer() { 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_space() <= kGap) { 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GrowBuffer(); 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pc_offset() >= next_buffer_check_) { 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckConstPool(false, true); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Instr x) { 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckBuffer(); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<Instr*>(pc_) = x; 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += kInstrSize; 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_address_at(Address pc) { 300e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Address target_pc = pc; 301e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Instr instr = Memory::int32_at(target_pc); 302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // If we have a bx instruction, the instruction before the bx is 303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // what we need to patch. 304e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int32_t kBxInstMask = 0x0ffffff0; 305e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int32_t kBxInstPattern = 0x012fff10; 306e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if ((instr & kBxInstMask) == kBxInstPattern) { 307e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke target_pc -= kInstrSize; 308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke instr = Memory::int32_at(target_pc); 309e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef USE_BLX 3126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // If we have a blx instruction, the instruction before it is 3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // what needs to be patched. 3146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if ((instr & kBlxRegMask) == kBlxRegPattern) { 3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block target_pc -= kInstrSize; 3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block instr = Memory::int32_at(target_pc); 3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang ASSERT(IsLdrPcImmediateOffset(instr)); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset = instr & 0xfff; // offset_12 is unsigned 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify that the constant pool comes after the instruction referencing it. 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offset >= -4); 325e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return target_pc + offset + 8; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) { 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(target_address_address_at(pc)); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid Assembler::set_target_at(Address constant_pool_entry, 335d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Address target) { 336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Memory::Address_at(constant_pool_entry) = target; 337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 339d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) { 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(target_address_address_at(pc)) = target; 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Intuitively, we would think it is necessary to flush the instruction cache 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after patching a target address in the code as follows: 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPU::FlushICache(pc, sizeof(target)); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // However, on ARM, no instruction was actually patched by the assignment 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // above; the target address is not part of an instruction, it is patched in 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the constant pool and is read via a data access; the instruction accessing 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this address in the constant pool remains unchanged. 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_ARM_ASSEMBLER_ARM_INL_H_ 354