| Index: src/mips/deoptimizer-mips.cc
 | 
| diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
 | 
| index 7302c2f6ddca886596fe3890f6ad06592934a422..8aab19d20630f8a41feaa3b387a1211950e1eec2 100644
 | 
| --- a/src/mips/deoptimizer-mips.cc
 | 
| +++ b/src/mips/deoptimizer-mips.cc
 | 
| @@ -582,6 +582,114 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void Deoptimizer::DoComputeSetterStubFrame(TranslationIterator* iterator,
 | 
| +                                           int frame_index) {
 | 
| +  JSFunction* setter = JSFunction::cast(ComputeLiteral(iterator->Next()));
 | 
| +  // The receiver and the implicit return value are expected in registers by the
 | 
| +  // StoreIC, so they don't belong to the output stack frame. This means that we
 | 
| +  // have to use a height of 0.
 | 
| +  unsigned height = 0;
 | 
| +  unsigned height_in_bytes = height * kPointerSize;
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("  translating setter stub => height=%u\n", height_in_bytes);
 | 
| +  }
 | 
| +
 | 
| +  // We need 5 stack entries from StackFrame::INTERNAL (ra, fp, cp, frame type,
 | 
| +  // code object, see MacroAssembler::EnterFrame) + 1 stack entry from setter
 | 
| +  // stub (implicit return value, see StoreStubCompiler::CompileStoreViaSetter).
 | 
| +  unsigned fixed_frame_size = (5 + 1) * kPointerSize;
 | 
| +  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 | 
| +
 | 
| +  // Allocate and store the output frame description.
 | 
| +  FrameDescription* output_frame =
 | 
| +      new(output_frame_size) FrameDescription(output_frame_size, setter);
 | 
| +  output_frame->SetFrameType(StackFrame::INTERNAL);
 | 
| +
 | 
| +  // A frame for a setter stub can not be the topmost or bottommost one.
 | 
| +  ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
 | 
| +  ASSERT(output_[frame_index] == NULL);
 | 
| +  output_[frame_index] = output_frame;
 | 
| +
 | 
| +  // The top address of the frame is computed from the previous frame's top and
 | 
| +  // this frame's size.
 | 
| +  uint32_t top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
 | 
| +  output_frame->SetTop(top_address);
 | 
| +
 | 
| +  unsigned output_offset = output_frame_size;
 | 
| +
 | 
| +  // Read caller's PC from the previous frame.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  intptr_t value = output_[frame_index - 1]->GetPc();
 | 
| +  output_frame->SetFrameSlot(output_offset, value);
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
 | 
| +           " ; caller's pc\n",
 | 
| +           top_address + output_offset, output_offset, value);
 | 
| +  }
 | 
| +
 | 
| +  // Read caller's FP from the previous frame, and set this frame's FP.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  value = output_[frame_index - 1]->GetFp();
 | 
| +  output_frame->SetFrameSlot(output_offset, value);
 | 
| +  intptr_t fp_value = top_address + output_offset;
 | 
| +  output_frame->SetFp(fp_value);
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
 | 
| +           " ; caller's fp\n",
 | 
| +           fp_value, output_offset, value);
 | 
| +  }
 | 
| +
 | 
| +  // The context can be gotten from the previous frame.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  value = output_[frame_index - 1]->GetContext();
 | 
| +  output_frame->SetFrameSlot(output_offset, value);
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
 | 
| +           " ; context\n",
 | 
| +           top_address + output_offset, output_offset, value);
 | 
| +  }
 | 
| +
 | 
| +  // A marker value is used in place of the function.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::INTERNAL));
 | 
| +  output_frame->SetFrameSlot(output_offset, value);
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
 | 
| +           " ; function (setter sentinel)\n",
 | 
| +           top_address + output_offset, output_offset, value);
 | 
| +  }
 | 
| +
 | 
| +  // Get Code object from setter stub.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  Code* setter_stub =
 | 
| +      isolate_->builtins()->builtin(Builtins::kStoreIC_Setter_ForDeopt);
 | 
| +  value = reinterpret_cast<intptr_t>(setter_stub);
 | 
| +  output_frame->SetFrameSlot(output_offset, value);
 | 
| +  if (FLAG_trace_deopt) {
 | 
| +    PrintF("    0x%08" V8PRIxPTR ": [top + %u] <- 0x%08" V8PRIxPTR
 | 
| +           " ; code object\n",
 | 
| +           top_address + output_offset, output_offset, value);
 | 
| +  }
 | 
| +
 | 
| +  // Skip receiver.
 | 
| +  Translation::Opcode opcode =
 | 
| +      static_cast<Translation::Opcode>(iterator->Next());
 | 
| +  iterator->Skip(Translation::NumberOfOperandsFor(opcode));
 | 
| +
 | 
| +  // The implicit return value was part of the artificial setter stub
 | 
| +  // environment.
 | 
| +  output_offset -= kPointerSize;
 | 
| +  DoTranslateCommand(iterator, frame_index, output_offset);
 | 
| +
 | 
| +  ASSERT(0 == output_offset);
 | 
| +
 | 
| +  intptr_t pc = reinterpret_cast<intptr_t>(
 | 
| +      setter_stub->instruction_start() +
 | 
| +      isolate_->heap()->setter_stub_deopt_pc_offset()->value());
 | 
| +  output_frame->SetPc(pc);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // This code is very similar to ia32/arm code, but relies on register names
 | 
|  // (fp, sp) and how the frame is laid out.
 | 
|  void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
 | 
| 
 |