| 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 |