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. 35692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch// Copyright 2012 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" 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cpu.h" 43f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "debug.h" 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdochint DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) { 51692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch ASSERT(!reg.is(kDoubleRegZero)); 52692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch ASSERT(!reg.is(kScratchDoubleReg)); 53692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch return reg.code(); 54692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch} 55692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 56692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::apply(intptr_t delta) { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (RelocInfo::IsInternalReference(rmode_)) { 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // absolute code pointer inside code object moves with the code object. 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int32_t* p = reinterpret_cast<int32_t*>(pc_); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *p += delta; // relocate entry 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We do not use pc relative addressing on ARM, so there is 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // nothing else to do. 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address() { 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Assembler::target_address_at(pc_); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::target_address_address() { 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch || rmode_ == EMBEDDED_OBJECT 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch || rmode_ == EXTERNAL_REFERENCE); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address>(Assembler::target_address_address_at(pc_)); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkeint RelocInfo::target_address_size() { 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return kPointerSize; 84f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 85f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 86f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, target); 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { 913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), this, HeapObject::cast(target_code)); 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::target_object() { 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_at(Assembler::target_address_address_at(pc_)); 1013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 1023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 1033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 104d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 1053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return Memory::Object_Handle_at(Assembler::target_address_address_at(pc_)); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** RelocInfo::target_object_address() { 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Object**>(Assembler::target_address_address_at(pc_)); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host() != NULL && 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->IsHeapObject()) { 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWrite( 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), &Memory::Object_at(pc_), HeapObject::cast(target)); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress* RelocInfo::target_reference_address() { 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(rmode_ == EXTERNAL_REFERENCE); 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<Address*>(Assembler::target_address_address_at(pc_)); 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = Memory::Address_at(pc_); 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return Handle<JSGlobalPropertyCell>( 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch reinterpret_cast<JSGlobalPropertyCell**>(address)); 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 141b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochJSGlobalPropertyCell* RelocInfo::target_cell() { 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = Memory::Address_at(pc_); 145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* object = HeapObject::FromAddress( 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch address - JSGlobalPropertyCell::kValueOffset); 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return reinterpret_cast<JSGlobalPropertyCell*>(object); 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell, 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteBarrierMode mode) { 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Address address = cell->address() + JSGlobalPropertyCell::kValueOffset; 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Memory::Address_at(pc_) = address; 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(1550) We are passing NULL as a slot because cell can never be on 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // evacuation candidate. 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWrite( 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), NULL, cell); 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress RelocInfo::call_address() { 1667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // The 2 instructions offset assumes patched debug break slot or return 1677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // sequence. 1687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 1697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(pc_ + 2 * Assembler::kInstrSize); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RelocInfo::set_call_address(Address target) { 175bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 176bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(pc_ + 2 * Assembler::kInstrSize) = target; 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (host() != NULL) { 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), this, HeapObject::cast(target_code)); 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* RelocInfo::call_object() { 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *call_object_address(); 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochvoid RelocInfo::set_call_object(Object* target) { 192bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch *call_object_address() = target; 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochObject** RelocInfo::call_object_address() { 197bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 198bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 199bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockbool RelocInfo::IsPatchedReturnSequence() { 2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Instr current_instr = Assembler::instr_at(pc_); 2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Instr next_instr = Assembler::instr_at(pc_ + Assembler::kInstrSize); 2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef USE_BLX 2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // A patched return sequence is: 2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // ldr ip, [pc, #0] 2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // blx ip 2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return ((current_instr & kLdrPCMask) == kLdrPCPattern) 2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && ((next_instr & kBlxRegMask) == kBlxRegPattern); 2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#else 2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // A patched return sequence is: 2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // mov lr, pc 2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // ldr pc, [pc, #-4] 2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return (current_instr == kMovLrPc) 2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block && ((next_instr & kLdrPCMask) == kLdrPCPattern); 2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool RelocInfo::IsPatchedDebugBreakSlotSequence() { 2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Instr current_instr = Assembler::instr_at(pc_); 2248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP); 2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 228f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid RelocInfo::Visit(ObjectVisitor* visitor) { 229f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke RelocInfo::Mode mode = rmode(); 230f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (mode == RelocInfo::EMBEDDED_OBJECT) { 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitEmbeddedPointer(this); 232f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (RelocInfo::IsCodeTarget(mode)) { 233f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitCodeTarget(this); 2341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 2351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block visitor->VisitGlobalPropertyCell(this); 236f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitExternalReference(this); 238f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 23944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): Get a cached isolate below. 24044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (((RelocInfo::IsJSReturn(mode) && 2417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch IsPatchedReturnSequence()) || 2427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (RelocInfo::IsDebugBreakSlot(mode) && 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block IsPatchedDebugBreakSlotSequence())) && 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debug()->has_break_points()) { 245f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitDebugTarget(this); 246f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif 247f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } else if (mode == RelocInfo::RUNTIME_ENTRY) { 248f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke visitor->VisitRuntimeEntry(this); 249f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merricktemplate<typename StaticVisitor> 25444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) { 255756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick RelocInfo::Mode mode = rmode(); 256756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick if (mode == RelocInfo::EMBEDDED_OBJECT) { 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitEmbeddedPointer(heap, this); 258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (RelocInfo::IsCodeTarget(mode)) { 2598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitCodeTarget(heap, this); 2601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 2618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitGlobalPropertyCell(heap, this); 262756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitExternalReference(this); 264756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#ifdef ENABLE_DEBUGGER_SUPPORT 26544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (heap->isolate()->debug()->has_break_points() && 266756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick ((RelocInfo::IsJSReturn(mode) && 267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick IsPatchedReturnSequence()) || 268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick (RelocInfo::IsDebugBreakSlot(mode) && 269756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick IsPatchedDebugBreakSlotSequence()))) { 2708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StaticVisitor::VisitDebugTarget(heap, this); 271756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#endif 272756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } else if (mode == RelocInfo::RUNTIME_ENTRY) { 273756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick StaticVisitor::VisitRuntimeEntry(this); 274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 276756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 278f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeOperand::Operand(int32_t immediate, RelocInfo::Mode rmode) { 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 280f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke imm32_ = immediate; 281f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke rmode_ = rmode; 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(const ExternalReference& f) { 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<int32_t>(f.address()); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::EXTERNAL_REFERENCE; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Smi* value) { 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = no_reg; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block imm32_ = reinterpret_cast<intptr_t>(value); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rmode_ = RelocInfo::NONE; 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOperand::Operand(Register rm) { 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rm_ = rm; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_ = no_reg; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ = LSL; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ = 0; 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Operand::is_reg() const { 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return rm_.is_valid() && 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rs_.is(no_reg) && 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_op_ == LSL && 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block shift_imm_ == 0; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::CheckBuffer() { 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (buffer_space() <= kGap) { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GrowBuffer(); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (pc_offset() >= next_buffer_check_) { 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckConstPool(false, true); 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::emit(Instr x) { 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CheckBuffer(); 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *reinterpret_cast<Instr*>(pc_) = x; 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pc_ += kInstrSize; 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_address_at(Address pc) { 333e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Address target_pc = pc; 334e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Instr instr = Memory::int32_at(target_pc); 335e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // If we have a bx instruction, the instruction before the bx is 336e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // what we need to patch. 337e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int32_t kBxInstMask = 0x0ffffff0; 338e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke static const int32_t kBxInstPattern = 0x012fff10; 339e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if ((instr & kBxInstMask) == kBxInstPattern) { 340e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke target_pc -= kInstrSize; 341e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke instr = Memory::int32_at(target_pc); 342e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef USE_BLX 3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // If we have a blx instruction, the instruction before it is 3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // what needs to be patched. 3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if ((instr & kBlxRegMask) == kBlxRegPattern) { 3486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block target_pc -= kInstrSize; 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block instr = Memory::int32_at(target_pc); 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang ASSERT(IsLdrPcImmediateOffset(instr)); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset = instr & 0xfff; // offset_12 is unsigned 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((instr & (1 << 23)) == 0) offset = -offset; // U bit defines offset sign 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify that the constant pool comes after the instruction referencing it. 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(offset >= -4); 358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return target_pc + offset + 8; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAddress Assembler::target_address_at(Address pc) { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Memory::Address_at(target_address_address_at(pc)); 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Assembler::deserialization_set_special_target_at( 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address constant_pool_entry, Address target) { 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Memory::Address_at(constant_pool_entry) = target; 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Assembler::set_external_target_at(Address constant_pool_entry, 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address target) { 375d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Memory::Address_at(constant_pool_entry) = target; 376d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Assembler::set_target_address_at(Address pc, Address target) { 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Memory::Address_at(target_address_address_at(pc)) = target; 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Intuitively, we would think it is necessary to flush the instruction cache 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after patching a target address in the code as follows: 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // CPU::FlushICache(pc, sizeof(target)); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // However, on ARM, no instruction was actually patched by the assignment 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // above; the target address is not part of an instruction, it is patched in 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the constant pool and is read via a data access; the instruction accessing 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // this address in the constant pool remains unchanged. 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_ARM_ASSEMBLER_ARM_INL_H_ 393