OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 output_frame->SetDoubleRegister(i, double_value); | 131 output_frame->SetDoubleRegister(i, double_value); |
132 } | 132 } |
133 } | 133 } |
134 | 134 |
135 | 135 |
136 Code* Deoptimizer::NotifyStubFailureBuiltin() { | 136 Code* Deoptimizer::NotifyStubFailureBuiltin() { |
137 return isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); | 137 return isolate_->builtins()->builtin(Builtins::kNotifyStubFailureSaveDoubles); |
138 } | 138 } |
139 | 139 |
140 | 140 |
141 #define __ masm-> | |
142 | |
143 static void CopyRegisterDumpToFrame(MacroAssembler* masm, | |
144 Register frame, | |
145 CPURegList reg_list, | |
146 Register scratch1, | |
147 Register scratch2, | |
148 int src_offset, | |
149 int dst_offset) { | |
150 int offset0, offset1; | |
151 CPURegList copy_to_input = reg_list; | |
152 int reg_count = reg_list.Count(); | |
153 int reg_size = reg_list.RegisterSizeInBytes(); | |
154 for (int i = 0; i < (reg_count / 2); i++) { | |
155 __ PeekPair(scratch1, scratch2, src_offset + (i * reg_size * 2)); | |
156 | |
157 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
158 offset1 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
159 | |
160 if ((offset0 + reg_size) == offset1) { | |
161 // Registers are adjacent: store in pairs. | |
162 __ Stp(scratch1, scratch2, MemOperand(frame, offset0)); | |
163 } else { | |
164 // Registers are not adjacent: store individually. | |
165 __ Str(scratch1, MemOperand(frame, offset0)); | |
166 __ Str(scratch2, MemOperand(frame, offset1)); | |
167 } | |
168 } | |
169 if ((reg_count & 1) != 0) { | |
170 __ Peek(scratch1, (reg_count - 1) * reg_size); | |
ulan
2014/04/09 11:42:41
Missing src_offset:
__ Peek(scratch1, src_offset +
| |
171 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; | |
172 __ Str(scratch1, MemOperand(frame, offset0)); | |
173 } | |
174 } | |
175 | |
176 #undef __ | |
177 | |
141 #define __ masm()-> | 178 #define __ masm()-> |
142 | 179 |
143 void Deoptimizer::EntryGenerator::Generate() { | 180 void Deoptimizer::EntryGenerator::Generate() { |
144 GeneratePrologue(); | 181 GeneratePrologue(); |
145 | 182 |
146 // TODO(all): This code needs to be revisited. We probably only need to save | 183 // TODO(all): This code needs to be revisited. We probably only need to save |
147 // caller-saved registers here. Callee-saved registers can be stored directly | 184 // caller-saved registers here. Callee-saved registers can be stored directly |
148 // in the input frame. | 185 // in the input frame. |
149 | 186 |
150 // Save all allocatable floating point registers. | 187 // Save all allocatable floating point registers. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); | 230 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); |
194 } | 231 } |
195 | 232 |
196 // Preserve "deoptimizer" object in register x0. | 233 // Preserve "deoptimizer" object in register x0. |
197 Register deoptimizer = x0; | 234 Register deoptimizer = x0; |
198 | 235 |
199 // Get the input frame descriptor pointer. | 236 // Get the input frame descriptor pointer. |
200 __ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset())); | 237 __ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset())); |
201 | 238 |
202 // Copy core registers into the input frame. | 239 // Copy core registers into the input frame. |
203 CPURegList copy_to_input = saved_registers; | 240 CopyRegisterDumpToFrame(masm(), x1, saved_registers, x2, x4, 0, |
204 for (int i = 0; i < saved_registers.Count(); i++) { | 241 FrameDescription::registers_offset()); |
205 // TODO(all): Look for opportunities to optimize this by using ldp/stp. | |
206 __ Peek(x2, i * kPointerSize); | |
207 CPURegister current_reg = copy_to_input.PopLowestIndex(); | |
208 int offset = (current_reg.code() * kPointerSize) + | |
209 FrameDescription::registers_offset(); | |
210 __ Str(x2, MemOperand(x1, offset)); | |
211 } | |
212 | 242 |
213 // Copy FP registers to the input frame. | 243 // Copy FP registers to the input frame. |
214 for (int i = 0; i < saved_fp_registers.Count(); i++) { | 244 CopyRegisterDumpToFrame(masm(), x1, saved_fp_registers, x2, x4, |
215 // TODO(all): Look for opportunities to optimize this by using ldp/stp. | 245 kFPRegistersOffset, |
216 int dst_offset = FrameDescription::double_registers_offset() + | 246 FrameDescription::double_registers_offset()); |
217 (i * kDoubleSize); | |
218 int src_offset = kFPRegistersOffset + (i * kDoubleSize); | |
219 __ Peek(x2, src_offset); | |
220 __ Str(x2, MemOperand(x1, dst_offset)); | |
221 } | |
222 | 247 |
223 // Remove the bailout id and the saved registers from the stack. | 248 // Remove the bailout id and the saved registers from the stack. |
224 __ Drop(1 + (kSavedRegistersAreaSize / kXRegSize)); | 249 __ Drop(1 + (kSavedRegistersAreaSize / kXRegSize)); |
225 | 250 |
226 // Compute a pointer to the unwinding limit in register x2; that is | 251 // Compute a pointer to the unwinding limit in register x2; that is |
227 // the first stack slot not part of the input frame. | 252 // the first stack slot not part of the input frame. |
228 Register unwind_limit = x2; | 253 Register unwind_limit = x2; |
229 __ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset())); | 254 __ Ldr(unwind_limit, MemOperand(x1, FrameDescription::frame_size_offset())); |
230 __ Add(unwind_limit, unwind_limit, __ StackPointer()); | 255 __ Add(unwind_limit, unwind_limit, __ StackPointer()); |
231 | 256 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 | 404 |
380 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 405 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
381 // No out-of-line constant pool support. | 406 // No out-of-line constant pool support. |
382 UNREACHABLE(); | 407 UNREACHABLE(); |
383 } | 408 } |
384 | 409 |
385 | 410 |
386 #undef __ | 411 #undef __ |
387 | 412 |
388 } } // namespace v8::internal | 413 } } // namespace v8::internal |
OLD | NEW |