From b9c771c10662e4ed5645c17a606dde033fa61e6e Mon Sep 17 00:00:00 2001 From: "sgjesse@chromium.org" Date: Thu, 12 May 2011 13:33:14 +0000 Subject: [PATCH] ARM: Reduce amount of code generated for context save on deopt. BUG=none TEST=none Review URL: http://codereview.chromium.org//6930038 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7873 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/deoptimizer-arm.cc | 53 +++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc index f0a69372f6..0298b0d178 100644 --- a/src/arm/deoptimizer-arm.cc +++ b/src/arm/deoptimizer-arm.cc @@ -549,13 +549,21 @@ void Deoptimizer::EntryGenerator::Generate() { const int kDoubleRegsSize = kDoubleSize * DwVfpRegister::kNumAllocatableRegisters; - // Save all general purpose registers before messing with them. - __ sub(sp, sp, Operand(kDoubleRegsSize)); - for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) { - DwVfpRegister vfp_reg = DwVfpRegister::FromAllocationIndex(i); - int offset = i * kDoubleSize; - __ vstr(vfp_reg, sp, offset); + // Save all VFP registers before messing with them. + DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0); + DwVfpRegister last = + DwVfpRegister::FromAllocationIndex( + DwVfpRegister::kNumAllocatableRegisters - 1); + ASSERT(last.code() > first.code()); + ASSERT((last.code() - first.code()) == + (DwVfpRegister::kNumAllocatableRegisters - 1)); +#ifdef DEBUG + for (int i = 0; i <= (DwVfpRegister::kNumAllocatableRegisters - 1); i++) { + ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) && + (DwVfpRegister::FromAllocationIndex(i).code() >= first.code())); } +#endif + __ vstm(db_w, sp, first, last); // Push all 16 registers (needed to populate FrameDescription::registers_). __ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit()); @@ -603,21 +611,30 @@ void Deoptimizer::EntryGenerator::Generate() { // Copy core registers into FrameDescription::registers_[kNumRegisters]. ASSERT(Register::kNumRegisters == kNumberOfRegisters); - for (int i = 0; i < kNumberOfRegisters; i++) { - int offset = (i * kPointerSize) + FrameDescription::registers_offset(); - __ ldr(r2, MemOperand(sp, i * kPointerSize)); - __ str(r2, MemOperand(r1, offset)); - } + ASSERT(kNumberOfRegisters % 2 == 0); + + Label arm_loop; + __ add(r6, r1, Operand(FrameDescription::registers_offset())); + __ mov(r5, Operand(sp)); + __ mov(r4, Operand(kNumberOfRegisters / 2)); + + __ bind(&arm_loop); + __ Ldrd(r2, r3, MemOperand(r5, kPointerSize * 2, PostIndex)); + __ sub(r4, r4, Operand(1), SetCC); + __ Strd(r2, r3, MemOperand(r6, kPointerSize * 2, PostIndex)); + __ b(gt, &arm_loop); // Copy VFP registers to // double_registers_[DoubleRegister::kNumAllocatableRegisters] - int double_regs_offset = FrameDescription::double_registers_offset(); - for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) { - int dst_offset = i * kDoubleSize + double_regs_offset; - int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; - __ vldr(d0, sp, src_offset); - __ vstr(d0, r1, dst_offset); - } + Label vfp_loop; + __ add(r6, r1, Operand(FrameDescription::double_registers_offset())); + __ mov(r4, Operand(DwVfpRegister::kNumAllocatableRegisters)); + + __ bind(&vfp_loop); + __ Ldrd(r2, r3, MemOperand(r5, kDoubleSize, PostIndex)); + __ sub(r4, r4, Operand(1), SetCC); + __ Strd(r2, r3, MemOperand(r6, kDoubleSize, PostIndex)); + __ b(gt, &vfp_loop); // Remove the bailout id, eventually return address, and the saved registers // from the stack.