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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/full-codegen.h" | 9 #include "src/full-codegen.h" |
10 #include "src/safepoint-table.h" | 10 #include "src/safepoint-table.h" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 103 |
104 | 104 |
105 void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { | 105 void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { |
106 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) { | 106 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) { |
107 double double_value = input_->GetDoubleRegister(i); | 107 double double_value = input_->GetDoubleRegister(i); |
108 output_frame->SetDoubleRegister(i, double_value); | 108 output_frame->SetDoubleRegister(i, double_value); |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 #define __ masm-> | |
114 | |
115 static void CopyRegisterDumpToFrame(MacroAssembler* masm, | |
116 Register frame, | |
117 CPURegList reg_list, | |
118 Register scratch1, | |
119 Register scratch2, | |
120 int src_offset, | |
121 int dst_offset) { | |
122 int offset0, offset1; | |
123 CPURegList copy_to_input = reg_list; | |
124 int reg_count = reg_list.Count(); | |
125 int reg_size = reg_list.RegisterSizeInBytes(); | |
126 for (int i = 0; i < (reg_count / 2); i++) { | |
127 __ PeekPair(scratch1, scratch2, src_offset + (i * reg_size * 2)); | |
128 | |
129 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
130 offset1 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
131 | |
132 if ((offset0 + reg_size) == offset1) { | |
133 // Registers are adjacent: store in pairs. | |
134 __ Stp(scratch1, scratch2, MemOperand(frame, offset0)); | |
135 } else { | |
136 // Registers are not adjacent: store individually. | |
137 __ Str(scratch1, MemOperand(frame, offset0)); | |
138 __ Str(scratch2, MemOperand(frame, offset1)); | |
139 } | |
140 } | |
141 if ((reg_count & 1) != 0) { | |
142 __ Peek(scratch1, src_offset + (reg_count - 1) * reg_size); | |
143 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
144 __ Str(scratch1, MemOperand(frame, offset0)); | |
145 } | |
146 } | |
147 | |
148 #undef __ | |
149 | 113 |
150 #define __ masm()-> | 114 #define __ masm()-> |
151 | 115 |
152 void Deoptimizer::EntryGenerator::Generate() { | 116 void Deoptimizer::EntryGenerator::Generate() { |
153 GeneratePrologue(); | 117 GeneratePrologue(); |
154 | 118 |
155 // TODO(all): This code needs to be revisited. We probably only need to save | 119 // TODO(all): This code needs to be revisited. We probably only need to save |
156 // caller-saved registers here. Callee-saved registers can be stored directly | 120 // caller-saved registers here. Callee-saved registers can be stored directly |
157 // in the input frame. | 121 // in the input frame. |
158 | 122 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
202 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); | 166 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); |
203 } | 167 } |
204 | 168 |
205 // Preserve "deoptimizer" object in register x0. | 169 // Preserve "deoptimizer" object in register x0. |
206 Register deoptimizer = x0; | 170 Register deoptimizer = x0; |
207 | 171 |
208 // Get the input frame descriptor pointer. | 172 // Get the input frame descriptor pointer. |
209 __ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset())); | 173 __ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset())); |
210 | 174 |
211 // Copy core registers into the input frame. | 175 // Copy core registers into the input frame. |
212 CopyRegisterDumpToFrame(masm(), x1, saved_registers, x2, x4, 0, | 176 CPURegList copy_to_input = saved_registers; |
213 FrameDescription::registers_offset()); | 177 for (int i = 0; i < saved_registers.Count(); i++) { |
| 178 __ Peek(x2, i * kPointerSize); |
| 179 CPURegister current_reg = copy_to_input.PopLowestIndex(); |
| 180 int offset = (current_reg.code() * kPointerSize) + |
| 181 FrameDescription::registers_offset(); |
| 182 __ Str(x2, MemOperand(x1, offset)); |
| 183 } |
214 | 184 |
215 // Copy FP registers to the input frame. | 185 // Copy FP registers to the input frame. |
216 CopyRegisterDumpToFrame(masm(), x1, saved_fp_registers, x2, x4, | 186 for (int i = 0; i < saved_fp_registers.Count(); i++) { |
217 kFPRegistersOffset, | 187 int dst_offset = FrameDescription::double_registers_offset() + |
218 FrameDescription::double_registers_offset()); | 188 (i * kDoubleSize); |
| 189 int src_offset = kFPRegistersOffset + (i * kDoubleSize); |
| 190 __ Peek(x2, src_offset); |
| 191 __ Str(x2, MemOperand(x1, dst_offset)); |
| 192 } |
219 | 193 |
220 // Remove the bailout id and the saved registers from the stack. | 194 // Remove the bailout id and the saved registers from the stack. |
221 __ Drop(1 + (kSavedRegistersAreaSize / kXRegSize)); | 195 __ Drop(1 + (kSavedRegistersAreaSize / kXRegSize)); |
222 | 196 |
223 // Compute a pointer to the unwinding limit in register x2; that is | 197 // Compute a pointer to the unwinding limit in register x2; that is |
224 // the first stack slot not part of the input frame. | 198 // the first stack slot not part of the input frame. |
225 Register unwind_limit = x2; | 199 Register unwind_limit = x2; |
226 __ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset())); | 200 __ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset())); |
227 __ Add(unwind_limit, unwind_limit, __ StackPointer()); | 201 __ Add(unwind_limit, unwind_limit, __ StackPointer()); |
228 | 202 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 | 350 |
377 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 351 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
378 // No out-of-line constant pool support. | 352 // No out-of-line constant pool support. |
379 UNREACHABLE(); | 353 UNREACHABLE(); |
380 } | 354 } |
381 | 355 |
382 | 356 |
383 #undef __ | 357 #undef __ |
384 | 358 |
385 } } // namespace v8::internal | 359 } } // namespace v8::internal |
OLD | NEW |