| Index: src/arm/deoptimizer-arm.cc
 | 
| diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
 | 
| index dcebd558c5245a4f1ac7583ace8400686b7eb88b..ee2a581a57dcb443e22f1395dab540afa6e3927b 100644
 | 
| --- a/src/arm/deoptimizer-arm.cc
 | 
| +++ b/src/arm/deoptimizer-arm.cc
 | 
| @@ -212,7 +212,7 @@ static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
 | 
|  
 | 
|  void Deoptimizer::DoComputeOsrOutputFrame() {
 | 
|    DeoptimizationInputData* data = DeoptimizationInputData::cast(
 | 
| -      compiled_code_->deoptimization_data());
 | 
| +      optimized_code_->deoptimization_data());
 | 
|    unsigned ast_id = data->OsrAstId()->value();
 | 
|  
 | 
|    int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
 | 
| @@ -246,7 +246,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
 | 
|    unsigned input_frame_size = input_->GetFrameSize();
 | 
|    ASSERT(fixed_size + height_in_bytes == input_frame_size);
 | 
|  
 | 
| -  unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
 | 
| +  unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
 | 
|    unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
 | 
|    unsigned outgoing_size = outgoing_height * kPointerSize;
 | 
|    unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
 | 
| @@ -338,7 +338,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
 | 
|  
 | 
|      unsigned pc_offset = data->OsrPcOffset()->value();
 | 
|      uint32_t pc = reinterpret_cast<uint32_t>(
 | 
| -        compiled_code_->entry() + pc_offset);
 | 
| +        optimized_code_->entry() + pc_offset);
 | 
|      output_[0]->SetPc(pc);
 | 
|    }
 | 
|    Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
 | 
| @@ -451,70 +451,6 @@ void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void Deoptimizer::DoCompiledStubFrame(TranslationIterator* iterator,
 | 
| -                                      int frame_index) {
 | 
| -  //
 | 
| -  //               FROM                                  TO             <-fp
 | 
| -  //    |          ....           |          |          ....           |
 | 
| -  //    +-------------------------+          +-------------------------+
 | 
| -  //    | JSFunction continuation |          | JSFunction continuation |
 | 
| -  //    +-------------------------+          +-------------------------+<-sp
 | 
| -  // |  |   saved frame (fp)      |
 | 
| -  // |  +=========================+<-fp
 | 
| -  // |  |   JSFunction context    |
 | 
| -  // v  +-------------------------+
 | 
| -  //    |   COMPILED_STUB marker  |          fp = saved frame
 | 
| -  //    +-------------------------+          f8 = JSFunction context
 | 
| -  //    |                         |
 | 
| -  //    | ...                     |
 | 
| -  //    |                         |
 | 
| -  //    +-------------------------+<-sp
 | 
| -  //
 | 
| -  //
 | 
| -  int output_frame_size = 1 * kPointerSize;
 | 
| -  FrameDescription* output_frame =
 | 
| -      new(output_frame_size) FrameDescription(output_frame_size, 0);
 | 
| -  Code* notify_miss =
 | 
| -      isolate_->builtins()->builtin(Builtins::kNotifyICMiss);
 | 
| -  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
 | 
| -  output_frame->SetContinuation(
 | 
| -      reinterpret_cast<intptr_t>(notify_miss->entry()));
 | 
| -
 | 
| -  ASSERT(compiled_code_->kind() == Code::COMPILED_STUB);
 | 
| -  int major_key = compiled_code_->major_key();
 | 
| -  CodeStubInterfaceDescriptor* descriptor =
 | 
| -      isolate_->code_stub_interface_descriptor(major_key);
 | 
| -  Handle<Code> miss_ic(descriptor->deoptimization_handler_);
 | 
| -  output_frame->SetPc(reinterpret_cast<intptr_t>(miss_ic->instruction_start()));
 | 
| -  unsigned input_frame_size = input_->GetFrameSize();
 | 
| -  intptr_t value = input_->GetFrameSlot(input_frame_size - kPointerSize);
 | 
| -  output_frame->SetFrameSlot(0, value);
 | 
| -  value = input_->GetFrameSlot(input_frame_size - 2 * kPointerSize);
 | 
| -  output_frame->SetRegister(fp.code(), value);
 | 
| -  output_frame->SetFp(value);
 | 
| -  value = input_->GetFrameSlot(input_frame_size - 3 * kPointerSize);
 | 
| -  output_frame->SetRegister(cp.code(), value);
 | 
| -
 | 
| -  Translation::Opcode opcode =
 | 
| -      static_cast<Translation::Opcode>(iterator->Next());
 | 
| -  ASSERT(opcode == Translation::REGISTER);
 | 
| -  USE(opcode);
 | 
| -  int input_reg = iterator->Next();
 | 
| -  intptr_t input_value = input_->GetRegister(input_reg);
 | 
| -  output_frame->SetRegister(r1.code(), input_value);
 | 
| -
 | 
| -  int32_t next = iterator->Next();
 | 
| -  opcode = static_cast<Translation::Opcode>(next);
 | 
| -  ASSERT(opcode == Translation::REGISTER);
 | 
| -  input_reg = iterator->Next();
 | 
| -  input_value = input_->GetRegister(input_reg);
 | 
| -  output_frame->SetRegister(r0.code(), input_value);
 | 
| -
 | 
| -  ASSERT(frame_index == 0);
 | 
| -  output_[frame_index] = output_frame;
 | 
| -}
 | 
| -
 | 
| -
 | 
|  void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 | 
|                                                int frame_index) {
 | 
|    Builtins* builtins = isolate_->builtins();
 | 
| @@ -942,7 +878,7 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
 | 
|    }
 | 
|    input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
 | 
|    input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
 | 
| -  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
 | 
| +  for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) {
 | 
|      input_->SetDoubleRegister(i, 0.0);
 | 
|    }
 | 
|  
 | 
| @@ -962,6 +898,7 @@ void Deoptimizer::EntryGenerator::Generate() {
 | 
|  
 | 
|    Isolate* isolate = masm()->isolate();
 | 
|  
 | 
| +  CpuFeatures::Scope scope(VFP3);
 | 
|    // Save all general purpose registers before messing with them.
 | 
|    const int kNumberOfRegisters = Register::kNumRegisters;
 | 
|  
 | 
| @@ -969,29 +906,23 @@ void Deoptimizer::EntryGenerator::Generate() {
 | 
|    RegList restored_regs = kJSCallerSaved | kCalleeSaved | ip.bit();
 | 
|  
 | 
|    const int kDoubleRegsSize =
 | 
| -      kDoubleSize * DwVfpRegister::kMaxNumAllocatableRegisters;
 | 
| -
 | 
| -  if (CpuFeatures::IsSupported(VFP2)) {
 | 
| -    CpuFeatures::Scope scope(VFP2);
 | 
| -    // Save all VFP registers before messing with them.
 | 
| -    DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0);
 | 
| -    DwVfpRegister last =
 | 
| -        DwVfpRegister::FromAllocationIndex(
 | 
| -            DwVfpRegister::kMaxNumAllocatableRegisters - 1);
 | 
| -    ASSERT(last.code() > first.code());
 | 
| -    ASSERT((last.code() - first.code()) ==
 | 
| -           (DwVfpRegister::kMaxNumAllocatableRegisters - 1));
 | 
| +      kDoubleSize * DwVfpRegister::kNumAllocatableRegisters;
 | 
| +
 | 
| +  // 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
 | 
| -    int max = DwVfpRegister::kMaxNumAllocatableRegisters - 1;
 | 
| -    for (int i = 0; i <= max; i++) {
 | 
| -      ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) &&
 | 
| -             (DwVfpRegister::FromAllocationIndex(i).code() >= first.code()));
 | 
| -    }
 | 
| -#endif
 | 
| -    __ vstm(db_w, sp, first, last);
 | 
| -  } else {
 | 
| -    __ sub(sp, sp, Operand(kDoubleRegsSize));
 | 
| +  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_).
 | 
|    // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps
 | 
| @@ -1050,17 +981,14 @@ void Deoptimizer::EntryGenerator::Generate() {
 | 
|      __ str(r2, MemOperand(r1, offset));
 | 
|    }
 | 
|  
 | 
| -  if (CpuFeatures::IsSupported(VFP2)) {
 | 
| -    CpuFeatures::Scope scope(VFP2);
 | 
| -    // Copy VFP registers to
 | 
| -    // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters]
 | 
| -    int double_regs_offset = FrameDescription::double_registers_offset();
 | 
| -    for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); ++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);
 | 
| -    }
 | 
| +  // 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);
 | 
|    }
 | 
|  
 | 
|    // Remove the bailout id, eventually return address, and the saved registers
 | 
| @@ -1081,13 +1009,10 @@ void Deoptimizer::EntryGenerator::Generate() {
 | 
|    // frame description.
 | 
|    __ add(r3,  r1, Operand(FrameDescription::frame_content_offset()));
 | 
|    Label pop_loop;
 | 
| -  Label pop_loop_header;
 | 
| -  __ b(&pop_loop_header);
 | 
|    __ bind(&pop_loop);
 | 
|    __ pop(r4);
 | 
|    __ str(r4, MemOperand(r3, 0));
 | 
|    __ add(r3, r3, Operand(sizeof(uint32_t)));
 | 
| -  __ bind(&pop_loop_header);
 | 
|    __ cmp(r2, sp);
 | 
|    __ b(ne, &pop_loop);
 | 
|  
 | 
| @@ -1104,29 +1029,24 @@ void Deoptimizer::EntryGenerator::Generate() {
 | 
|    __ pop(r0);  // Restore deoptimizer object (class Deoptimizer).
 | 
|  
 | 
|    // Replace the current (input) frame with the output frames.
 | 
| -  Label outer_push_loop, inner_push_loop,
 | 
| -      outer_loop_header, inner_loop_header;
 | 
| +  Label outer_push_loop, inner_push_loop;
 | 
|    // Outer loop state: r0 = current "FrameDescription** output_",
 | 
|    // r1 = one past the last FrameDescription**.
 | 
|    __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
 | 
|    __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset()));  // r0 is output_.
 | 
|    __ add(r1, r0, Operand(r1, LSL, 2));
 | 
| -  __ jmp(&outer_loop_header);
 | 
|    __ bind(&outer_push_loop);
 | 
|    // Inner loop state: r2 = current FrameDescription*, r3 = loop index.
 | 
|    __ ldr(r2, MemOperand(r0, 0));  // output_[ix]
 | 
|    __ ldr(r3, MemOperand(r2, FrameDescription::frame_size_offset()));
 | 
| -  __ jmp(&inner_loop_header);
 | 
|    __ bind(&inner_push_loop);
 | 
|    __ sub(r3, r3, Operand(sizeof(uint32_t)));
 | 
|    __ add(r6, r2, Operand(r3));
 | 
|    __ ldr(r7, MemOperand(r6, FrameDescription::frame_content_offset()));
 | 
|    __ push(r7);
 | 
| -  __ bind(&inner_loop_header);
 | 
|    __ cmp(r3, Operand(0));
 | 
|    __ b(ne, &inner_push_loop);  // test for gt?
 | 
|    __ add(r0, r0, Operand(kPointerSize));
 | 
| -  __ bind(&outer_loop_header);
 | 
|    __ cmp(r0, r1);
 | 
|    __ b(lt, &outer_push_loop);
 | 
|  
 | 
| 
 |