1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_MIPS_CODE_STUBS_MIPS_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_MIPS_CODE_STUBS_MIPS_H_ 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/mips/frames-mips.h" 944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1044f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 { 1144f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal { 1244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); 1544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass StringHelper : public AllStatic { 183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate code for copying a large number of characters. This function 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is allowed to spend extra time setting up conditions to make copying 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // faster. Copying of overlapping regions is not supported. 223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Dest register ends at the position after the last character written. 233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateCopyCharacters(MacroAssembler* masm, 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dest, 253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register src, 263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register count, 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding encoding); 293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compares two flat one-byte strings and returns result in v0. 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void GenerateCompareFlatOneByteStrings( 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Register left, Register right, Register scratch1, 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, Register scratch3, Register scratch4); 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compares two flat one-byte strings for equality and returns result in v0. 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void GenerateFlatOneByteStringEquals(MacroAssembler* masm, 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register left, Register right, 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3); 4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void GenerateOneByteCharsCompareLoop( 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Register left, Register right, Register length, 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, Register scratch3, 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* chars_not_equal); 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass StoreRegistersStateStub: public PlatformCodeStub { 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit StoreRegistersStateStub(Isolate* isolate) 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PlatformCodeStub(isolate) {} 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void GenerateAheadOfTime(Isolate* isolate); 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub); 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RestoreRegistersStateStub: public PlatformCodeStub { 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit RestoreRegistersStateStub(Isolate* isolate) 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PlatformCodeStub(isolate) {} 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static void GenerateAheadOfTime(Isolate* isolate); 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub); 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass RecordWriteStub: public PlatformCodeStub { 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub(Isolate* isolate, 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode fp_mode) 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PlatformCodeStub(isolate), 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch regs_(object, // An input reg. 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address, // An input reg. 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value) { // One scratch reg. 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch minor_key_ = ObjectBits::encode(object.code()) | 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ValueBits::encode(value.code()) | 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddressBits::encode(address.code()) | 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetActionBits::encode(remembered_set_action) | 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsModeBits::encode(fp_mode); 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub(uint32_t key, Isolate* isolate) 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {} 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum Mode { 1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STORE_BUFFER_ONLY, 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL, 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch INCREMENTAL_COMPACTION 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool SometimesSetsUpAFrame() override { return false; } 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { 1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const unsigned offset = masm->instr_at(pos) & kImm16Mask; 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, BNE | (zero_reg.code() << kRsShift) | 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Assembler::IsBne(masm->instr_at(pos))); 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const unsigned offset = masm->instr_at(pos) & kImm16Mask; 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->instr_at_put(pos, BEQ | (zero_reg.code() << kRsShift) | 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Assembler::IsBeq(masm->instr_at(pos))); 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static Mode GetMode(Code* stub) { 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr first_instruction = Assembler::instr_at(stub->instruction_start()); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Instr second_instruction = Assembler::instr_at(stub->instruction_start() + 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2 * Assembler::kInstrSize); 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBeq(first_instruction)) { 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL; 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Assembler::IsBne(first_instruction)); 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (Assembler::IsBeq(second_instruction)) { 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return INCREMENTAL_COMPACTION; 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Assembler::IsBne(second_instruction)); 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return STORE_BUFFER_ONLY; 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void Patch(Code* stub, Mode mode) { 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler masm(stub->GetIsolate(), stub->instruction_start(), 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stub->instruction_size(), CodeObjectRequired::kNo); 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (mode) { 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case STORE_BUFFER_ONLY: 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(GetMode(stub) == INCREMENTAL || 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMode(stub) == INCREMENTAL_COMPACTION); 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, 0); 1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchBranchIntoNop(&masm, 2 * Assembler::kInstrSize); 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL: 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, 0); 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case INCREMENTAL_COMPACTION: 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PatchNopIntoBranch(&masm, 2 * Assembler::kInstrSize); 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(GetMode(stub) == mode); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(stub->GetIsolate(), stub->instruction_start(), 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4 * Assembler::kInstrSize); 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // This is a helper class for freeing up 3 scratch registers. The input is 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // two registers that must be preserved and one scratch register provided by 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // the caller. 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RegisterAllocation { 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public: 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation(Register object, 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address, 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0) 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : object_(object), 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch address_(address), 1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scratch0_(scratch0) { 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(scratch0, object, address, no_reg)); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_); 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Save(MacroAssembler* masm) { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object_, address_, scratch1_, scratch0_)); 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't have to save scratch0_ because it was given to us as 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // a scratch register. 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->push(scratch1_); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void Restore(MacroAssembler* masm) { 1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->pop(scratch1_); 1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If we have to call into C then we need to save and restore all caller- 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // saved registers that were not already preserved. The scratch registers 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // will be restored by other means so we don't bother pushing them here. 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPush((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPushFPU(kCallerSavedFPU); 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode mode) { 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mode == kSaveFPRegs) { 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPopFPU(kCallerSavedFPU); 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch masm->MultiPop((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register object() { return object_; } 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register address() { return address_; } 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch0() { return scratch0_; } 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch inline Register scratch1() { return scratch1_; } 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private: 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object_; 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register address_; 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0_; 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch1_; 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch friend class RecordWriteStub; 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch enum OnNoNeedToInformIncrementalMarker { 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kReturnOnNoNeedToInformIncrementalMarker, 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch }; 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline Major MajorKey() const final { return RecordWrite; } 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Generate(MacroAssembler* masm) override; 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void GenerateIncremental(MacroAssembler* masm, Mode mode); 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch void CheckNeedsToInformIncrementalMarker( 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MacroAssembler* masm, 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch OnNoNeedToInformIncrementalMarker on_no_need, 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Mode mode); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InformIncrementalMarker(MacroAssembler* masm); 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Activate(Code* code) override { 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object() const { 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Register::from_code(ObjectBits::decode(minor_key_)); 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value() const { 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Register::from_code(ValueBits::decode(minor_key_)); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address() const { 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Register::from_code(AddressBits::decode(minor_key_)); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action() const { 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return RememberedSetActionBits::decode(minor_key_); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp_regs_mode() const { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SaveFPRegsModeBits::decode(minor_key_); 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ObjectBits: public BitField<int, 0, 5> {}; 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class ValueBits: public BitField<int, 5, 5> {}; 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class AddressBits: public BitField<int, 10, 5> {}; 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {}; 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {}; 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label slow_; 2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RegisterAllocation regs_; 27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(RecordWriteStub); 27644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Trampoline stub to call into native code. To call safely into native code 280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// in the presence of compacting GC (which can move code objects) we need to 281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// keep the code which called into native pinned in the memory. Currently the 282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// simplest approach is to generate such stub early enough so it can never be 283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// moved by GC 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass DirectCEntryStub: public PlatformCodeStub { 285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {} 287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch void GenerateCall(MacroAssembler* masm, Register target); 288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool NeedsImmovableCode() override { return true; } 291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); 294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NameDictionaryLookupStub: public PlatformCodeStub { 298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public: 299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; 300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionaryLookupStub(Isolate* isolate, LookupMode mode) 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : PlatformCodeStub(isolate) { 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch minor_key_ = LookupModeBits::encode(mode); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch static void GenerateNegativeLookup(MacroAssembler* masm, 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* miss, 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* done, 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register receiver, 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register properties, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch0); 313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static void GeneratePositiveLookup(MacroAssembler* masm, 315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* miss, 316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register elements, 318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register name, 319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register r0, 320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register r1); 321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool SometimesSetsUpAFrame() override { return false; } 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private: 325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kInlinedProbes = 4; 326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kTotalProbes = 20; 327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kCapacityOffset = 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kHeaderSize + 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kCapacityIndex * kPointerSize; 331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch static const int kElementsStartOffset = 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kHeaderSize + 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kElementsStartIndex * kPointerSize; 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupMode mode() const { return LookupModeBits::decode(minor_key_); } 337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); 342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}; 34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_MIPS_CODE_STUBS_MIPS_H_ 349