Index: src/arm64/deoptimizer-arm64.cc |
diff --git a/src/arm64/deoptimizer-arm64.cc b/src/arm64/deoptimizer-arm64.cc |
index 93cb5176d2cb9b87c0d4b5979caca61a7f75f929..af33652e253c25e95fa66016d6e5ed34c1831c2a 100644 |
--- a/src/arm64/deoptimizer-arm64.cc |
+++ b/src/arm64/deoptimizer-arm64.cc |
@@ -138,6 +138,43 @@ Code* Deoptimizer::NotifyStubFailureBuiltin() { |
} |
+#define __ masm-> |
+ |
+static void CopyRegisterDumpToFrame(MacroAssembler* masm, |
+ Register frame, |
+ CPURegList reg_list, |
+ Register scratch1, |
+ Register scratch2, |
+ int src_offset, |
+ int dst_offset) { |
+ int offset0, offset1; |
+ CPURegList copy_to_input = reg_list; |
+ int reg_count = reg_list.Count(); |
+ int reg_size = reg_list.RegisterSizeInBytes(); |
+ for (int i = 0; i < (reg_count / 2); i++) { |
+ __ PeekPair(scratch1, scratch2, src_offset + (i * reg_size * 2)); |
+ |
+ offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; |
+ offset1 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; |
+ |
+ if ((offset0 + reg_size) == offset1) { |
+ // Registers are adjacent: store in pairs. |
+ __ Stp(scratch1, scratch2, MemOperand(frame, offset0)); |
+ } else { |
+ // Registers are not adjacent: store individually. |
+ __ Str(scratch1, MemOperand(frame, offset0)); |
+ __ Str(scratch2, MemOperand(frame, offset1)); |
+ } |
+ } |
+ if ((reg_count & 1) != 0) { |
+ __ Peek(scratch1, src_offset + (reg_count - 1) * reg_size); |
+ offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; |
+ __ Str(scratch1, MemOperand(frame, offset0)); |
+ } |
+} |
+ |
+#undef __ |
+ |
#define __ masm()-> |
void Deoptimizer::EntryGenerator::Generate() { |
@@ -200,25 +237,13 @@ void Deoptimizer::EntryGenerator::Generate() { |
__ Ldr(x1, MemOperand(deoptimizer, Deoptimizer::input_offset())); |
// Copy core registers into the input frame. |
- CPURegList copy_to_input = saved_registers; |
- for (int i = 0; i < saved_registers.Count(); i++) { |
- // TODO(all): Look for opportunities to optimize this by using ldp/stp. |
- __ Peek(x2, i * kPointerSize); |
- CPURegister current_reg = copy_to_input.PopLowestIndex(); |
- int offset = (current_reg.code() * kPointerSize) + |
- FrameDescription::registers_offset(); |
- __ Str(x2, MemOperand(x1, offset)); |
- } |
+ CopyRegisterDumpToFrame(masm(), x1, saved_registers, x2, x4, 0, |
+ FrameDescription::registers_offset()); |
// Copy FP registers to the input frame. |
- for (int i = 0; i < saved_fp_registers.Count(); i++) { |
- // TODO(all): Look for opportunities to optimize this by using ldp/stp. |
- int dst_offset = FrameDescription::double_registers_offset() + |
- (i * kDoubleSize); |
- int src_offset = kFPRegistersOffset + (i * kDoubleSize); |
- __ Peek(x2, src_offset); |
- __ Str(x2, MemOperand(x1, dst_offset)); |
- } |
+ CopyRegisterDumpToFrame(masm(), x1, saved_fp_registers, x2, x4, |
+ kFPRegistersOffset, |
+ FrameDescription::double_registers_offset()); |
// Remove the bailout id and the saved registers from the stack. |
__ Drop(1 + (kSavedRegistersAreaSize / kXRegSize)); |