| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_MIPS_CODE_STUBS_ARM_H_ | 5 #ifndef V8_PPC_CODE_STUBS_PPC_H_ |
| 6 #define V8_MIPS_CODE_STUBS_ARM_H_ | 6 #define V8_PPC_CODE_STUBS_PPC_H_ |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 | 10 |
| 11 | 11 |
| 12 void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); | 12 void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code); |
| 13 | 13 |
| 14 | 14 |
| 15 class StringHelper : public AllStatic { | 15 class StringHelper : public AllStatic { |
| 16 public: | 16 public: |
| 17 // Generate code for copying a large number of characters. This function | 17 // Generate code for copying a large number of characters. This function |
| 18 // is allowed to spend extra time setting up conditions to make copying | 18 // is allowed to spend extra time setting up conditions to make copying |
| 19 // faster. Copying of overlapping regions is not supported. | 19 // faster. Copying of overlapping regions is not supported. |
| 20 // Dest register ends at the position after the last character written. | 20 // Dest register ends at the position after the last character written. |
| 21 static void GenerateCopyCharacters(MacroAssembler* masm, | 21 static void GenerateCopyCharacters(MacroAssembler* masm, Register dest, |
| 22 Register dest, | 22 Register src, Register count, |
| 23 Register src, | |
| 24 Register count, | |
| 25 Register scratch, | 23 Register scratch, |
| 26 String::Encoding encoding); | 24 String::Encoding encoding); |
| 27 | 25 |
| 28 // Compares two flat one-byte strings and returns result in v0. | 26 // Compares two flat one-byte strings and returns result in r0. |
| 29 static void GenerateCompareFlatOneByteStrings( | 27 static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm, |
| 30 MacroAssembler* masm, Register left, Register right, Register scratch1, | 28 Register left, Register right, |
| 31 Register scratch2, Register scratch3, Register scratch4); | 29 Register scratch1, |
| 30 Register scratch2, |
| 31 Register scratch3); |
| 32 | 32 |
| 33 // Compares two flat one-byte strings for equality and returns result in v0. | 33 // Compares two flat one-byte strings for equality and returns result in r0. |
| 34 static void GenerateFlatOneByteStringEquals(MacroAssembler* masm, | 34 static void GenerateFlatOneByteStringEquals(MacroAssembler* masm, |
| 35 Register left, Register right, | 35 Register left, Register right, |
| 36 Register scratch1, | 36 Register scratch1, |
| 37 Register scratch2, | 37 Register scratch2); |
| 38 Register scratch3); | |
| 39 | 38 |
| 40 private: | 39 private: |
| 41 static void GenerateOneByteCharsCompareLoop( | 40 static void GenerateOneByteCharsCompareLoop(MacroAssembler* masm, |
| 42 MacroAssembler* masm, Register left, Register right, Register length, | 41 Register left, Register right, |
| 43 Register scratch1, Register scratch2, Register scratch3, | 42 Register length, |
| 44 Label* chars_not_equal); | 43 Register scratch1, |
| 44 Label* chars_not_equal); |
| 45 | 45 |
| 46 DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); | 46 DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); |
| 47 }; | 47 }; |
| 48 | 48 |
| 49 | 49 |
| 50 class StoreRegistersStateStub: public PlatformCodeStub { | 50 class StoreRegistersStateStub : public PlatformCodeStub { |
| 51 public: | 51 public: |
| 52 explicit StoreRegistersStateStub(Isolate* isolate) | 52 explicit StoreRegistersStateStub(Isolate* isolate) |
| 53 : PlatformCodeStub(isolate) {} | 53 : PlatformCodeStub(isolate) {} |
| 54 | 54 |
| 55 static void GenerateAheadOfTime(Isolate* isolate); | 55 static void GenerateAheadOfTime(Isolate* isolate); |
| 56 | 56 |
| 57 private: | 57 private: |
| 58 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); | 58 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
| 59 DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub); | 59 DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub); |
| 60 }; | 60 }; |
| 61 | 61 |
| 62 | 62 |
| 63 class RestoreRegistersStateStub: public PlatformCodeStub { | 63 class RestoreRegistersStateStub : public PlatformCodeStub { |
| 64 public: | 64 public: |
| 65 explicit RestoreRegistersStateStub(Isolate* isolate) | 65 explicit RestoreRegistersStateStub(Isolate* isolate) |
| 66 : PlatformCodeStub(isolate) {} | 66 : PlatformCodeStub(isolate) {} |
| 67 | 67 |
| 68 static void GenerateAheadOfTime(Isolate* isolate); | 68 static void GenerateAheadOfTime(Isolate* isolate); |
| 69 | 69 |
| 70 private: | 70 private: |
| 71 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); | 71 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
| 72 DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub); | 72 DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub); |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 | 75 |
| 76 class RecordWriteStub: public PlatformCodeStub { | 76 class RecordWriteStub : public PlatformCodeStub { |
| 77 public: | 77 public: |
| 78 RecordWriteStub(Isolate* isolate, | 78 RecordWriteStub(Isolate* isolate, Register object, Register value, |
| 79 Register object, | 79 Register address, RememberedSetAction remembered_set_action, |
| 80 Register value, | |
| 81 Register address, | |
| 82 RememberedSetAction remembered_set_action, | |
| 83 SaveFPRegsMode fp_mode) | 80 SaveFPRegsMode fp_mode) |
| 84 : PlatformCodeStub(isolate), | 81 : PlatformCodeStub(isolate), |
| 85 regs_(object, // An input reg. | 82 regs_(object, // An input reg. |
| 86 address, // An input reg. | 83 address, // An input reg. |
| 87 value) { // One scratch reg. | 84 value) { // One scratch reg. |
| 88 minor_key_ = ObjectBits::encode(object.code()) | | 85 minor_key_ = ObjectBits::encode(object.code()) | |
| 89 ValueBits::encode(value.code()) | | 86 ValueBits::encode(value.code()) | |
| 90 AddressBits::encode(address.code()) | | 87 AddressBits::encode(address.code()) | |
| 91 RememberedSetActionBits::encode(remembered_set_action) | | 88 RememberedSetActionBits::encode(remembered_set_action) | |
| 92 SaveFPRegsModeBits::encode(fp_mode); | 89 SaveFPRegsModeBits::encode(fp_mode); |
| 93 } | 90 } |
| 94 | 91 |
| 95 RecordWriteStub(uint32_t key, Isolate* isolate) | 92 RecordWriteStub(uint32_t key, Isolate* isolate) |
| 96 : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {} | 93 : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {} |
| 97 | 94 |
| 98 enum Mode { | 95 enum Mode { STORE_BUFFER_ONLY, INCREMENTAL, INCREMENTAL_COMPACTION }; |
| 99 STORE_BUFFER_ONLY, | |
| 100 INCREMENTAL, | |
| 101 INCREMENTAL_COMPACTION | |
| 102 }; | |
| 103 | 96 |
| 104 virtual bool SometimesSetsUpAFrame() { return false; } | 97 virtual bool SometimesSetsUpAFrame() { return false; } |
| 105 | 98 |
| 106 static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { | 99 static void PatchBranchIntoNop(MacroAssembler* masm, int pos) { |
| 107 const unsigned offset = masm->instr_at(pos) & kImm16Mask; | 100 // Consider adding DCHECK here to catch bad patching |
| 108 masm->instr_at_put(pos, BNE | (zero_reg.code() << kRsShift) | | 101 masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BT); |
| 109 (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); | |
| 110 DCHECK(Assembler::IsBne(masm->instr_at(pos))); | |
| 111 } | 102 } |
| 112 | 103 |
| 113 static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { | 104 static void PatchNopIntoBranch(MacroAssembler* masm, int pos) { |
| 114 const unsigned offset = masm->instr_at(pos) & kImm16Mask; | 105 // Consider adding DCHECK here to catch bad patching |
| 115 masm->instr_at_put(pos, BEQ | (zero_reg.code() << kRsShift) | | 106 masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF); |
| 116 (zero_reg.code() << kRtShift) | (offset & kImm16Mask)); | |
| 117 DCHECK(Assembler::IsBeq(masm->instr_at(pos))); | |
| 118 } | 107 } |
| 119 | 108 |
| 120 static Mode GetMode(Code* stub) { | 109 static Mode GetMode(Code* stub) { |
| 121 Instr first_instruction = Assembler::instr_at(stub->instruction_start()); | 110 Instr first_instruction = |
| 111 Assembler::instr_at(stub->instruction_start() + Assembler::kInstrSize); |
| 122 Instr second_instruction = Assembler::instr_at(stub->instruction_start() + | 112 Instr second_instruction = Assembler::instr_at(stub->instruction_start() + |
| 123 2 * Assembler::kInstrSize); | 113 (Assembler::kInstrSize * 2)); |
| 124 | 114 |
| 125 if (Assembler::IsBeq(first_instruction)) { | 115 // Consider adding DCHECK here to catch unexpected instruction sequence |
| 116 if (BF == (first_instruction & kBOfieldMask)) { |
| 126 return INCREMENTAL; | 117 return INCREMENTAL; |
| 127 } | 118 } |
| 128 | 119 |
| 129 DCHECK(Assembler::IsBne(first_instruction)); | 120 if (BF == (second_instruction & kBOfieldMask)) { |
| 130 | |
| 131 if (Assembler::IsBeq(second_instruction)) { | |
| 132 return INCREMENTAL_COMPACTION; | 121 return INCREMENTAL_COMPACTION; |
| 133 } | 122 } |
| 134 | 123 |
| 135 DCHECK(Assembler::IsBne(second_instruction)); | |
| 136 | |
| 137 return STORE_BUFFER_ONLY; | 124 return STORE_BUFFER_ONLY; |
| 138 } | 125 } |
| 139 | 126 |
| 140 static void Patch(Code* stub, Mode mode) { | 127 static void Patch(Code* stub, Mode mode) { |
| 141 MacroAssembler masm(NULL, | 128 MacroAssembler masm(NULL, stub->instruction_start(), |
| 142 stub->instruction_start(), | |
| 143 stub->instruction_size()); | 129 stub->instruction_size()); |
| 144 switch (mode) { | 130 switch (mode) { |
| 145 case STORE_BUFFER_ONLY: | 131 case STORE_BUFFER_ONLY: |
| 146 DCHECK(GetMode(stub) == INCREMENTAL || | 132 DCHECK(GetMode(stub) == INCREMENTAL || |
| 147 GetMode(stub) == INCREMENTAL_COMPACTION); | 133 GetMode(stub) == INCREMENTAL_COMPACTION); |
| 148 PatchBranchIntoNop(&masm, 0); | 134 |
| 149 PatchBranchIntoNop(&masm, 2 * Assembler::kInstrSize); | 135 PatchBranchIntoNop(&masm, Assembler::kInstrSize); |
| 136 PatchBranchIntoNop(&masm, Assembler::kInstrSize * 2); |
| 150 break; | 137 break; |
| 151 case INCREMENTAL: | 138 case INCREMENTAL: |
| 152 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); | 139 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
| 153 PatchNopIntoBranch(&masm, 0); | 140 PatchNopIntoBranch(&masm, Assembler::kInstrSize); |
| 154 break; | 141 break; |
| 155 case INCREMENTAL_COMPACTION: | 142 case INCREMENTAL_COMPACTION: |
| 156 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); | 143 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
| 157 PatchNopIntoBranch(&masm, 2 * Assembler::kInstrSize); | 144 PatchNopIntoBranch(&masm, Assembler::kInstrSize * 2); |
| 158 break; | 145 break; |
| 159 } | 146 } |
| 160 DCHECK(GetMode(stub) == mode); | 147 DCHECK(GetMode(stub) == mode); |
| 161 CpuFeatures::FlushICache(stub->instruction_start(), | 148 CpuFeatures::FlushICache(stub->instruction_start() + Assembler::kInstrSize, |
| 162 4 * Assembler::kInstrSize); | 149 2 * Assembler::kInstrSize); |
| 163 } | 150 } |
| 164 | 151 |
| 165 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); | 152 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
| 166 | 153 |
| 167 private: | 154 private: |
| 168 // This is a helper class for freeing up 3 scratch registers. The input is | 155 // This is a helper class for freeing up 3 scratch registers. The input is |
| 169 // two registers that must be preserved and one scratch register provided by | 156 // two registers that must be preserved and one scratch register provided by |
| 170 // the caller. | 157 // the caller. |
| 171 class RegisterAllocation { | 158 class RegisterAllocation { |
| 172 public: | 159 public: |
| 173 RegisterAllocation(Register object, | 160 RegisterAllocation(Register object, Register address, Register scratch0) |
| 174 Register address, | 161 : object_(object), address_(address), scratch0_(scratch0) { |
| 175 Register scratch0) | |
| 176 : object_(object), | |
| 177 address_(address), | |
| 178 scratch0_(scratch0) { | |
| 179 DCHECK(!AreAliased(scratch0, object, address, no_reg)); | 162 DCHECK(!AreAliased(scratch0, object, address, no_reg)); |
| 180 scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_); | 163 scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_); |
| 181 } | 164 } |
| 182 | 165 |
| 183 void Save(MacroAssembler* masm) { | 166 void Save(MacroAssembler* masm) { |
| 184 DCHECK(!AreAliased(object_, address_, scratch1_, scratch0_)); | 167 DCHECK(!AreAliased(object_, address_, scratch1_, scratch0_)); |
| 185 // We don't have to save scratch0_ because it was given to us as | 168 // We don't have to save scratch0_ because it was given to us as |
| 186 // a scratch register. | 169 // a scratch register. |
| 187 masm->push(scratch1_); | 170 masm->push(scratch1_); |
| 188 } | 171 } |
| 189 | 172 |
| 190 void Restore(MacroAssembler* masm) { | 173 void Restore(MacroAssembler* masm) { masm->pop(scratch1_); } |
| 191 masm->pop(scratch1_); | |
| 192 } | |
| 193 | 174 |
| 194 // If we have to call into C then we need to save and restore all caller- | 175 // If we have to call into C then we need to save and restore all caller- |
| 195 // saved registers that were not already preserved. The scratch registers | 176 // saved registers that were not already preserved. The scratch registers |
| 196 // will be restored by other means so we don't bother pushing them here. | 177 // will be restored by other means so we don't bother pushing them here. |
| 197 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { | 178 void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { |
| 198 masm->MultiPush((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); | 179 masm->mflr(r0); |
| 180 masm->push(r0); |
| 181 masm->MultiPush(kJSCallerSaved & ~scratch1_.bit()); |
| 199 if (mode == kSaveFPRegs) { | 182 if (mode == kSaveFPRegs) { |
| 200 masm->MultiPushFPU(kCallerSavedFPU); | 183 // Save all volatile FP registers except d0. |
| 184 masm->SaveFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1); |
| 201 } | 185 } |
| 202 } | 186 } |
| 203 | 187 |
| 204 inline void RestoreCallerSaveRegisters(MacroAssembler*masm, | 188 inline void RestoreCallerSaveRegisters(MacroAssembler* masm, |
| 205 SaveFPRegsMode mode) { | 189 SaveFPRegsMode mode) { |
| 206 if (mode == kSaveFPRegs) { | 190 if (mode == kSaveFPRegs) { |
| 207 masm->MultiPopFPU(kCallerSavedFPU); | 191 // Restore all volatile FP registers except d0. |
| 192 masm->RestoreFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1); |
| 208 } | 193 } |
| 209 masm->MultiPop((kJSCallerSaved | ra.bit()) & ~scratch1_.bit()); | 194 masm->MultiPop(kJSCallerSaved & ~scratch1_.bit()); |
| 195 masm->pop(r0); |
| 196 masm->mtlr(r0); |
| 210 } | 197 } |
| 211 | 198 |
| 212 inline Register object() { return object_; } | 199 inline Register object() { return object_; } |
| 213 inline Register address() { return address_; } | 200 inline Register address() { return address_; } |
| 214 inline Register scratch0() { return scratch0_; } | 201 inline Register scratch0() { return scratch0_; } |
| 215 inline Register scratch1() { return scratch1_; } | 202 inline Register scratch1() { return scratch1_; } |
| 216 | 203 |
| 217 private: | 204 private: |
| 218 Register object_; | 205 Register object_; |
| 219 Register address_; | 206 Register address_; |
| 220 Register scratch0_; | 207 Register scratch0_; |
| 221 Register scratch1_; | 208 Register scratch1_; |
| 222 | 209 |
| 223 friend class RecordWriteStub; | 210 friend class RecordWriteStub; |
| 224 }; | 211 }; |
| 225 | 212 |
| 226 enum OnNoNeedToInformIncrementalMarker { | 213 enum OnNoNeedToInformIncrementalMarker { |
| 227 kReturnOnNoNeedToInformIncrementalMarker, | 214 kReturnOnNoNeedToInformIncrementalMarker, |
| 228 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker | 215 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker |
| 229 }; | 216 }; |
| 230 | 217 |
| 231 virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; } | 218 virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; } |
| 232 | 219 |
| 233 virtual void Generate(MacroAssembler* masm) OVERRIDE; | 220 virtual void Generate(MacroAssembler* masm) OVERRIDE; |
| 234 void GenerateIncremental(MacroAssembler* masm, Mode mode); | 221 void GenerateIncremental(MacroAssembler* masm, Mode mode); |
| 235 void CheckNeedsToInformIncrementalMarker( | 222 void CheckNeedsToInformIncrementalMarker( |
| 236 MacroAssembler* masm, | 223 MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need, |
| 237 OnNoNeedToInformIncrementalMarker on_no_need, | |
| 238 Mode mode); | 224 Mode mode); |
| 239 void InformIncrementalMarker(MacroAssembler* masm); | 225 void InformIncrementalMarker(MacroAssembler* masm); |
| 240 | 226 |
| 241 void Activate(Code* code) { | 227 void Activate(Code* code) { |
| 242 code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); | 228 code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); |
| 243 } | 229 } |
| 244 | 230 |
| 245 Register object() const { | 231 Register object() const { |
| 246 return Register::from_code(ObjectBits::decode(minor_key_)); | 232 return Register::from_code(ObjectBits::decode(minor_key_)); |
| 247 } | 233 } |
| 248 | 234 |
| 249 Register value() const { | 235 Register value() const { |
| 250 return Register::from_code(ValueBits::decode(minor_key_)); | 236 return Register::from_code(ValueBits::decode(minor_key_)); |
| 251 } | 237 } |
| 252 | 238 |
| 253 Register address() const { | 239 Register address() const { |
| 254 return Register::from_code(AddressBits::decode(minor_key_)); | 240 return Register::from_code(AddressBits::decode(minor_key_)); |
| 255 } | 241 } |
| 256 | 242 |
| 257 RememberedSetAction remembered_set_action() const { | 243 RememberedSetAction remembered_set_action() const { |
| 258 return RememberedSetActionBits::decode(minor_key_); | 244 return RememberedSetActionBits::decode(minor_key_); |
| 259 } | 245 } |
| 260 | 246 |
| 261 SaveFPRegsMode save_fp_regs_mode() const { | 247 SaveFPRegsMode save_fp_regs_mode() const { |
| 262 return SaveFPRegsModeBits::decode(minor_key_); | 248 return SaveFPRegsModeBits::decode(minor_key_); |
| 263 } | 249 } |
| 264 | 250 |
| 265 class ObjectBits: public BitField<int, 0, 5> {}; | 251 class ObjectBits : public BitField<int, 0, 5> {}; |
| 266 class ValueBits: public BitField<int, 5, 5> {}; | 252 class ValueBits : public BitField<int, 5, 5> {}; |
| 267 class AddressBits: public BitField<int, 10, 5> {}; | 253 class AddressBits : public BitField<int, 10, 5> {}; |
| 268 class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {}; | 254 class RememberedSetActionBits : public BitField<RememberedSetAction, 15, 1> { |
| 269 class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {}; | 255 }; |
| 256 class SaveFPRegsModeBits : public BitField<SaveFPRegsMode, 16, 1> {}; |
| 270 | 257 |
| 271 Label slow_; | 258 Label slow_; |
| 272 RegisterAllocation regs_; | 259 RegisterAllocation regs_; |
| 273 | 260 |
| 274 DISALLOW_COPY_AND_ASSIGN(RecordWriteStub); | 261 DISALLOW_COPY_AND_ASSIGN(RecordWriteStub); |
| 275 }; | 262 }; |
| 276 | 263 |
| 277 | 264 |
| 278 // Trampoline stub to call into native code. To call safely into native code | 265 // Trampoline stub to call into native code. To call safely into native code |
| 279 // in the presence of compacting GC (which can move code objects) we need to | 266 // in the presence of compacting GC (which can move code objects) we need to |
| 280 // keep the code which called into native pinned in the memory. Currently the | 267 // keep the code which called into native pinned in the memory. Currently the |
| 281 // simplest approach is to generate such stub early enough so it can never be | 268 // simplest approach is to generate such stub early enough so it can never be |
| 282 // moved by GC | 269 // moved by GC |
| 283 class DirectCEntryStub: public PlatformCodeStub { | 270 class DirectCEntryStub : public PlatformCodeStub { |
| 284 public: | 271 public: |
| 285 explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {} | 272 explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {} |
| 286 void GenerateCall(MacroAssembler* masm, Register target); | 273 void GenerateCall(MacroAssembler* masm, Register target); |
| 287 | 274 |
| 288 private: | 275 private: |
| 289 bool NeedsImmovableCode() { return true; } | 276 bool NeedsImmovableCode() { return true; } |
| 290 | 277 |
| 291 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); | 278 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
| 292 DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); | 279 DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); |
| 293 }; | 280 }; |
| 294 | 281 |
| 295 | 282 |
| 296 class NameDictionaryLookupStub: public PlatformCodeStub { | 283 class NameDictionaryLookupStub : public PlatformCodeStub { |
| 297 public: | 284 public: |
| 298 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; | 285 enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP }; |
| 299 | 286 |
| 300 NameDictionaryLookupStub(Isolate* isolate, LookupMode mode) | 287 NameDictionaryLookupStub(Isolate* isolate, LookupMode mode) |
| 301 : PlatformCodeStub(isolate) { | 288 : PlatformCodeStub(isolate) { |
| 302 minor_key_ = LookupModeBits::encode(mode); | 289 minor_key_ = LookupModeBits::encode(mode); |
| 303 } | 290 } |
| 304 | 291 |
| 305 static void GenerateNegativeLookup(MacroAssembler* masm, | 292 static void GenerateNegativeLookup(MacroAssembler* masm, Label* miss, |
| 306 Label* miss, | 293 Label* done, Register receiver, |
| 307 Label* done, | 294 Register properties, Handle<Name> name, |
| 308 Register receiver, | |
| 309 Register properties, | |
| 310 Handle<Name> name, | |
| 311 Register scratch0); | 295 Register scratch0); |
| 312 | 296 |
| 313 static void GeneratePositiveLookup(MacroAssembler* masm, | 297 static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, |
| 314 Label* miss, | 298 Label* done, Register elements, |
| 315 Label* done, | 299 Register name, Register r0, Register r1); |
| 316 Register elements, | |
| 317 Register name, | |
| 318 Register r0, | |
| 319 Register r1); | |
| 320 | 300 |
| 321 virtual bool SometimesSetsUpAFrame() { return false; } | 301 virtual bool SometimesSetsUpAFrame() { return false; } |
| 322 | 302 |
| 323 private: | 303 private: |
| 324 static const int kInlinedProbes = 4; | 304 static const int kInlinedProbes = 4; |
| 325 static const int kTotalProbes = 20; | 305 static const int kTotalProbes = 20; |
| 326 | 306 |
| 327 static const int kCapacityOffset = | 307 static const int kCapacityOffset = |
| 328 NameDictionary::kHeaderSize + | 308 NameDictionary::kHeaderSize + |
| 329 NameDictionary::kCapacityIndex * kPointerSize; | 309 NameDictionary::kCapacityIndex * kPointerSize; |
| 330 | 310 |
| 331 static const int kElementsStartOffset = | 311 static const int kElementsStartOffset = |
| 332 NameDictionary::kHeaderSize + | 312 NameDictionary::kHeaderSize + |
| 333 NameDictionary::kElementsStartIndex * kPointerSize; | 313 NameDictionary::kElementsStartIndex * kPointerSize; |
| 334 | 314 |
| 335 LookupMode mode() const { return LookupModeBits::decode(minor_key_); } | 315 LookupMode mode() const { return LookupModeBits::decode(minor_key_); } |
| 336 | 316 |
| 337 class LookupModeBits: public BitField<LookupMode, 0, 1> {}; | 317 class LookupModeBits : public BitField<LookupMode, 0, 1> {}; |
| 338 | 318 |
| 339 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); | 319 DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); |
| 340 DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); | 320 DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); |
| 341 }; | 321 }; |
| 322 } |
| 323 } // namespace v8::internal |
| 342 | 324 |
| 343 | 325 #endif // V8_PPC_CODE_STUBS_PPC_H_ |
| 344 } } // namespace v8::internal | |
| 345 | |
| 346 #endif // V8_MIPS_CODE_STUBS_ARM_H_ | |
| OLD | NEW |