| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/codegen.h" | 5 #include "src/codegen.h" |
| 6 #include "src/deoptimizer.h" | 6 #include "src/deoptimizer.h" |
| 7 #include "src/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
| 8 #include "src/register-configuration.h" | |
| 9 #include "src/safepoint-table.h" | 8 #include "src/safepoint-table.h" |
| 10 | 9 |
| 11 namespace v8 { | 10 namespace v8 { |
| 12 namespace internal { | 11 namespace internal { |
| 13 | 12 |
| 14 const int Deoptimizer::table_entry_size_ = 8; | 13 const int Deoptimizer::table_entry_size_ = 8; |
| 15 | 14 |
| 16 | 15 |
| 17 int Deoptimizer::patch_size() { | 16 int Deoptimizer::patch_size() { |
| 18 const int kCallInstructionSizeInWords = 3; | 17 const int kCallInstructionSizeInWords = 3; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 86 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
| 88 // Set the register values. The values are not important as there are no | 87 // Set the register values. The values are not important as there are no |
| 89 // callee saved registers in JavaScript frames, so all registers are | 88 // callee saved registers in JavaScript frames, so all registers are |
| 90 // spilled. Registers fp and sp are set to the correct values though. | 89 // spilled. Registers fp and sp are set to the correct values though. |
| 91 | 90 |
| 92 for (int i = 0; i < Register::kNumRegisters; i++) { | 91 for (int i = 0; i < Register::kNumRegisters; i++) { |
| 93 input_->SetRegister(i, i * 4); | 92 input_->SetRegister(i, i * 4); |
| 94 } | 93 } |
| 95 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); | 94 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); |
| 96 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); | 95 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); |
| 97 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { | 96 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { |
| 98 input_->SetDoubleRegister(i, 0.0); | 97 input_->SetDoubleRegister(i, 0.0); |
| 99 } | 98 } |
| 100 | 99 |
| 101 // Fill the frame content from the actual data on the frame. | 100 // Fill the frame content from the actual data on the frame. |
| 102 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { | 101 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { |
| 103 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); | 102 input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); |
| 104 } | 103 } |
| 105 } | 104 } |
| 106 | 105 |
| 107 | 106 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 136 // easily ported. | 135 // easily ported. |
| 137 void Deoptimizer::TableEntryGenerator::Generate() { | 136 void Deoptimizer::TableEntryGenerator::Generate() { |
| 138 GeneratePrologue(); | 137 GeneratePrologue(); |
| 139 | 138 |
| 140 // Save all general purpose registers before messing with them. | 139 // Save all general purpose registers before messing with them. |
| 141 const int kNumberOfRegisters = Register::kNumRegisters; | 140 const int kNumberOfRegisters = Register::kNumRegisters; |
| 142 | 141 |
| 143 // Everything but pc, lr and ip which will be saved but not restored. | 142 // Everything but pc, lr and ip which will be saved but not restored. |
| 144 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); | 143 RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit(); |
| 145 | 144 |
| 146 const int kDoubleRegsSize = kDoubleSize * DwVfpRegister::kMaxNumRegisters; | 145 const int kDoubleRegsSize = |
| 146 kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters; |
| 147 | 147 |
| 148 // Save all allocatable VFP registers before messing with them. | 148 // Save all allocatable VFP registers before messing with them. |
| 149 DCHECK(kDoubleRegZero.code() == 14); | 149 DCHECK(kDoubleRegZero.code() == 14); |
| 150 DCHECK(kScratchDoubleReg.code() == 15); | 150 DCHECK(kScratchDoubleReg.code() == 15); |
| 151 | 151 |
| 152 // Check CPU flags for number of registers, setting the Z condition flag. | 152 // Check CPU flags for number of registers, setting the Z condition flag. |
| 153 __ CheckFor32DRegs(ip); | 153 __ CheckFor32DRegs(ip); |
| 154 | 154 |
| 155 // Push registers d0-d15, and possibly d16-d31, on the stack. | 155 // Push registers d0-d13, and possibly d16-d31, on the stack. |
| 156 // If d16-d31 are not pushed, decrease the stack pointer instead. | 156 // If d16-d31 are not pushed, decrease the stack pointer instead. |
| 157 __ vstm(db_w, sp, d16, d31, ne); | 157 __ vstm(db_w, sp, d16, d31, ne); |
| 158 __ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq); | 158 __ sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq); |
| 159 __ vstm(db_w, sp, d0, d15); | 159 __ vstm(db_w, sp, d0, d13); |
| 160 | 160 |
| 161 // Push all 16 registers (needed to populate FrameDescription::registers_). | 161 // Push all 16 registers (needed to populate FrameDescription::registers_). |
| 162 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps | 162 // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps |
| 163 // handle this a bit differently. | 163 // handle this a bit differently. |
| 164 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); | 164 __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); |
| 165 | 165 |
| 166 __ mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 166 __ mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 167 __ str(fp, MemOperand(ip)); | 167 __ str(fp, MemOperand(ip)); |
| 168 | 168 |
| 169 const int kSavedRegistersAreaSize = | 169 const int kSavedRegistersAreaSize = |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 DCHECK(Register::kNumRegisters == kNumberOfRegisters); | 204 DCHECK(Register::kNumRegisters == kNumberOfRegisters); |
| 205 for (int i = 0; i < kNumberOfRegisters; i++) { | 205 for (int i = 0; i < kNumberOfRegisters; i++) { |
| 206 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); | 206 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
| 207 __ ldr(r2, MemOperand(sp, i * kPointerSize)); | 207 __ ldr(r2, MemOperand(sp, i * kPointerSize)); |
| 208 __ str(r2, MemOperand(r1, offset)); | 208 __ str(r2, MemOperand(r1, offset)); |
| 209 } | 209 } |
| 210 | 210 |
| 211 // Copy VFP registers to | 211 // Copy VFP registers to |
| 212 // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] | 212 // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] |
| 213 int double_regs_offset = FrameDescription::double_registers_offset(); | 213 int double_regs_offset = FrameDescription::double_registers_offset(); |
| 214 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); | 214 for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) { |
| 215 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { | 215 int dst_offset = i * kDoubleSize + double_regs_offset; |
| 216 int code = config->GetAllocatableDoubleCode(i); | 216 int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; |
| 217 int dst_offset = code * kDoubleSize + double_regs_offset; | |
| 218 int src_offset = code * kDoubleSize + kNumberOfRegisters * kPointerSize; | |
| 219 __ vldr(d0, sp, src_offset); | 217 __ vldr(d0, sp, src_offset); |
| 220 __ vstr(d0, r1, dst_offset); | 218 __ vstr(d0, r1, dst_offset); |
| 221 } | 219 } |
| 222 | 220 |
| 223 // Remove the bailout id and the saved registers from the stack. | 221 // Remove the bailout id and the saved registers from the stack. |
| 224 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); | 222 __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); |
| 225 | 223 |
| 226 // Compute a pointer to the unwinding limit in register r2; that is | 224 // Compute a pointer to the unwinding limit in register r2; that is |
| 227 // the first stack slot not part of the input frame. | 225 // the first stack slot not part of the input frame. |
| 228 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); | 226 __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 353 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
| 356 DCHECK(FLAG_enable_embedded_constant_pool); | 354 DCHECK(FLAG_enable_embedded_constant_pool); |
| 357 SetFrameSlot(offset, value); | 355 SetFrameSlot(offset, value); |
| 358 } | 356 } |
| 359 | 357 |
| 360 | 358 |
| 361 #undef __ | 359 #undef __ |
| 362 | 360 |
| 363 } // namespace internal | 361 } // namespace internal |
| 364 } // namespace v8 | 362 } // namespace v8 |
| OLD | NEW |