1b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#ifndef V8_ARM_CODE_STUBS_ARM_H_ 665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#define V8_ARM_CODE_STUBS_ARM_H_ 765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace v8 { 965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace internal { 1065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 12ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); 13ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 14ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgclass StringHelper : public AllStatic { 162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org public: 172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // Generate code for copying a large number of characters. This function 182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // is allowed to spend extra time setting up conditions to make copying 192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // faster. Copying of overlapping regions is not supported. 202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org // Dest register ends at the position after the last character written. 21fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org static void GenerateCopyCharacters(MacroAssembler* masm, 22fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org Register dest, 23fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org Register src, 24fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org Register count, 25fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org Register scratch, 26fd703f3d69389b9129ab38adb1caeb2be7a21ecfmachenbach@chromium.org String::Encoding encoding); 272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org 282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Compares two flat one-byte strings and returns result in r0. 292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org static void GenerateCompareFlatOneByteStrings( 302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org MacroAssembler* masm, Register left, Register right, Register scratch1, 312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, Register scratch3, Register scratch4); 322c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org 332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Compares two flat one-byte strings for equality and returns result in r0. 342c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org static void GenerateFlatOneByteStringEquals(MacroAssembler* masm, 352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register left, Register right, 3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch1, 3765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Register scratch2, 382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch3); 3965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 401c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private: 412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org static void GenerateOneByteCharsCompareLoop( 422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org MacroAssembler* masm, Register left, Register right, Register length, 432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, Register scratch2, Label* chars_not_equal); 449aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); 4665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 4765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 4865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 4965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// This stub can convert a signed int32 to a heap number (double). It does 5065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// not work for int32s that are in Smi range! No GC occurs during this stub 5165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// so you don't have to set up the frame. 52a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass WriteInt32ToHeapNumberStub : public PlatformCodeStub { 5365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public: 549aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org WriteInt32ToHeapNumberStub(Isolate* isolate, Register the_int, 559aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register the_heap_number, Register scratch) 569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org : PlatformCodeStub(isolate) { 579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org minor_key_ = IntRegisterBits::encode(the_int.code()) | 589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org HeapNumberRegisterBits::encode(the_heap_number.code()) | 599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org ScratchRegisterBits::encode(scratch.code()); 609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 6165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 628432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate); 63c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 6465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private: 659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register the_int() const { 669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(IntRegisterBits::decode(minor_key_)); 679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register the_heap_number() const { 709aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(HeapNumberRegisterBits::decode(minor_key_)); 719aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 729aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register scratch() const { 749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(ScratchRegisterBits::decode(minor_key_)); 759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 7665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 7765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Minor key encoding in 16 bits. 7865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org class IntRegisterBits: public BitField<int, 0, 4> {}; 7965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; 8065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org class ScratchRegisterBits: public BitField<int, 8, 4> {}; 8165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 8342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DEFINE_PLATFORM_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub); 8465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org}; 8565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 8665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 87a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass RecordWriteStub: public PlatformCodeStub { 88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 89f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub(Isolate* isolate, 90f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Register object, 91c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 92c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 93c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode fp_mode) 95f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org : PlatformCodeStub(isolate), 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com regs_(object, // An input reg. 97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address, // An input reg. 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value) { // One scratch reg. 999aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org minor_key_ = ObjectBits::encode(object.code()) | 1009aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org ValueBits::encode(value.code()) | 1019aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org AddressBits::encode(address.code()) | 1029aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org RememberedSetActionBits::encode(remembered_set_action) | 1039aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org SaveFPRegsModeBits::encode(fp_mode); 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 10642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org RecordWriteStub(uint32_t key, Isolate* isolate) 10742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {} 10842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum Mode { 110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STORE_BUFFER_ONLY, 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INCREMENTAL, 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com INCREMENTAL_COMPACTION 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual bool SometimesSetsUpAFrame() { return false; } 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20)); 119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::IsTstImmediate(masm->instr_at(pos))); 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27); 124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::IsBranch(masm->instr_at(pos))); 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static Mode GetMode(Code* stub) { 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Instr first_instruction = Assembler::instr_at(stub->instruction_start()); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Instr second_instruction = Assembler::instr_at(stub->instruction_start() + 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Assembler::kInstrSize); 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Assembler::IsBranch(first_instruction)) { 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return INCREMENTAL; 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 136e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::IsTstImmediate(first_instruction)); 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (Assembler::IsBranch(second_instruction)) { 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return INCREMENTAL_COMPACTION; 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 142e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::IsTstImmediate(second_instruction)); 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return STORE_BUFFER_ONLY; 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static void Patch(Code* stub, Mode mode) { 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler masm(NULL, 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_start(), 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com stub->instruction_size()); 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com switch (mode) { 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case STORE_BUFFER_ONLY: 153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(GetMode(stub) == INCREMENTAL || 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMode(stub) == INCREMENTAL_COMPACTION); 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PatchBranchIntoNop(&masm, 0); 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PatchBranchIntoNop(&masm, Assembler::kInstrSize); 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case INCREMENTAL: 159e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PatchNopIntoBranch(&masm, 0); 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com case INCREMENTAL_COMPACTION: 163e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com PatchNopIntoBranch(&masm, Assembler::kInstrSize); 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com break; 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(GetMode(stub) == mode); 1685de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(stub->instruction_start(), 1695de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org 2 * Assembler::kInstrSize); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1726313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 1736313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // This is a helper class for freeing up 3 scratch registers. The input is 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // two registers that must be preserved and one scratch register provided by 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the caller. 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class RegisterAllocation { 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public: 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RegisterAllocation(Register object, 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0) 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com : object_(object), 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com address_(address), 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch0_(scratch0) { 186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(scratch0, object, address, no_reg)); 1871e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_); 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Save(MacroAssembler* masm) { 191e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(object_, address_, scratch1_, scratch0_)); 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't have to save scratch0_ because it was given to us as 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a scratch register. 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->push(scratch1_); 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void Restore(MacroAssembler* masm) { 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->pop(scratch1_); 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If we have to call into C then we need to save and restore all caller- 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // saved registers that were not already preserved. The scratch registers 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // will be restored by other means so we don't bother pushing them here. 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mode == kSaveFPRegs) { 20777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org masm->SaveFPRegs(sp, scratch0_); 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void RestoreCallerSaveRegisters(MacroAssembler*masm, 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode mode) { 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mode == kSaveFPRegs) { 21477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org masm->RestoreFPRegs(sp, scratch0_); 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register object() { return object_; } 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register address() { return address_; } 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register scratch0() { return scratch0_; } 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline Register scratch1() { return scratch1_; } 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private: 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object_; 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address_; 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0_; 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1_; 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com friend class RecordWriteStub; 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum OnNoNeedToInformIncrementalMarker { 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kReturnOnNoNeedToInformIncrementalMarker, 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kUpdateRememberedSetOnNoNeedToInformIncrementalMarker 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 23842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; } 2399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 24042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org virtual void Generate(MacroAssembler* masm) OVERRIDE; 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void GenerateIncremental(MacroAssembler* masm, Mode mode); 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckNeedsToInformIncrementalMarker( 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MacroAssembler* masm, 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com OnNoNeedToInformIncrementalMarker on_no_need, 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Mode mode); 246f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void InformIncrementalMarker(MacroAssembler* masm); 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2489aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org void Activate(Code* code) { 2499aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); 2509aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2529aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register object() const { 2539aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(ObjectBits::decode(minor_key_)); 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2569aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value() const { 2579aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(ValueBits::decode(minor_key_)); 2589aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 2599aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2609aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register address() const { 2619aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return Register::from_code(AddressBits::decode(minor_key_)); 2629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 2639aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org RememberedSetAction remembered_set_action() const { 2659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return RememberedSetActionBits::decode(minor_key_); 2669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 2679aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2689aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org SaveFPRegsMode save_fp_regs_mode() const { 2699aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org return SaveFPRegsModeBits::decode(minor_key_); 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class ObjectBits: public BitField<int, 0, 4> {}; 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class ValueBits: public BitField<int, 4, 4> {}; 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class AddressBits: public BitField<int, 8, 4> {}; 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {}; 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {}; 277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label slow_; 279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RegisterAllocation regs_; 2809aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2819aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org DISALLOW_COPY_AND_ASSIGN(RecordWriteStub); 282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}; 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 28583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Trampoline stub to call into native code. To call safely into native code 28683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// in the presence of compacting GC (which can move code objects) we need to 28783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// keep the code which called into native pinned in the memory. Currently the 28883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// simplest approach is to generate such stub early enough so it can never be 28983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// moved by GC 290a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass DirectCEntryStub: public PlatformCodeStub { 29183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org public: 292f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {} 29349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org void GenerateCall(MacroAssembler* masm, Register target); 29483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 29583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org private: 2964d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org bool NeedsImmovableCode() { return true; } 2979aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org 2986313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 29942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); 30083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org}; 30183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 30283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 303750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgclass NameDictionaryLookupStub: public PlatformCodeStub { 3041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org public: 3051c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; 3061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 307f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org NameDictionaryLookupStub(Isolate* isolate, LookupMode mode) 3089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org : PlatformCodeStub(isolate) { 3099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org minor_key_ = LookupModeBits::encode(mode); 3109aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org } 3111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com static void GenerateNegativeLookup(MacroAssembler* masm, 313394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 314394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* done, 315394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register receiver, 316394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register properties, 317750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 318394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch0); 319394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 3201c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static void GeneratePositiveLookup(MacroAssembler* masm, 3211c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Label* miss, 3221c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Label* done, 3231c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register elements, 3241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register name, 3251c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register r0, 3261c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Register r1); 3271c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com virtual bool SometimesSetsUpAFrame() { return false; } 329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3301c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private: 3311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kInlinedProbes = 4; 3321c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kTotalProbes = 20; 3331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 3341c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kCapacityOffset = 335750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kHeaderSize + 336750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kCapacityIndex * kPointerSize; 3371c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 3381c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org static const int kElementsStartOffset = 339750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kHeaderSize + 340750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 3411c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 3429aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org LookupMode mode() const { return LookupModeBits::decode(minor_key_); } 3431c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 3441c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org class LookupModeBits: public BitField<LookupMode, 0, 1> {}; 3451c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 3466313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); 34742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); 3481c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}; 3491c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 35065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} } // namespace v8::internal 35165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 35265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#endif // V8_ARM_CODE_STUBS_ARM_H_ 353