13100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Copyright (c) 1994-2006 Sun Microsystems Inc. 23100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// All Rights Reserved. 33100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Redistribution and use in source and binary forms, with or without 53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modification, are permitted provided that the following conditions are 63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// met: 73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistributions of source code must retain the above copyright notice, 93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// this list of conditions and the following disclaimer. 103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Redistribution in binary form must reproduce the above copyright 123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// notice, this list of conditions and the following disclaimer in the 133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// documentation and/or other materials provided with the distribution. 143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// - Neither the name of Sun Microsystems or the names of contributors may 163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// be used to endorse or promote products derived from this software without 173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// specific prior written permission. 183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// 193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The original source code covered by the above license above has been 323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// modified significantly by Google Inc. 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#ifndef V8_MIPS_ASSEMBLER_MIPS_INL_H_ 373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define V8_MIPS_ASSEMBLER_MIPS_INL_H_ 383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "mips/assembler-mips.h" 403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include "cpu.h" 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "debug.h" 433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace v8 { 463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace internal { 473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Operand and MemOperand. 503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(int32_t immediate, RelocInfo::Mode rmode) { 523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rm_ = no_reg; 533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu imm32_ = immediate; 543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rmode_ = rmode; 553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(const ExternalReference& f) { 593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rm_ = no_reg; 603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu imm32_ = reinterpret_cast<int32_t>(f.address()); 613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rmode_ = RelocInfo::EXTERNAL_REFERENCE; 623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(Smi* value) { 663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rm_ = no_reg; 673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu imm32_ = reinterpret_cast<intptr_t>(value); 683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rmode_ = RelocInfo::NONE; 693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuOperand::Operand(Register rm) { 733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu rm_ = rm; 743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescubool Operand::is_reg() const { 783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return rm_.is_valid(); 793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint FPURegister::ToAllocationIndex(FPURegister reg) { 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(reg.code() % 2 == 0); 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(reg.code() / 2 < kNumAllocatableRegisters); 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(reg.is_valid()); 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!reg.is(kDoubleRegZero)); 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!reg.is(kLithiumScratchDouble)); 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (reg.code() / 2); 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 91c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 93257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// RelocInfo. 943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::apply(intptr_t delta) { 96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (IsCodeTarget(rmode_)) { 97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask; 98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask; 99589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (scope1 != scope2) { 101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Assembler::JumpLabelToJumpRegister(pc_); 102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 103589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch } 1043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (IsInternalReference(rmode_)) { 1053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Absolute code pointer inside code object moves with the code object. 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* p = reinterpret_cast<byte*>(pc_); 1073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int count = Assembler::RelocateInternalReference(p, delta); 1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CPU::FlushICache(p, count * sizeof(uint32_t)); 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::target_address() { 1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 1153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Assembler::target_address_at(pc_); 1163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::target_address_address() { 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IsCodeTarget(rmode_) || 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rmode_ == RUNTIME_ENTRY || 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rmode_ == EMBEDDED_OBJECT || 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch rmode_ == EXTERNAL_REFERENCE); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Read the address of the word containing the target_address in an 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction stream. 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The only architecture-independent user of this function is the serializer. 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The serializer uses it to find out how many raw bytes of instruction to 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // output before the next target. 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // For an instruction like LUI/ORI where the target bits are mixed into the 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction bits, the size of the target will be zero, indicating that the 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // serializer should not step forward in memory after a target is resolved 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // and written. In this case the target_address_address function should 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // return the end of the instructions to be patched, allowing the 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // deserializer to deserialize the instructions as raw bytes and put them in 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // place, ready to be patched with the target. After jump optimization, 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // that is the address of the instruction that follows J/JAL/JR/JALR 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // instruction. 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<Address>( 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch pc_ + Assembler::kInstructionsFor32BitConstant * Assembler::kInstrSize); 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint RelocInfo::target_address_size() { 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Assembler::kSpecialTargetSize; 1453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_address(Address target, WriteBarrierMode mode) { 1493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == RUNTIME_ENTRY); 1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Assembler::set_target_address_at(pc_, target); 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && host() != NULL && IsCodeTarget(rmode_)) { 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), this, HeapObject::cast(target_code)); 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject* RelocInfo::target_object() { 1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return reinterpret_cast<Object*>(Assembler::target_address_at(pc_)); 1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> RelocInfo::target_object_handle(Assembler* origin) { 1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return Handle<Object>(reinterpret_cast<Object**>( 1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Assembler::target_address_at(pc_))); 1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject** RelocInfo::target_object_address() { 17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Provide a "natural pointer" to the embedded object, 17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // which can be de-referenced during heap iteration. 1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 176257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reconstructed_obj_ptr_ = 177257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reinterpret_cast<Object*>(Assembler::target_address_at(pc_)); 178257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return &reconstructed_obj_ptr_; 1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_object(Object* target, WriteBarrierMode mode) { 1833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); 1843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Assembler::set_target_address_at(pc_, reinterpret_cast<Address>(target)); 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host() != NULL && 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->IsHeapObject()) { 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWrite( 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), &Memory::Object_at(pc_), HeapObject::cast(target)); 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 1923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 1943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress* RelocInfo::target_reference_address() { 1953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu ASSERT(rmode_ == EXTERNAL_REFERENCE); 196257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch reconstructed_adr_ptr_ = Assembler::target_address_at(pc_); 197257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return &reconstructed_adr_ptr_; 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 20144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<JSGlobalPropertyCell> RelocInfo::target_cell_handle() { 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address = Memory::Address_at(pc_); 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Handle<JSGlobalPropertyCell>( 20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<JSGlobalPropertyCell**>(address)); 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 20944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockJSGlobalPropertyCell* RelocInfo::target_cell() { 21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address = Memory::Address_at(pc_); 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* object = HeapObject::FromAddress( 21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block address - JSGlobalPropertyCell::kValueOffset); 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return reinterpret_cast<JSGlobalPropertyCell*>(object); 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RelocInfo::set_target_cell(JSGlobalPropertyCell* cell, 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch WriteBarrierMode mode) { 22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(rmode_ == RelocInfo::GLOBAL_PROPERTY_CELL); 22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address = cell->address() + JSGlobalPropertyCell::kValueOffset; 22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Memory::Address_at(pc_) = address; 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == UPDATE_WRITE_BARRIER && host() != NULL) { 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // TODO(1550) We are passing NULL as a slot because cell can never be on 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // evacuation candidate. 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWrite( 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), NULL, cell); 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuAddress RelocInfo::call_address() { 23344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The pc_ offset of 0 assumes mips patched return sequence per 23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or 23744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot(). 23844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Assembler::target_address_at(pc_); 2393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::set_call_address(Address target) { 24344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The pc_ offset of 0 assumes mips patched return sequence per 24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // debug-mips.cc BreakLocationIterator::SetDebugBreakAtReturn(), or 24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // debug break slot per BreakLocationIterator::SetDebugBreakAtSlot(). 24844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Assembler::set_target_address_at(pc_, target); 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (host() != NULL) { 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* target_code = Code::GetCodeFromTargetAddress(target); 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch host(), this, HeapObject::cast(target_code)); 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject* RelocInfo::call_object() { 2583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return *call_object_address(); 2593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuObject** RelocInfo::call_object_address() { 26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || 26444f0eee88ff00398ff7f715fab053374d808c90dSteve Block (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); 2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize); 2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid RelocInfo::set_call_object(Object* target) { 2703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu *call_object_address() = target; 2713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 2723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescubool RelocInfo::IsPatchedReturnSequence() { 27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr0 = Assembler::instr_at(pc_); 27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize); 27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool patched_return = ((instr0 & kOpcodeMask) == LUI && 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block (instr1 & kOpcodeMask) == ORI && 280589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ((instr2 & kOpcodeMask) == JAL || 281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ((instr2 & kOpcodeMask) == SPECIAL && 282589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch (instr2 & kFunctionFieldMask) == JALR))); 28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return patched_return; 28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 28744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool RelocInfo::IsPatchedDebugBreakSlotSequence() { 28844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Instr current_instr = Assembler::instr_at(pc_); 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP); 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(ObjectVisitor* visitor) { 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block RelocInfo::Mode mode = rmode(); 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (mode == RelocInfo::EMBEDDED_OBJECT) { 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitEmbeddedPointer(this); 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (RelocInfo::IsCodeTarget(mode)) { 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block visitor->VisitCodeTarget(this); 299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch visitor->VisitGlobalPropertyCell(this); 30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch visitor->VisitExternalReference(this); 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): Get a cached isolate below. 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (((RelocInfo::IsJSReturn(mode) && 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsPatchedReturnSequence()) || 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (RelocInfo::IsDebugBreakSlot(mode) && 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsPatchedDebugBreakSlotSequence())) && 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->debug()->has_break_points()) { 31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block visitor->VisitDebugTarget(this); 3113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif 31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (mode == RelocInfo::RUNTIME_ENTRY) { 31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block visitor->VisitRuntimeEntry(this); 31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 31644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 31744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 31844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate<typename StaticVisitor> 31944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RelocInfo::Visit(Heap* heap) { 32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block RelocInfo::Mode mode = rmode(); 32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (mode == RelocInfo::EMBEDDED_OBJECT) { 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitEmbeddedPointer(heap, this); 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (RelocInfo::IsCodeTarget(mode)) { 324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StaticVisitor::VisitCodeTarget(heap, this); 325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (mode == RelocInfo::GLOBAL_PROPERTY_CELL) { 326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StaticVisitor::VisitGlobalPropertyCell(heap, this); 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StaticVisitor::VisitExternalReference(this); 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (heap->isolate()->debug()->has_break_points() && 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ((RelocInfo::IsJSReturn(mode) && 33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block IsPatchedReturnSequence()) || 33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block (RelocInfo::IsDebugBreakSlot(mode) && 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block IsPatchedDebugBreakSlotSequence()))) { 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StaticVisitor::VisitDebugTarget(heap, this); 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (mode == RelocInfo::RUNTIME_ENTRY) { 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block StaticVisitor::VisitRuntimeEntry(this); 33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------- 344257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Assembler. 3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::CheckBuffer() { 3483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (buffer_space() <= kGap) { 3493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu GrowBuffer(); 3503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 3513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 3523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 35444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Assembler::CheckTrampolinePoolQuick() { 35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (pc_offset() >= next_buffer_check_) { 35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckTrampolinePool(); 35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Assembler::emit(Instr x) { 3623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!is_buffer_growth_blocked()) { 3633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CheckBuffer(); 3643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu *reinterpret_cast<Instr*>(pc_) = x; 3663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu pc_ += kInstrSize; 36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CheckTrampolinePoolQuick(); 3683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 3693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} } // namespace v8::internal 3723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#endif // V8_MIPS_ASSEMBLER_MIPS_INL_H_ 374