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