1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright (c) 1994-2006 Sun Microsystems Inc. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// All Rights Reserved. 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Redistribution and use in source and binary forms, with or without 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modification, are permitted provided that the following conditions are 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// met: 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistributions of source code must retain the above copyright notice, 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// this list of conditions and the following disclaimer. 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Redistribution in binary form must reproduce the above copyright 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// notice, this list of conditions and the following disclaimer in the 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// documentation and/or other materials provided with the distribution. 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// - Neither the name of Sun Microsystems or the names of contributors may 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// be used to endorse or promote products derived from this software without 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// specific prior written permission. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The original source code covered by the above license above has been 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// modified significantly by Google Inc. 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A light-weight IA32 Assembler. 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_X87_ASSEMBLER_X87_INL_H_ 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_X87_ASSEMBLER_X87_INL_H_ 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x87/assembler-x87.h" 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h" 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 4462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool CpuFeatures::SupportsCrankshaft() { return true; } 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool CpuFeatures::SupportsSimd128() { return false; } 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const byte kCallOpcode = 0xE8; 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kNoCodeAgeSequenceLength = 5; 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The modes possibly affected by apply must be in kApplyMask. 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::apply(intptr_t delta) { 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc_); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p -= delta; // Relocate entry. 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsCodeAgeSequence(rmode_)) { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*pc_ == kCallOpcode) { 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p -= delta; // Relocate entry. 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) { 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Special handling of a debug break slot when a break point is set (call 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction has been inserted). 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t* p = reinterpret_cast<int32_t*>( 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p -= delta; // Relocate entry. 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsInternalReference(rmode_)) { 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // absolute code pointer inside code object moves with the code object. 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc_); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p += delta; // Relocate entry. 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address() { 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Assembler::target_address_at(pc_, host_); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_address_address() { 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch || rmode_ == EMBEDDED_OBJECT 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch || rmode_ == EXTERNAL_REFERENCE); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Address>(pc_); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::constant_pool_entry_address() { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return NULL; 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RelocInfo::target_address_size() { 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Assembler::kSpecialTargetSize; 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject* RelocInfo::target_object() { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Memory::Object_at(pc_); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Memory::Object_Handle_at(pc_); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_object(Object* target, 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::Object_at(pc_) = target; 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate_, pc_, sizeof(Address)); 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (write_barrier_mode == UPDATE_WRITE_BARRIER && 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch host() != NULL && 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->IsHeapObject()) { 128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch host()->GetHeap()->RecordWriteIntoCode(host(), this, target); 1293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 1303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch host(), this, HeapObject::cast(target)); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_external_reference() { 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::EXTERNAL_REFERENCE); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Memory::Address_at(pc_); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference() { 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rmode_ == INTERNAL_REFERENCE); 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Memory::Address_at(pc_); 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::target_internal_reference_address() { 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(rmode_ == INTERNAL_REFERENCE); 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return reinterpret_cast<Address>(pc_); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress RelocInfo::target_runtime_entry(Assembler* origin) { 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsRuntimeEntry(rmode_)); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Address>(*reinterpret_cast<int32_t*>(pc_)); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_runtime_entry(Address target, 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsRuntimeEntry(rmode_)); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (target_address() != target) { 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_target_address(target, write_barrier_mode, icache_flush_mode); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Cell> RelocInfo::target_cell_handle() { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address address = Memory::Address_at(pc_); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Cell>(reinterpret_cast<Cell**>(address)); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCell* RelocInfo::target_cell() { 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Cell::FromValueAddress(Memory::Address_at(pc_)); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_target_cell(Cell* cell, 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch WriteBarrierMode write_barrier_mode, 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(cell->IsCell()); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CELL); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address address = cell->address() + Cell::kValueOffset; 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::Address_at(pc_) = address; 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate_, pc_, sizeof(Address)); 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { 193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, 194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cell); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) { 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Memory::Object_Handle_at(pc_ + 1); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCode* RelocInfo::code_age_stub() { 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Code::GetCodeFromTargetAddress( 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::target_address_at(pc_ + 1, host_)); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::set_code_age_stub(Code* stub, 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(*pc_ == kCallOpcode); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at( 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate_, pc_ + 1, host_, stub->instruction_start(), icache_flush_mode); 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress RelocInfo::debug_call_address() { 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Assembler::target_address_at(location, host_); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RelocInfo::set_debug_call_address(Address target) { 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, location, host_, target); 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (host() != NULL) { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch host(), this, HeapObject::cast(target_code)); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::WipeOut() { 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsInternalReference(rmode_)) { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Memory::Address_at(pc_) = NULL; 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Effectively write zero into the relocation. 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::set_target_address_at(isolate_, pc_, host_, 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ + sizeof(int32_t)); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochtemplate <typename ObjectVisitor> 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode = rmode(); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == RelocInfo::EMBEDDED_OBJECT) { 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitEmbeddedPointer(this); 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, pc_, sizeof(Address)); 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeTarget(mode)) { 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitCodeTarget(this); 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::CELL) { 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitCell(this); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitExternalReference(this); 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch visitor->VisitInternalReference(this); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeAgeSequence(mode)) { 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitCodeAgeSequence(this); 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitDebugTarget(this); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsRuntimeEntry(mode)) { 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch visitor->VisitRuntimeEntry(this); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename StaticVisitor> 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RelocInfo::Visit(Heap* heap) { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode = rmode(); 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode == RelocInfo::EMBEDDED_OBJECT) { 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitEmbeddedPointer(heap, this); 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(heap->isolate(), pc_, sizeof(Address)); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeTarget(mode)) { 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitCodeTarget(heap, this); 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::CELL) { 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitCell(heap, this); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitExternalReference(this); 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (mode == RelocInfo::INTERNAL_REFERENCE) { 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StaticVisitor::VisitInternalReference(this); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (RelocInfo::IsCodeAgeSequence(mode)) { 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitCodeAgeSequence(heap, this); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (RelocInfo::IsDebugBreakSlot(mode) && 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IsPatchedDebugBreakSlotSequence()) { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitDebugTarget(heap, this); 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsRuntimeEntry(mode)) { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StaticVisitor::VisitRuntimeEntry(this); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(int x) { 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = x; 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE32; 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochImmediate::Immediate(Address x, RelocInfo::Mode rmode) { 3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch x_ = reinterpret_cast<int32_t>(x); 3133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch rmode_ = rmode; 3143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(const ExternalReference& ext) { 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<int32_t>(ext.address()); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::EXTERNAL_REFERENCE; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Label* internal_offset) { 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<int32_t>(internal_offset); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::INTERNAL_REFERENCE; 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Handle<Object> handle) { 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference using_raw_address; 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify all Objects referred by code are NOT in new space. 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* obj = *handle; 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (obj->IsHeapObject()) { 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<intptr_t>(handle.location()); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::EMBEDDED_OBJECT; 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // no relocation needed 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<intptr_t>(obj); 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE32; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Smi* value) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<intptr_t>(value); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE32; 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochImmediate::Immediate(Address addr) { 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x_ = reinterpret_cast<int32_t>(addr); 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = RelocInfo::NONE32; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x) { 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<uint32_t*>(pc_) = x; 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pc_ += sizeof(uint32_t); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::emit_q(uint64_t x) { 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *reinterpret_cast<uint64_t*>(pc_) = x; 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pc_ += sizeof(uint64_t); 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Object> handle) { 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference heap_object_check; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Verify all Objects referred by code are NOT in new space. 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* obj = *handle; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (obj->IsHeapObject()) { 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(reinterpret_cast<intptr_t>(handle.location()), 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::EMBEDDED_OBJECT); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // no relocation needed 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(reinterpret_cast<intptr_t>(obj)); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(uint32_t x, RelocInfo::Mode rmode, TypeFeedbackId id) { 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (rmode == RelocInfo::CODE_TARGET && !id.IsNone()) { 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(RelocInfo::CODE_TARGET_WITH_ID, id.ToInt()); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!RelocInfo::IsNone(rmode) 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch && rmode != RelocInfo::CODE_AGE_SEQUENCE) { 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordRelocInfo(rmode); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(x); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(Handle<Code> code, 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode rmode, 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId id) { 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference embedding_raw_address; 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(reinterpret_cast<intptr_t>(code.location()), rmode, id); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit(const Immediate& x) { 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (x.rmode_ == RelocInfo::INTERNAL_REFERENCE) { 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* label = reinterpret_cast<Label*>(x.x_); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_code_relative_offset(label); 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!RelocInfo::IsNone(x.rmode_)) RecordRelocInfo(x.rmode_); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(x.x_); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_code_relative_offset(Label* label) { 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (label->is_bound()) { 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t pos; 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos = label->pos() + Code::kHeaderSize - kHeapObjectTag; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(pos); 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit_disp(label, Displacement::CODE_RELATIVE); 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid Assembler::emit_b(Immediate x) { 4223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(x.is_int8() || x.is_uint8()); 4233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch uint8_t value = static_cast<uint8_t>(x.x_); 4243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch *pc_++ = value; 4253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_w(const Immediate& x) { 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsNone(x.rmode_)); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint16_t value = static_cast<uint16_t>(x.x_); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<uint16_t*>(pc_)[0] = value; 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pc_ += sizeof(uint16_t); 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAddress Assembler::target_address_at(Address pc, Address constant_pool) { 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Address constant_pool, Address target, 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ICacheFlushMode icache_flush_mode) { 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(pc); 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p = target - (pc + sizeof(int32_t)); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (icache_flush_mode != SKIP_ICACHE_FLUSH) { 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(isolate, p, sizeof(int32_t)); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochAddress Assembler::target_address_at(Address pc, Code* code) { 45162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return target_address_at(pc, constant_pool); 45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 45462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 45562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid Assembler::set_target_address_at(Isolate* isolate, Address pc, Code* code, 45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address target, 45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ICacheFlushMode icache_flush_mode) { 45862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Address constant_pool = code ? code->constant_pool() : NULL; 45962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch set_target_address_at(isolate, pc, constant_pool, target, icache_flush_mode); 46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochAddress Assembler::target_address_from_return_address(Address pc) { 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pc - kCallTargetAddressOffset; 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDisplacement Assembler::disp_at(Label* L) { 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Displacement(long_at(L->pos())); 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::disp_at_put(Label* L, Displacement disp) { 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch long_at_put(L->pos(), disp.data()); 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_disp(Label* L, Displacement::Type type) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Displacement disp(L, type); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch L->link_to(pc_offset()); 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch emit(static_cast<int>(disp.data())); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Assembler::emit_near_disp(Label* L) { 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch byte disp = 0x00; 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (L->is_near_linked()) { 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset = L->near_link_pos() - pc_offset(); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(offset)); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch disp = static_cast<byte>(offset & 0xFF); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch L->link_to(pc_offset(), Label::kNear); 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *pc_++ = disp; 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Assembler::deserialization_set_target_internal_reference_at( 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate, Address pc, Address target, RelocInfo::Mode mode) { 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Memory::Address_at(pc) = target; 499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_modrm(int mod, Register rm) { 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((mod & -4) == 0); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buf_[0] = mod << 6 | rm.code(); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch len_ = 1; 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_sib(ScaleFactor scale, Register index, Register base) { 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1); 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((scale & -4) == 0); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use SIB with no index register only for base esp. 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!index.is(esp) || base.is(esp)); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch buf_[1] = scale << 6 | index.code() << 3 | base.code(); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch len_ = 2; 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_disp8(int8_t disp) { 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1 || len_ == 2); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *reinterpret_cast<int8_t*>(&buf_[len_++]) = disp; 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Operand::set_dispr(int32_t disp, RelocInfo::Mode rmode) { 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(len_ == 1 || len_ == 2); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *p = disp; 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch len_ += sizeof(int32_t); 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode_ = rmode; 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Register reg) { 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // reg 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_modrm(3, reg); 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(int32_t disp, RelocInfo::Mode rmode) { 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [disp/r] 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_modrm(0, ebp); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_dispr(disp, rmode); 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochOperand::Operand(Immediate imm) { 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // [disp/r] 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_modrm(0, ebp); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_dispr(imm.x_, imm.rmode_); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_X87_ASSEMBLER_X87_INL_H_ 555