| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64_CODE_STUBS_ARM64_H_ | 5 #ifndef V8_ARM64_CODE_STUBS_ARM64_H_ |
| 6 #define V8_ARM64_CODE_STUBS_ARM64_H_ | 6 #define V8_ARM64_CODE_STUBS_ARM64_H_ |
| 7 | 7 |
| 8 #include "src/ic-inl.h" | 8 #include "src/ic-inl.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 | 113 |
| 114 virtual bool SometimesSetsUpAFrame() { return false; } | 114 virtual bool SometimesSetsUpAFrame() { return false; } |
| 115 | 115 |
| 116 static Mode GetMode(Code* stub) { | 116 static Mode GetMode(Code* stub) { |
| 117 // Find the mode depending on the first two instructions. | 117 // Find the mode depending on the first two instructions. |
| 118 Instruction* instr1 = | 118 Instruction* instr1 = |
| 119 reinterpret_cast<Instruction*>(stub->instruction_start()); | 119 reinterpret_cast<Instruction*>(stub->instruction_start()); |
| 120 Instruction* instr2 = instr1->following(); | 120 Instruction* instr2 = instr1->following(); |
| 121 | 121 |
| 122 if (instr1->IsUncondBranchImm()) { | 122 if (instr1->IsUncondBranchImm()) { |
| 123 ASSERT(instr2->IsPCRelAddressing() && (instr2->Rd() == xzr.code())); | 123 DCHECK(instr2->IsPCRelAddressing() && (instr2->Rd() == xzr.code())); |
| 124 return INCREMENTAL; | 124 return INCREMENTAL; |
| 125 } | 125 } |
| 126 | 126 |
| 127 ASSERT(instr1->IsPCRelAddressing() && (instr1->Rd() == xzr.code())); | 127 DCHECK(instr1->IsPCRelAddressing() && (instr1->Rd() == xzr.code())); |
| 128 | 128 |
| 129 if (instr2->IsUncondBranchImm()) { | 129 if (instr2->IsUncondBranchImm()) { |
| 130 return INCREMENTAL_COMPACTION; | 130 return INCREMENTAL_COMPACTION; |
| 131 } | 131 } |
| 132 | 132 |
| 133 ASSERT(instr2->IsPCRelAddressing()); | 133 DCHECK(instr2->IsPCRelAddressing()); |
| 134 | 134 |
| 135 return STORE_BUFFER_ONLY; | 135 return STORE_BUFFER_ONLY; |
| 136 } | 136 } |
| 137 | 137 |
| 138 // We patch the two first instructions of the stub back and forth between an | 138 // We patch the two first instructions of the stub back and forth between an |
| 139 // adr and branch when we start and stop incremental heap marking. | 139 // adr and branch when we start and stop incremental heap marking. |
| 140 // The branch is | 140 // The branch is |
| 141 // b label | 141 // b label |
| 142 // The adr is | 142 // The adr is |
| 143 // adr xzr label | 143 // adr xzr label |
| 144 // so effectively a nop. | 144 // so effectively a nop. |
| 145 static void Patch(Code* stub, Mode mode) { | 145 static void Patch(Code* stub, Mode mode) { |
| 146 // We are going to patch the two first instructions of the stub. | 146 // We are going to patch the two first instructions of the stub. |
| 147 PatchingAssembler patcher( | 147 PatchingAssembler patcher( |
| 148 reinterpret_cast<Instruction*>(stub->instruction_start()), 2); | 148 reinterpret_cast<Instruction*>(stub->instruction_start()), 2); |
| 149 Instruction* instr1 = patcher.InstructionAt(0); | 149 Instruction* instr1 = patcher.InstructionAt(0); |
| 150 Instruction* instr2 = patcher.InstructionAt(kInstructionSize); | 150 Instruction* instr2 = patcher.InstructionAt(kInstructionSize); |
| 151 // Instructions must be either 'adr' or 'b'. | 151 // Instructions must be either 'adr' or 'b'. |
| 152 ASSERT(instr1->IsPCRelAddressing() || instr1->IsUncondBranchImm()); | 152 DCHECK(instr1->IsPCRelAddressing() || instr1->IsUncondBranchImm()); |
| 153 ASSERT(instr2->IsPCRelAddressing() || instr2->IsUncondBranchImm()); | 153 DCHECK(instr2->IsPCRelAddressing() || instr2->IsUncondBranchImm()); |
| 154 // Retrieve the offsets to the labels. | 154 // Retrieve the offsets to the labels. |
| 155 int32_t offset_to_incremental_noncompacting = instr1->ImmPCOffset(); | 155 int32_t offset_to_incremental_noncompacting = instr1->ImmPCOffset(); |
| 156 int32_t offset_to_incremental_compacting = instr2->ImmPCOffset(); | 156 int32_t offset_to_incremental_compacting = instr2->ImmPCOffset(); |
| 157 | 157 |
| 158 switch (mode) { | 158 switch (mode) { |
| 159 case STORE_BUFFER_ONLY: | 159 case STORE_BUFFER_ONLY: |
| 160 ASSERT(GetMode(stub) == INCREMENTAL || | 160 DCHECK(GetMode(stub) == INCREMENTAL || |
| 161 GetMode(stub) == INCREMENTAL_COMPACTION); | 161 GetMode(stub) == INCREMENTAL_COMPACTION); |
| 162 patcher.adr(xzr, offset_to_incremental_noncompacting); | 162 patcher.adr(xzr, offset_to_incremental_noncompacting); |
| 163 patcher.adr(xzr, offset_to_incremental_compacting); | 163 patcher.adr(xzr, offset_to_incremental_compacting); |
| 164 break; | 164 break; |
| 165 case INCREMENTAL: | 165 case INCREMENTAL: |
| 166 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); | 166 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
| 167 patcher.b(offset_to_incremental_noncompacting >> kInstructionSizeLog2); | 167 patcher.b(offset_to_incremental_noncompacting >> kInstructionSizeLog2); |
| 168 patcher.adr(xzr, offset_to_incremental_compacting); | 168 patcher.adr(xzr, offset_to_incremental_compacting); |
| 169 break; | 169 break; |
| 170 case INCREMENTAL_COMPACTION: | 170 case INCREMENTAL_COMPACTION: |
| 171 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); | 171 DCHECK(GetMode(stub) == STORE_BUFFER_ONLY); |
| 172 patcher.adr(xzr, offset_to_incremental_noncompacting); | 172 patcher.adr(xzr, offset_to_incremental_noncompacting); |
| 173 patcher.b(offset_to_incremental_compacting >> kInstructionSizeLog2); | 173 patcher.b(offset_to_incremental_compacting >> kInstructionSizeLog2); |
| 174 break; | 174 break; |
| 175 } | 175 } |
| 176 ASSERT(GetMode(stub) == mode); | 176 DCHECK(GetMode(stub) == mode); |
| 177 } | 177 } |
| 178 | 178 |
| 179 private: | 179 private: |
| 180 // This is a helper class to manage the registers associated with the stub. | 180 // This is a helper class to manage the registers associated with the stub. |
| 181 // The 'object' and 'address' registers must be preserved. | 181 // The 'object' and 'address' registers must be preserved. |
| 182 class RegisterAllocation { | 182 class RegisterAllocation { |
| 183 public: | 183 public: |
| 184 RegisterAllocation(Register object, | 184 RegisterAllocation(Register object, |
| 185 Register address, | 185 Register address, |
| 186 Register scratch) | 186 Register scratch) |
| 187 : object_(object), | 187 : object_(object), |
| 188 address_(address), | 188 address_(address), |
| 189 scratch0_(scratch), | 189 scratch0_(scratch), |
| 190 saved_regs_(kCallerSaved), | 190 saved_regs_(kCallerSaved), |
| 191 saved_fp_regs_(kCallerSavedFP) { | 191 saved_fp_regs_(kCallerSavedFP) { |
| 192 ASSERT(!AreAliased(scratch, object, address)); | 192 DCHECK(!AreAliased(scratch, object, address)); |
| 193 | 193 |
| 194 // The SaveCallerSaveRegisters method needs to save caller-saved | 194 // The SaveCallerSaveRegisters method needs to save caller-saved |
| 195 // registers, but we don't bother saving MacroAssembler scratch registers. | 195 // registers, but we don't bother saving MacroAssembler scratch registers. |
| 196 saved_regs_.Remove(MacroAssembler::DefaultTmpList()); | 196 saved_regs_.Remove(MacroAssembler::DefaultTmpList()); |
| 197 saved_fp_regs_.Remove(MacroAssembler::DefaultFPTmpList()); | 197 saved_fp_regs_.Remove(MacroAssembler::DefaultFPTmpList()); |
| 198 | 198 |
| 199 // We would like to require more scratch registers for this stub, | 199 // We would like to require more scratch registers for this stub, |
| 200 // but the number of registers comes down to the ones used in | 200 // but the number of registers comes down to the ones used in |
| 201 // FullCodeGen::SetVar(), which is architecture independent. | 201 // FullCodeGen::SetVar(), which is architecture independent. |
| 202 // We allocate 2 extra scratch registers that we'll save on the stack. | 202 // We allocate 2 extra scratch registers that we'll save on the stack. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 int MinorKey() const { | 306 int MinorKey() const { |
| 307 return MinorKeyFor(object_, value_, address_, remembered_set_action_, | 307 return MinorKeyFor(object_, value_, address_, remembered_set_action_, |
| 308 save_fp_regs_mode_); | 308 save_fp_regs_mode_); |
| 309 } | 309 } |
| 310 | 310 |
| 311 static int MinorKeyFor(Register object, | 311 static int MinorKeyFor(Register object, |
| 312 Register value, | 312 Register value, |
| 313 Register address, | 313 Register address, |
| 314 RememberedSetAction action, | 314 RememberedSetAction action, |
| 315 SaveFPRegsMode fp_mode) { | 315 SaveFPRegsMode fp_mode) { |
| 316 ASSERT(object.Is64Bits()); | 316 DCHECK(object.Is64Bits()); |
| 317 ASSERT(value.Is64Bits()); | 317 DCHECK(value.Is64Bits()); |
| 318 ASSERT(address.Is64Bits()); | 318 DCHECK(address.Is64Bits()); |
| 319 return ObjectBits::encode(object.code()) | | 319 return ObjectBits::encode(object.code()) | |
| 320 ValueBits::encode(value.code()) | | 320 ValueBits::encode(value.code()) | |
| 321 AddressBits::encode(address.code()) | | 321 AddressBits::encode(address.code()) | |
| 322 RememberedSetActionBits::encode(action) | | 322 RememberedSetActionBits::encode(action) | |
| 323 SaveFPRegsModeBits::encode(fp_mode); | 323 SaveFPRegsModeBits::encode(fp_mode); |
| 324 } | 324 } |
| 325 | 325 |
| 326 void Activate(Code* code) { | 326 void Activate(Code* code) { |
| 327 code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); | 327 code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code); |
| 328 } | 328 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 TargetAddressStorageMode storage_mode() { return storage_mode_; } | 466 TargetAddressStorageMode storage_mode() { return storage_mode_; } |
| 467 | 467 |
| 468 private: | 468 private: |
| 469 TargetAddressStorageMode storage_mode_; | 469 TargetAddressStorageMode storage_mode_; |
| 470 }; | 470 }; |
| 471 | 471 |
| 472 | 472 |
| 473 } } // namespace v8::internal | 473 } } // namespace v8::internal |
| 474 | 474 |
| 475 #endif // V8_ARM64_CODE_STUBS_ARM64_H_ | 475 #endif // V8_ARM64_CODE_STUBS_ARM64_H_ |
| OLD | NEW |