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 |