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