| Index: src/x64/deoptimizer-x64.cc | 
| diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc | 
| index 8e776f9bfb9fd840f9114fb9a410663ffb138fd6..0bb02dbe7c49ef760552ad71abf901fc4d4054d9 100644 | 
| --- a/src/x64/deoptimizer-x64.cc | 
| +++ b/src/x64/deoptimizer-x64.cc | 
| @@ -348,313 +348,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() { | 
| } | 
|  | 
|  | 
| -void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, | 
| -                                             int frame_index) { | 
| -  // | 
| -  //               FROM                                  TO | 
| -  //    |          ....           |          |          ....           | | 
| -  //    +-------------------------+          +-------------------------+ | 
| -  //    | JSFunction continuation |          | JSFunction continuation | | 
| -  //    +-------------------------+          +-------------------------+ | 
| -  // |  |   saved frame (rbp)     |          |   saved frame (rbp)     | | 
| -  // |  +=========================+<-rbp     +=========================+<-rbp | 
| -  // |  |   JSFunction context    |          |   JSFunction context    | | 
| -  // v  +-------------------------+          +-------------------------| | 
| -  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   | | 
| -  //    +-------------------------+          +-------------------------+ | 
| -  //    |                         |          |  caller args.arguments_ | | 
| -  //    | ...                     |          +-------------------------+ | 
| -  //    |                         |          |  caller args.length_    | | 
| -  //    |-------------------------|<-rsp     +-------------------------+ | 
| -  //                                         |  caller args pointer    | | 
| -  //                                         +-------------------------+ | 
| -  //                                         |  caller stack param 1   | | 
| -  //      parameters in registers            +-------------------------+ | 
| -  //       and spilled to stack              |           ....          | | 
| -  //                                         +-------------------------+ | 
| -  //                                         |  caller stack param n   | | 
| -  //                                         +-------------------------+<-rsp | 
| -  //                                         rax = number of parameters | 
| -  //                                         rbx = failure handler address | 
| -  //                                         rbp = saved frame | 
| -  //                                         rsi = JSFunction context | 
| -  // | 
| - | 
| -  ASSERT(compiled_code_->kind() == Code::COMPILED_STUB); | 
| -  int major_key = compiled_code_->major_key(); | 
| -  CodeStubInterfaceDescriptor* descriptor = | 
| -      isolate_->code_stub_interface_descriptor(major_key); | 
| - | 
| -  // The output frame must have room for all pushed register parameters | 
| -  // and the standard stack frame slots.  Include space for an argument | 
| -  // object to the callee and optionally the space to pass the argument | 
| -  // object to the stub failure handler. | 
| -  int height_in_bytes = kPointerSize * descriptor->register_param_count_ + | 
| -      sizeof(Arguments) + kPointerSize; | 
| -  int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; | 
| -  int input_frame_size = input_->GetFrameSize(); | 
| -  int output_frame_size = height_in_bytes + fixed_frame_size; | 
| -  if (trace_) { | 
| -    PrintF("  translating %s => StubFailureTrampolineStub, height=%d\n", | 
| -           CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), | 
| -           height_in_bytes); | 
| -  } | 
| - | 
| -  // The stub failure trampoline is a single frame. | 
| -  FrameDescription* output_frame = | 
| -      new(output_frame_size) FrameDescription(output_frame_size, NULL); | 
| -  output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE); | 
| -  ASSERT(frame_index == 0); | 
| -  output_[frame_index] = output_frame; | 
| - | 
| -  // The top address for the output frame can be computed from the input | 
| -  // frame pointer and the output frame's height. Subtract space for the | 
| -  // context and function slots. | 
| -  intptr_t top_address = input_->GetRegister(rbp.code()) - (2 * kPointerSize) - | 
| -        height_in_bytes; | 
| -  output_frame->SetTop(top_address); | 
| - | 
| -  // Read caller's PC (JSFunction continuation) from the input frame. | 
| -  unsigned input_frame_offset = input_frame_size - kPointerSize; | 
| -  unsigned output_frame_offset = output_frame_size - kPointerSize; | 
| -  intptr_t value = input_->GetFrameSlot(input_frame_offset); | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; caller's pc\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  // Read caller's FP from the input frame, and set this frame's FP. | 
| -  input_frame_offset -= kPointerSize; | 
| -  value = input_->GetFrameSlot(input_frame_offset); | 
| -  output_frame_offset -= kPointerSize; | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  intptr_t frame_ptr = input_->GetRegister(rbp.code()); | 
| -  output_frame->SetRegister(rbp.code(), frame_ptr); | 
| -  output_frame->SetFp(frame_ptr); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; caller's fp\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  // The context can be gotten from the input frame. | 
| -  input_frame_offset -= kPointerSize; | 
| -  value = input_->GetFrameSlot(input_frame_offset); | 
| -  output_frame->SetRegister(rsi.code(), value); | 
| -  output_frame_offset -= kPointerSize; | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; context\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  // A marker value is used in place of the function. | 
| -  output_frame_offset -= kPointerSize; | 
| -  value = reinterpret_cast<intptr_t>( | 
| -      Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; function (stub failure sentinel)\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  intptr_t caller_arg_count = 0; | 
| -  if (descriptor->stack_parameter_count_ != NULL) { | 
| -    caller_arg_count = | 
| -        input_->GetRegister(descriptor->stack_parameter_count_->code()); | 
| -  } | 
| - | 
| -  // Build the Arguments object for the caller's parameters and a pointer to it. | 
| -  output_frame_offset -= kPointerSize; | 
| -  value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 
| -      (caller_arg_count - 1) * kPointerSize; | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; args.arguments\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  output_frame_offset -= kPointerSize; | 
| -  value = caller_arg_count; | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; args.length\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  output_frame_offset -= kPointerSize; | 
| -  value = frame_ptr - (output_frame_size - output_frame_offset) - | 
| -      StandardFrameConstants::kMarkerOffset + kPointerSize; | 
| -  output_frame->SetFrameSlot(output_frame_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; args*\n", | 
| -           top_address + output_frame_offset, output_frame_offset, value); | 
| -  } | 
| - | 
| -  // Copy the register parameters to the failure frame. | 
| -  for (int i = 0; i < descriptor->register_param_count_; ++i) { | 
| -    output_frame_offset -= kPointerSize; | 
| -    DoTranslateCommand(iterator, 0, output_frame_offset); | 
| -  } | 
| - | 
| -  ASSERT(0 == output_frame_offset); | 
| - | 
| -  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) { | 
| -    double double_value = input_->GetDoubleRegister(i); | 
| -    output_frame->SetDoubleRegister(i, double_value); | 
| -  } | 
| - | 
| -  intptr_t handler = | 
| -      reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_); | 
| -  int params = descriptor->register_param_count_; | 
| -  if (descriptor->stack_parameter_count_ != NULL) { | 
| -    params++; | 
| -  } | 
| -  output_frame->SetRegister(rax.code(), params); | 
| -  output_frame->SetRegister(rbx.code(), handler); | 
| - | 
| -  // Compute this frame's PC, state, and continuation. | 
| -  Code* trampoline = NULL; | 
| -  int extra = descriptor->extra_expression_stack_count_; | 
| -  StubFailureTrampolineStub(extra).FindCodeInCache(&trampoline, isolate_); | 
| -  ASSERT(trampoline != NULL); | 
| -  output_frame->SetPc(reinterpret_cast<intptr_t>( | 
| -      trampoline->instruction_start())); | 
| -  output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS)); | 
| -  Code* notify_failure = | 
| -      isolate_->builtins()->builtin(Builtins::kNotifyStubFailure); | 
| -  output_frame->SetContinuation( | 
| -      reinterpret_cast<intptr_t>(notify_failure->entry())); | 
| -} | 
| - | 
| - | 
| -void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator, | 
| -                                              int frame_index) { | 
| -  Builtins* builtins = isolate_->builtins(); | 
| -  Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric); | 
| -  JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); | 
| -  unsigned height = iterator->Next(); | 
| -  unsigned height_in_bytes = height * kPointerSize; | 
| -  if (trace_) { | 
| -    PrintF("  translating construct stub => height=%d\n", height_in_bytes); | 
| -  } | 
| - | 
| -  unsigned fixed_frame_size = 7 * 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, function); | 
| -  output_frame->SetFrameType(StackFrame::CONSTRUCT); | 
| - | 
| -  // Construct stub can not be topmost or bottommost. | 
| -  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. | 
| -  intptr_t top_address; | 
| -  top_address = output_[frame_index - 1]->GetTop() - output_frame_size; | 
| -  output_frame->SetTop(top_address); | 
| - | 
| -  // Compute the incoming parameter translation. | 
| -  int parameter_count = height; | 
| -  unsigned output_offset = output_frame_size; | 
| -  for (int i = 0; i < parameter_count; ++i) { | 
| -    output_offset -= kPointerSize; | 
| -    DoTranslateCommand(iterator, frame_index, output_offset); | 
| -  } | 
| - | 
| -  // Read caller's PC from the previous frame. | 
| -  output_offset -= kPointerSize; | 
| -  intptr_t callers_pc = output_[frame_index - 1]->GetPc(); | 
| -  output_frame->SetFrameSlot(output_offset, callers_pc); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; caller's pc\n", | 
| -           top_address + output_offset, output_offset, callers_pc); | 
| -  } | 
| - | 
| -  // Read caller's FP from the previous frame, and set this frame's FP. | 
| -  output_offset -= kPointerSize; | 
| -  intptr_t 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 (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 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 (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 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::CONSTRUCT)); | 
| -  output_frame->SetFrameSlot(output_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; function (construct sentinel)\n", | 
| -           top_address + output_offset, output_offset, value); | 
| -  } | 
| - | 
| -  // The output frame reflects a JSConstructStubGeneric frame. | 
| -  output_offset -= kPointerSize; | 
| -  value = reinterpret_cast<intptr_t>(construct_stub); | 
| -  output_frame->SetFrameSlot(output_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; code object\n", | 
| -           top_address + output_offset, output_offset, value); | 
| -  } | 
| - | 
| -  // Number of incoming arguments. | 
| -  output_offset -= kPointerSize; | 
| -  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); | 
| -  output_frame->SetFrameSlot(output_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; argc (%d)\n", | 
| -           top_address + output_offset, output_offset, value, height - 1); | 
| -  } | 
| - | 
| -  // The newly allocated object was passed as receiver in the artificial | 
| -  // constructor stub environment created by HEnvironment::CopyForInlining(). | 
| -  output_offset -= kPointerSize; | 
| -  value = output_frame->GetFrameSlot(output_frame_size - kPointerSize); | 
| -  output_frame->SetFrameSlot(output_offset, value); | 
| -  if (trace_) { | 
| -    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 
| -           V8PRIxPTR " ; allocated receiver\n", | 
| -           top_address + output_offset, output_offset, value); | 
| -  } | 
| - | 
| -  ASSERT(0 == output_offset); | 
| - | 
| -  intptr_t pc = reinterpret_cast<intptr_t>( | 
| -      construct_stub->instruction_start() + | 
| -      isolate_->heap()->construct_stub_deopt_pc_offset()->value()); | 
| -  output_frame->SetPc(pc); | 
| -} | 
| - | 
| - | 
| void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, | 
| int frame_index) { | 
| BailoutId node_id = BailoutId(iterator->Next()); | 
| @@ -846,6 +539,27 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 
| } | 
|  | 
|  | 
| +void Deoptimizer::SetPlatformCompiledStubRegisters( | 
| +    FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { | 
| +  intptr_t handler = | 
| +      reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_); | 
| +  int params = descriptor->register_param_count_; | 
| +  if (descriptor->stack_parameter_count_ != NULL) { | 
| +    params++; | 
| +  } | 
| +  output_frame->SetRegister(rax.code(), params); | 
| +  output_frame->SetRegister(rbx.code(), handler); | 
| +} | 
| + | 
| + | 
| +void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { | 
| +  for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) { | 
| +    double double_value = input_->GetDoubleRegister(i); | 
| +    output_frame->SetDoubleRegister(i, double_value); | 
| +  } | 
| +} | 
| + | 
| + | 
| #define __ masm()-> | 
|  | 
| void Deoptimizer::EntryGenerator::Generate() { | 
|  |