Unify deoptimizer for stub failure trampoline frames.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Mar 2013 16:18:50 +0000 (16:18 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 8 Mar 2013 16:18:50 +0000 (16:18 +0000)
This unifies the translation of a compiled stub frame to a stub failure
trampoline frame. Only the frame's register allocation is different on
each architecture and can be factored out.

R=danno@chromium.org

Review URL: https://codereview.chromium.org/12379045

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13887 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/deoptimizer-arm.cc
src/arm/frames-arm.cc
src/deoptimizer.cc
src/deoptimizer.h
src/frames.h
src/ia32/deoptimizer-ia32.cc
src/ia32/frames-ia32.cc
src/x64/deoptimizer-x64.cc
src/x64/frames-x64.cc

index 3753318..9bcc1ac 100644 (file)
@@ -356,187 +356,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
 }
 
 
-void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
-                                             int frame_index) {
-  //
-  //               FROM                                  TO
-  //    |          ....           |          |          ....           |
-  //    +-------------------------+          +-------------------------+
-  //    | JSFunction continuation |          | JSFunction continuation |
-  //    +-------------------------+          +-------------------------+
-  // |  |   saved frame (fp)      |          |   saved frame (fp)      |
-  // |  +=========================+<-fp      +=========================+<-fp
-  // |  |   JSFunction context    |          |   JSFunction context    |
-  // v  +-------------------------+          +-------------------------|
-  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
-  //    +-------------------------+          +-------------------------+
-  //    |                         |          |  caller args.arguments_ |
-  //    | ...                     |          +-------------------------+
-  //    |                         |          |  caller args.length_    |
-  //    |-------------------------|<-sp      +-------------------------+
-  //                                         |  caller args pointer    |
-  //                                         +-------------------------+
-  //                                         |  caller stack param 1   |
-  //      parameters in registers            +-------------------------+
-  //       and spilled to stack              |           ....          |
-  //                                         +-------------------------+
-  //                                         |  caller stack param n   |
-  //                                         +-------------------------+<-sp
-  //                                         r0 = number of parameters
-  //                                         r1 = failure handler address
-  //                                         fp = saved frame
-  //                                         cp = 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(fp.code()) - (2 * kPointerSize) -
-        height_in_bytes;
-  output_frame->SetTop(top_address);
-
-  // Read caller's PC (JSFunction continuation) from the input frame.
-  intptr_t input_frame_offset = input_frame_size - kPointerSize;
-  intptr_t 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%08x: [top + %d] <- 0x%08x ; 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(fp.code());
-  output_frame->SetRegister(fp.code(), frame_ptr);
-  output_frame->SetFp(frame_ptr);
-  if (trace_) {
-    PrintF("    0x%08x: [top + %d] <- 0x%08x ; 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(cp.code(), value);
-  output_frame_offset -= kPointerSize;
-  output_frame->SetFrameSlot(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; function (stub fail sentinel)\n",
-           top_address + output_frame_offset, output_frame_offset, value);
-  }
-
-  int 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%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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 < DwVfpRegister::kMaxNumRegisters; ++i) {
-    double double_value = input_->GetDoubleRegister(i);
-    output_frame->SetDoubleRegister(i, double_value);
-  }
-
-  ApiFunction function(descriptor->deoptimization_handler_);
-  ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
-  intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
-  int params = descriptor->register_param_count_;
-  if (descriptor->stack_parameter_count_ != NULL) {
-    params++;
-  }
-  output_frame->SetRegister(r0.code(), params);
-  output_frame->SetRegister(r1.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()));
-}
-
-
 // This code is very similar to ia32 code, but relies on register names (fp, sp)
 // and how the frame is laid out.
 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
@@ -735,6 +554,28 @@ void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
 }
 
 
+void Deoptimizer::SetPlatformCompiledStubRegisters(
+    FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
+  ApiFunction function(descriptor->deoptimization_handler_);
+  ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
+  intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
+  int params = descriptor->register_param_count_;
+  if (descriptor->stack_parameter_count_ != NULL) {
+    params++;
+  }
+  output_frame->SetRegister(r0.code(), params);
+  output_frame->SetRegister(r1.code(), handler);
+}
+
+
+void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
+  for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
+    double double_value = input_->GetDoubleRegister(i);
+    output_frame->SetDoubleRegister(i, double_value);
+  }
+}
+
+
 #define __ masm()->
 
 // This code tries to be close to ia32 code so that any changes can be
index a805d28..5cbe77a 100644 (file)
 
 #if defined(V8_TARGET_ARCH_ARM)
 
+#include "assembler.h"
+#include "assembler-arm.h"
+#include "assembler-arm-inl.h"
 #include "frames-inl.h"
+#include "macro-assembler.h"
+#include "macro-assembler-arm.h"
 
 namespace v8 {
 namespace internal {
@@ -40,6 +45,10 @@ Address ExitFrame::ComputeStackPointer(Address fp) {
 }
 
 
+Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; }
+Register StubFailureTrampolineFrame::context_register() { return cp; }
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_ARM
index 21ffe07..3924636 100644 (file)
@@ -1174,6 +1174,187 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
 }
 
 
+void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
+                                             int frame_index) {
+  //
+  //               FROM                                  TO
+  //    |          ....           |          |          ....           |
+  //    +-------------------------+          +-------------------------+
+  //    | JSFunction continuation |          | JSFunction continuation |
+  //    +-------------------------+          +-------------------------+
+  // |  |    saved frame (FP)     |          |    saved frame (FP)     |
+  // |  +=========================+<-fpreg   +=========================+<-fpreg
+  // |  |   JSFunction context    |          |   JSFunction context    |
+  // v  +-------------------------+          +-------------------------|
+  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
+  //    +-------------------------+          +-------------------------+
+  //    |                         |          |  caller args.arguments_ |
+  //    | ...                     |          +-------------------------+
+  //    |                         |          |  caller args.length_    |
+  //    |-------------------------|<-spreg   +-------------------------+
+  //                                         |  caller args pointer    |
+  //                                         +-------------------------+
+  //                                         |  caller stack param 1   |
+  //      parameters in registers            +-------------------------+
+  //       and spilled to stack              |           ....          |
+  //                                         +-------------------------+
+  //                                         |  caller stack param n   |
+  //                                         +-------------------------+<-spreg
+  //                                         reg = number of parameters
+  //                                         reg = failure handler address
+  //                                         reg = saved frame
+  //                                         reg = 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.
+  Register fp_reg = StubFailureTrampolineFrame::fp_register();
+  intptr_t top_address = input_->GetRegister(fp_reg.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(fp_reg.code());
+  output_frame->SetRegister(fp_reg.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.
+  Register context_reg = StubFailureTrampolineFrame::context_register();
+  input_frame_offset -= kPointerSize;
+  value = input_->GetFrameSlot(input_frame_offset);
+  output_frame->SetRegister(context_reg.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);
+
+  // Copy the double registers from the input into the output frame.
+  CopyDoubleRegisters(output_frame);
+
+  // Fill registers containing handler and number of parameters.
+  SetPlatformCompiledStubRegisters(output_frame, descriptor);
+
+  // 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::MaterializeHeapObjects(JavaScriptFrameIterator* it) {
   ASSERT_NE(DEBUGGER, bailout_type_);
 
index b4d8873..6231c7c 100644 (file)
@@ -388,6 +388,15 @@ class Deoptimizer : public Malloced {
   // deoptimizations the input frame is filled in generated code.
   void FillInputFrame(Address tos, JavaScriptFrame* frame);
 
+  // Fill the given output frame's registers to contain the failure handler
+  // address and the number of parameters for a stub failure trampoline.
+  void SetPlatformCompiledStubRegisters(FrameDescription* output_frame,
+                                        CodeStubInterfaceDescriptor* desc);
+
+  // Fill the given output frame's double registers with the original values
+  // from the input frame's double registers.
+  void CopyDoubleRegisters(FrameDescription* output_frame);
+
   Isolate* isolate_;
   JSFunction* function_;
   Code* compiled_code_;
index a91d004..ca0d5be 100644 (file)
@@ -709,6 +709,10 @@ class StubFailureTrampolineFrame: public StandardFrame {
 
   virtual void Iterate(ObjectVisitor* v) const;
 
+  // Architecture-specific register description.
+  static Register fp_register();
+  static Register context_register();
+
  protected:
   inline explicit StubFailureTrampolineFrame(
       StackFrameIterator* iterator);
index 667f131..8cdcf99 100644 (file)
@@ -463,186 +463,6 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
 }
 
 
-void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
-                                             int frame_index) {
-  //
-  //               FROM                                  TO
-  //    |          ....           |          |          ....           |
-  //    +-------------------------+          +-------------------------+
-  //    | JSFunction continuation |          | JSFunction continuation |
-  //    +-------------------------+          +-------------------------+
-  // |  |   saved frame (ebp)     |          |   saved frame (ebp)     |
-  // |  +=========================+<-ebp     +=========================+<-ebp
-  // |  |   JSFunction context    |          |   JSFunction context    |
-  // v  +-------------------------+          +-------------------------|
-  //    |   COMPILED_STUB marker  |          |   STUB_FAILURE marker   |
-  //    +-------------------------+          +-------------------------+
-  //    |                         |          |  caller args.arguments_ |
-  //    | ...                     |          +-------------------------+
-  //    |                         |          |  caller args.length_    |
-  //    |-------------------------|<-esp     +-------------------------+
-  //                                         |  caller args pointer    |
-  //                                         +-------------------------+
-  //                                         |  caller stack param 1   |
-  //      parameters in registers            +-------------------------+
-  //       and spilled to stack              |           ....          |
-  //                                         +-------------------------+
-  //                                         |  caller stack param n   |
-  //                                         +-------------------------+<-esp
-  //                                         eax = number of parameters
-  //                                         ebx = failure handler address
-  //                                         ebp = saved frame
-  //                                         esi = 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(ebp.code()) - (2 * kPointerSize) -
-        height_in_bytes;
-  output_frame->SetTop(top_address);
-
-  // Read caller's PC (JSFunction continuation) from the input frame.
-  intptr_t input_frame_offset = input_frame_size - kPointerSize;
-  intptr_t 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%08x: [top + %d] <- 0x%08x ; 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(ebp.code());
-  output_frame->SetRegister(ebp.code(), frame_ptr);
-  output_frame->SetFp(frame_ptr);
-  if (trace_) {
-    PrintF("    0x%08x: [top + %d] <- 0x%08x ; 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(esi.code(), value);
-  output_frame_offset -= kPointerSize;
-  output_frame->SetFrameSlot(output_frame_offset, value);
-  if (trace_) {
-    PrintF("    0x%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; function (stub fail sentinel)\n",
-           top_address + output_frame_offset, output_frame_offset, value);
-  }
-
-  int 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%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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%08x: [top + %d] <- 0x%08x ; 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::kNumAllocatableRegisters; ++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(eax.code(), params);
-  output_frame->SetRegister(ebx.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::DoComputeJSFrame(TranslationIterator* iterator,
                                    int frame_index) {
   BailoutId node_id = BailoutId(iterator->Next());
@@ -850,6 +670,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(eax.code(), params);
+  output_frame->SetRegister(ebx.code(), handler);
+}
+
+
+void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
+  for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; ++i) {
+    double double_value = input_->GetDoubleRegister(i);
+    output_frame->SetDoubleRegister(i, double_value);
+  }
+}
+
+
 #define __ masm()->
 
 void Deoptimizer::EntryGenerator::Generate() {
index dd44f0e..4932fa3 100644 (file)
@@ -29,6 +29,9 @@
 
 #if defined(V8_TARGET_ARCH_IA32)
 
+#include "assembler.h"
+#include "assembler-ia32.h"
+#include "assembler-ia32-inl.h"
 #include "frames-inl.h"
 
 namespace v8 {
@@ -40,6 +43,10 @@ Address ExitFrame::ComputeStackPointer(Address fp) {
 }
 
 
+Register StubFailureTrampolineFrame::fp_register() { return ebp; }
+Register StubFailureTrampolineFrame::context_register() { return esi; }
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_IA32
index 5aa46f3..0bb02db 100644 (file)
@@ -348,193 +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::DoComputeJSFrame(TranslationIterator* iterator,
                                    int frame_index) {
   BailoutId node_id = BailoutId(iterator->Next());
@@ -726,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() {
index 6c58bc9..1d6adfd 100644 (file)
@@ -29,6 +29,9 @@
 
 #if defined(V8_TARGET_ARCH_X64)
 
+#include "assembler.h"
+#include "assembler-x64.h"
+#include "assembler-x64-inl.h"
 #include "frames-inl.h"
 
 namespace v8 {
@@ -40,6 +43,10 @@ Address ExitFrame::ComputeStackPointer(Address fp) {
 }
 
 
+Register StubFailureTrampolineFrame::fp_register() { return rbp; }
+Register StubFailureTrampolineFrame::context_register() { return rsi; }
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64