[turbofan] Unify referencing of stack slots
authordanno <danno@chromium.org>
Tue, 18 Aug 2015 14:47:56 +0000 (07:47 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 18 Aug 2015 14:48:11 +0000 (14:48 +0000)
Previously, it was not possible to specify StackSlotOperands for all
slots in both the caller and callee stacks. Specifically, the region
of the callee's stack including the saved return address, frame
pointer, function pointer and context pointer could not be addressed
by the register allocator/gap resolver.

In preparation for better tail call support, which will use the gap
resolver to reconcile outgoing parameters, this change makes it
possible to address all slots on the stack, because slots in the
previously inaccessible dead zone may become parameter slots for
outgoing tail calls. All caller stack slots are accessible as they
were before, with slot -1 corresponding to the last stack
parameter. Stack slot indices >= 0 access the callee stack, with slot
0 corresponding to the callee's saved return address, 1 corresponding
to the saved frame pointer, 2 corresponding to the current function
context, 3 corresponding to the frame marker/JSFunction, and slots 4
and above corresponding to spill slots.

The following changes were specifically needed:

* Frame has been changed to explicitly manage three areas of the
  callee frame, the fixed header, the spill slot area, and the
  callee-saved register area.
* Conversions from stack slot indices to fp offsets all now go through
  a common bottleneck: OptimizedFrame::StackSlotOffsetRelativeToFp
* The generation of deoptimization translation tables has been changed
  to support the new stack slot indexing scheme. Crankshaft, which
  doesn't support the new slot numbering in its register allocator,
  must adapt the indexes when creating translation tables.
* Callee-saved parameters are now kept below spill slots, not above,
  to support saving only the optimal set of used registers, which is
  only known after register allocation is finished and spill slots
  have been allocated.

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

Cr-Commit-Position: refs/heads/master@{#30224}

26 files changed:
BUILD.gn
src/arm/lithium-codegen-arm.cc
src/arm64/lithium-codegen-arm64.cc
src/compiler/arm/code-generator-arm.cc
src/compiler/arm64/code-generator-arm64.cc
src/compiler/code-generator.cc
src/compiler/frame.cc [new file with mode: 0644]
src/compiler/frame.h
src/compiler/ia32/code-generator-ia32.cc
src/compiler/linkage.cc
src/compiler/mips/code-generator-mips.cc
src/compiler/mips64/code-generator-mips64.cc
src/compiler/osr.cc
src/compiler/pipeline.cc
src/compiler/pipeline.h
src/compiler/register-allocator.cc
src/compiler/x64/code-generator-x64.cc
src/deoptimizer.cc
src/deoptimizer.h
src/frames.cc
src/frames.h
src/ia32/lithium-codegen-ia32.cc
src/mips/lithium-codegen-mips.cc
src/mips64/lithium-codegen-mips64.cc
src/x64/lithium-codegen-x64.cc
tools/gyp/v8.gyp

index 9bb19f04f77e3b6546828d2905291149a3f1be15..e7fd74e6eb1c3e147652237d8f64055f1103087d 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -687,6 +687,7 @@ source_set("v8_base") {
     "src/compiler/dead-code-elimination.cc",
     "src/compiler/dead-code-elimination.h",
     "src/compiler/diamond.h",
+    "src/compiler/frame.cc",
     "src/compiler/frame.h",
     "src/compiler/frame-elider.cc",
     "src/compiler/frame-elider.h",
index 930a8e388fc37404649ac59caad159dae1e55251..31a111d908dbc53a7842e1197fc246b7eb7f9769 100644 (file)
@@ -647,15 +647,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 65399f4b258f7d0c606a66c58667eb95e63880d1..3dff64cbe84ce91571d901dbdfcab2f4cc1c81a7 100644 (file)
@@ -275,15 +275,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 722f5378729daec6352b00d99a2cc098d75cbbcf..dca6d4e3ecbb90cd57c2fabd4f331f4222281386 100644 (file)
@@ -8,6 +8,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/scopes.h"
 
 namespace v8 {
@@ -949,55 +950,25 @@ void CodeGenerator::AssembleDeoptimizerCall(
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    bool saved_pp;
     if (FLAG_enable_embedded_constant_pool) {
       __ Push(lr, fp, pp);
       // Adjust FP to point to saved FP.
       __ sub(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
-      saved_pp = true;
     } else {
       __ Push(lr, fp);
       __ mov(fp, sp);
-      saved_pp = false;
-    }
-    int register_save_area_size = saved_pp ? kPointerSize : 0;
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0 || saved_pp) {
-      // Save callee-saved registers.
-      __ stm(db_w, sp, saves);
-      register_save_area_size +=
-          kPointerSize * base::bits::CountPopulation32(saves);
-    }
-    const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
-    if (saves_fp != 0) {
-      // Save callee-saved FP registers.
-      STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
-      uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
-      uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
-      DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp));
-
-      __ vstm(db_w, sp, DwVfpRegister::from_code(first),
-              DwVfpRegister::from_code(last));
-      register_save_area_size += 2 * kPointerSize * (last - first + 1);
-    }
-    if (register_save_area_size > 0) {
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
     }
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else {
-    frame()->SetPCOnStack(false);
+    frame()->SetElidedFrameSizeInSlots(0);
   }
 
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (info()->is_osr()) {
     // TurboFan OSR-compiled functions cannot be entered directly.
     __ Abort(kShouldNotDirectlyEnterOsrFunction);
@@ -1010,41 +981,63 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
   }
 
-  if (stack_slots > 0) {
-    __ sub(sp, sp, Operand(stack_slots * kPointerSize));
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ sub(sp, sp, Operand(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves_fp != 0) {
+    // Save callee-saved FP registers.
+    STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
+    uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
+    uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
+    DCHECK_EQ((last - first + 1), base::bits::CountPopulation32(saves_fp));
+    __ vstm(db_w, sp, DwVfpRegister::from_code(first),
+            DwVfpRegister::from_code(last));
+    frame()->AllocateSavedCalleeRegisterSlots((last - first + 1) *
+                                              (kDoubleSize / kPointerSize));
+  }
+  const RegList saves = FLAG_enable_embedded_constant_pool
+                            ? (descriptor->CalleeSavedRegisters() & ~pp.bit())
+                            : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ stm(db_w, sp, saves);
+    frame()->AllocateSavedCalleeRegisterSlots(
+        base::bits::CountPopulation32(saves));
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   int pop_count = static_cast<int>(descriptor->StackParameterCount());
+
+  // Restore registers.
+  const RegList saves = FLAG_enable_embedded_constant_pool
+                            ? (descriptor->CalleeSavedRegisters() & ~pp.bit())
+                            : descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ ldm(ia_w, sp, saves);
+  }
+
+  // Restore FP registers.
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
+    uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
+    uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
+    __ vldm(ia_w, sp, DwVfpRegister::from_code(first),
+            DwVfpRegister::from_code(last));
+  }
+
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ add(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore FP registers.
-      const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
-      if (saves_fp != 0) {
-        STATIC_ASSERT(DwVfpRegister::kMaxNumRegisters == 32);
-        uint32_t last = base::bits::CountLeadingZeros32(saves_fp) - 1;
-        uint32_t first = base::bits::CountTrailingZeros32(saves_fp);
-        __ vldm(ia_w, sp, DwVfpRegister::from_code(first),
-                DwVfpRegister::from_code(last));
-      }
-      // Restore registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      if (saves != 0) {
-        __ ldm(ia_w, sp, saves);
-      }
-    }
     __ LeaveFrame(StackFrame::MANUAL);
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
     // Canonicalize JSFunction return sites for now.
index 59c61ba2918a8c36ea5ae776a14751a8a0f72500..1b68577772f9164dca0ff62d8694e922b1c40214 100644 (file)
@@ -9,6 +9,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/scopes.h"
 
 namespace v8 {
@@ -1083,43 +1084,22 @@ static int AlignedStackSlots(int stack_slots) {
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ SetStackPointer(csp);
     __ Push(lr, fp);
     __ Mov(fp, csp);
-
-    // Save FP registers.
-    CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
-                                     descriptor->CalleeSavedFPRegisters());
-    DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list());
-    int saved_count = saves_fp.Count();
-    __ PushCPURegList(saves_fp);
-    // Save registers.
-    CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
-                                  descriptor->CalleeSavedRegisters());
-    // TODO(palfia): TF save list is not in sync with
-    // CPURegList::GetCalleeSaved(): x30 is missing.
-    // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list());
-    saved_count += saves.Count();
-    __ PushCPURegList(saves);
-
-    frame()->SetRegisterSaveAreaSize(saved_count * kPointerSize);
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ SetStackPointer(jssp);
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ SetStackPointer(jssp);
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else {
-    frame()->SetPCOnStack(false);
+    frame()->SetElidedFrameSizeInSlots(0);
   }
 
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (info()->is_osr()) {
     // TurboFan OSR-compiled functions cannot be entered directly.
     __ Abort(kShouldNotDirectlyEnterOsrFunction);
@@ -1132,42 +1112,60 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ ldr(x1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
   }
 
-  if (stack_slots > 0) {
+  if (stack_shrink_slots > 0) {
     Register sp = __ StackPointer();
     if (!sp.Is(csp)) {
-      __ Sub(sp, sp, stack_slots * kPointerSize);
+      __ Sub(sp, sp, stack_shrink_slots * kPointerSize);
     }
-    __ Sub(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize);
+    __ Sub(csp, csp, AlignedStackSlots(stack_shrink_slots) * kPointerSize);
+  }
+
+  // Save FP registers.
+  CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                                   descriptor->CalleeSavedFPRegisters());
+  int saved_count = saves_fp.Count();
+  if (saved_count != 0) {
+    DCHECK(saves_fp.list() == CPURegList::GetCalleeSavedFP().list());
+    __ PushCPURegList(saves_fp);
+    frame()->AllocateSavedCalleeRegisterSlots(saved_count *
+                                              (kDoubleSize / kPointerSize));
+  }
+  // Save registers.
+  // TODO(palfia): TF save list is not in sync with
+  // CPURegList::GetCalleeSaved(): x30 is missing.
+  // DCHECK(saves.list() == CPURegList::GetCalleeSaved().list());
+  CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
+                                descriptor->CalleeSavedRegisters());
+  saved_count = saves.Count();
+  if (saved_count != 0) {
+    __ PushCPURegList(saves);
+    frame()->AllocateSavedCalleeRegisterSlots(saved_count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
-  int pop_count = static_cast<int>(descriptor->StackParameterCount());
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ Add(csp, csp, AlignedStackSlots(stack_slots) * kPointerSize);
-      }
 
-      // Restore registers.
-      CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
-                                    descriptor->CalleeSavedRegisters());
-      __ PopCPURegList(saves);
+  // Restore registers.
+  CPURegList saves = CPURegList(CPURegister::kRegister, kXRegSizeInBits,
+                                descriptor->CalleeSavedRegisters());
+  if (saves.Count() != 0) {
+    __ PopCPURegList(saves);
+  }
 
-      CPURegList saves_fp =
-          CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
-                     descriptor->CalleeSavedFPRegisters());
-      __ PopCPURegList(saves_fp);
-    }
+  // Restore fp registers.
+  CPURegList saves_fp = CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
+                                   descriptor->CalleeSavedFPRegisters());
+  if (saves_fp.Count() != 0) {
+    __ PopCPURegList(saves_fp);
+  }
 
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ Mov(csp, fp);
     __ Pop(fp, lr);
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
index ca74795a2810af9d84bf528b3b6a6cedc9683c47..07a741f73e24f2595ee5777ca8df5d8d8afc36aa 100644 (file)
@@ -216,10 +216,16 @@ void CodeGenerator::RecordSafepoint(ReferenceMap* references,
                                     Safepoint::DeoptMode deopt_mode) {
   Safepoint safepoint =
       safepoints()->DefineSafepoint(masm(), kind, arguments, deopt_mode);
+  int stackSlotToSpillSlotDelta =
+      frame()->GetTotalFrameSlotCount() - frame()->GetSpillSlotCount();
   for (auto& operand : references->reference_operands()) {
     if (operand.IsStackSlot()) {
-      safepoint.DefinePointerSlot(StackSlotOperand::cast(operand).index(),
-                                  zone());
+      int index = StackSlotOperand::cast(operand).index();
+      DCHECK(index >= 0);
+      // Safepoint table indices are 0-based from the beginning of the spill
+      // slot area, adjust appropriately.
+      index -= stackSlotToSpillSlotDelta;
+      safepoint.DefinePointerSlot(index, zone());
     } else if (operand.IsRegister() && (kind & Safepoint::kWithRegisters)) {
       Register reg =
           Register::FromAllocationIndex(RegisterOperand::cast(operand).index());
diff --git a/src/compiler/frame.cc b/src/compiler/frame.cc
new file mode 100644 (file)
index 0000000..079fccb
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/frame.h"
+
+#include "src/compiler/linkage.h"
+#include "src/compiler/register-allocator.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Frame::Frame(int fixed_frame_size_in_slots)
+    : frame_slot_count_(fixed_frame_size_in_slots),
+      spilled_callee_register_slot_count_(0),
+      stack_slot_count_(0),
+      allocated_registers_(NULL),
+      allocated_double_registers_(NULL) {}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
index f901b1e2b3402bc662023b1618cefa4702cc7cc5..aa823b6ba8ad0f885c68ed6dfe91f460a48e11c2 100644 (file)
@@ -6,26 +6,93 @@
 #define V8_COMPILER_FRAME_H_
 
 #include "src/bit-vector.h"
+#include "src/frames.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// Collects the spill slot requirements and the allocated general and double
-// registers for a compiled function. Frames are usually populated by the
-// register allocator and are used by Linkage to generate code for the prologue
-// and epilogue to compiled code.
+// Collects the spill slot and other frame slot requirements for a compiled
+// function. Frames are usually populated by the register allocator and are used
+// by Linkage to generate code for the prologue and epilogue to compiled code.
+//
+// Frames are divided up into three regions. The first is the fixed header,
+// which always has a constant size and can be predicted before code generation
+// begins depending on the type of code being generated. The second is the
+// region for spill slots, which is immediately below the fixed header and grows
+// as the register allocator needs to spill to the stack and asks the frame for
+// more space. The third region, which contains the callee-saved registers must
+// be reserved after register allocation, since its size can only be precisely
+// determined after register allocation once the number of used callee-saved
+// register is certain.
+//
+// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
+// two slots.
+//
+// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
+// the callee's saved return address and 1 corresponding to the saved frame
+// pointer. Some frames have additional information stored in the fixed header,
+// for example JSFunctions store the function context and marker in the fixed
+// header, with slot index 2 corresponding to the current function context and 3
+// corresponding to the frame marker/JSFunction. The frame region immediately
+// below the fixed header contains spill slots starting a 4 for JsFunctions. The
+// callee-saved frame region below that starts at 4+spilled_slot_count. Callee
+// stack slots corresponding to parameters are accessible through negative slot
+// ids.
+//
+// Every slot of a caller or callee frame is accessible by the register
+// allocator and gap resolver with a SpillSlotOperand containing its
+// corresponding slot id.
+//
+// Below an example JSFunction Frame with slot ids, frame regions and contents:
+//
+//  slot      JS frame
+//       +-----------------+----------------------------
+//  -n-1 |   parameter 0   |                        ^
+//       |- - - - - - - - -|                        |
+//  -n   |                 |                      Caller
+//  ...  |       ...       |                   frame slots
+//  -2   |  parameter n-1  |                   (slot < 0)
+//       |- - - - - - - - -|                        |
+//  -1   |   parameter n   |                        v
+//  -----+-----------------+----------------------------
+//   0   |   return addr   |   ^                    ^
+//       |- - - - - - - - -|   |                    |
+//   1   | saved frame ptr | Fixed                  |
+//       |- - - - - - - - -| Header <-- frame ptr   |
+//   2   |     Context     |   |                    |
+//       |- - - - - - - - -|   |                    |
+//   3   |JSFunction/Marker|   v                    |
+//       +-----------------+----                    |
+//   4   |    spill 1      |   ^                  Callee
+//       |- - - - - - - - -|   |               frame slots
+//  ...  |      ...        | Spill slots       (slot >= 0)
+//       |- - - - - - - - -|   |                    |
+//  m+4  |    spill m      |   v                    |
+//       +-----------------+----                    |
+//  m+5  |  callee-saved 1 |   ^                    |
+//       |- - - - - - - - -|   |                    |
+//       |      ...        | Callee-saved           |
+//       |- - - - - - - - -|   |                    |
+// m+r+4 |  callee-saved r |   v                    v
+//  -----+-----------------+----- <-- stack ptr ---------
+//
 class Frame : public ZoneObject {
  public:
-  Frame()
-      : register_save_area_size_(0),
-        spill_slot_count_(0),
-        osr_stack_slot_count_(0),
-        allocated_registers_(NULL),
-        allocated_double_registers_(NULL),
-        pc_on_stack_(true) {}
+  explicit Frame(int fixed_frame_size_in_slots);
 
-  inline int GetSpillSlotCount() { return spill_slot_count_; }
+  inline int GetTotalFrameSlotCount() { return frame_slot_count_; }
+
+  inline int GetSavedCalleeRegisterSlotCount() {
+    return spilled_callee_register_slot_count_;
+  }
+  inline int GetSpillSlotCount() { return stack_slot_count_; }
+
+  inline void SetElidedFrameSizeInSlots(int slots) {
+    DCHECK_EQ(0, spilled_callee_register_slot_count_);
+    DCHECK_EQ(0, stack_slot_count_);
+    frame_slot_count_ = slots;
+  }
 
   void SetAllocatedRegisters(BitVector* regs) {
     DCHECK(allocated_registers_ == NULL);
@@ -41,48 +108,52 @@ class Frame : public ZoneObject {
     return !allocated_double_registers_->IsEmpty();
   }
 
-  void SetRegisterSaveAreaSize(int size) {
-    DCHECK(IsAligned(size, kPointerSize));
-    register_save_area_size_ = size;
+  int AlignSavedCalleeRegisterSlots() {
+    DCHECK_EQ(0, spilled_callee_register_slot_count_);
+    int frame_slot_count_before = frame_slot_count_;
+    frame_slot_count_ = RoundUp(frame_slot_count_, 2);
+    return frame_slot_count_before - frame_slot_count_;
   }
 
-  int GetRegisterSaveAreaSize() { return register_save_area_size_; }
+  void AllocateSavedCalleeRegisterSlots(int count) {
+    frame_slot_count_ += count;
+    spilled_callee_register_slot_count_ += count;
+  }
 
-  // OSR stack slots, including locals and expression stack slots.
-  void SetOsrStackSlotCount(int slots) {
-    DCHECK(slots >= 0);
-    osr_stack_slot_count_ = slots;
+  int AllocateSpillSlot(int width) {
+    DCHECK_EQ(0, spilled_callee_register_slot_count_);
+    int frame_slot_count_before = frame_slot_count_;
+    int slot = AllocateAlignedFrameSlot(width);
+    stack_slot_count_ += (frame_slot_count_ - frame_slot_count_before);
+    return slot;
   }
 
-  int GetOsrStackSlotCount() { return osr_stack_slot_count_; }
+  int ReserveSpillSlots(size_t slot_count) {
+    DCHECK_EQ(0, spilled_callee_register_slot_count_);
+    DCHECK_EQ(0, stack_slot_count_);
+    stack_slot_count_ += static_cast<int>(slot_count);
+    frame_slot_count_ += static_cast<int>(slot_count);
+    return frame_slot_count_ - 1;
+  }
 
-  int AllocateSpillSlot(int width) {
+ private:
+  int AllocateAlignedFrameSlot(int width) {
     DCHECK(width == 4 || width == 8);
     // Skip one slot if necessary.
     if (width > kPointerSize) {
       DCHECK(width == kPointerSize * 2);
-      spill_slot_count_++;
-      spill_slot_count_ |= 1;
+      frame_slot_count_++;
+      frame_slot_count_ |= 1;
     }
-    return spill_slot_count_++;
-  }
-
-  void ReserveSpillSlots(size_t slot_count) {
-    DCHECK_EQ(0, spill_slot_count_);  // can only reserve before allocation.
-    spill_slot_count_ = static_cast<int>(slot_count);
+    return frame_slot_count_++;
   }
 
-  void SetPCOnStack(bool val) { pc_on_stack_ = val; }
-
-  int PCOnStackSize() { return pc_on_stack_ ? kRegisterSize : 0; }
-
  private:
-  int register_save_area_size_;
-  int spill_slot_count_;
-  int osr_stack_slot_count_;
+  int frame_slot_count_;
+  int spilled_callee_register_slot_count_;
+  int stack_slot_count_;
   BitVector* allocated_registers_;
   BitVector* allocated_double_registers_;
-  bool pc_on_stack_;
 
   DISALLOW_COPY_AND_ASSIGN(Frame);
 };
index 27033d66e051e899022baa6ba02fcb30fa7f8d8a..4241a5e9824c35c341241975b3feb585df099030 100644 (file)
@@ -7,6 +7,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/ia32/assembler-ia32.h"
 #include "src/ia32/frames-ia32.h"
 #include "src/ia32/macro-assembler-ia32.h"
@@ -1260,34 +1261,22 @@ void CodeGenerator::AssembleDeoptimizerCall(
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     // Assemble a prologue similar the to cdecl calling convention.
     __ push(ebp);
     __ mov(ebp, esp);
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      int register_save_area_size = 0;
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        __ push(Register::from_code(i));
-        register_save_area_size += kPointerSize;
-      }
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
     // TODO(turbofan): this prologue is redundant with OSR, but needed for
     // code aging.
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize);
   }
 
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (info()->is_osr()) {
     // TurboFan OSR-compiled functions cannot be entered directly.
     __ Abort(kShouldNotDirectlyEnterOsrFunction);
@@ -1300,40 +1289,42 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (stack_shrink_slots > 0) {
+    __ sub(esp, Immediate(stack_shrink_slots * kPointerSize));
   }
 
-  if (stack_slots > 0) {
-    // Allocate the stack slots used by this frame.
-    __ sub(esp, Immediate(stack_slots * kPointerSize));
+  if (saves != 0) {  // Save callee-saved registers.
+    DCHECK(!info()->is_osr());
+    int pushed = 0;
+    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+      if (!((1 << i) & saves)) continue;
+      __ push(Register::from_code(i));
+      ++pushed;
+    }
+    frame()->AllocateSavedCalleeRegisterSlots(pushed);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ add(esp, Immediate(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      if (saves != 0) {
-        for (int i = 0; i < Register::kNumRegisters; i++) {
-          if (!((1 << i) & saves)) continue;
-          __ pop(Register::from_code(i));
-        }
-      }
-      __ pop(ebp);  // Pop caller's frame pointer.
-    } else {
-      // No saved registers.
-      __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
-      __ pop(ebp);       // Pop caller's frame pointer.
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  // Restore registers.
+  if (saves != 0) {
+    for (int i = 0; i < Register::kNumRegisters; i++) {
+      if (!((1 << i) & saves)) continue;
+      __ pop(Register::from_code(i));
     }
+  }
+
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    __ mov(esp, ebp);  // Move stack pointer back to frame pointer.
+    __ pop(ebp);       // Pop caller's frame pointer.
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
     // Canonicalize JSFunction return sites for now.
     if (return_label_.is_bound()) {
index e6ef59898f9360eec3e3a491fc2bed695580c292..66e5cda7d7536f01431f1bdf9edf4a1b114299b0 100644 (file)
@@ -5,6 +5,7 @@
 #include "src/code-stubs.h"
 #include "src/compiler.h"
 #include "src/compiler/common-operator.h"
+#include "src/compiler/frame.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/node.h"
 #include "src/compiler/osr.h"
@@ -190,27 +191,21 @@ CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
 
 
 FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame) const {
-  if (frame->GetSpillSlotCount() > 0 || incoming_->IsJSFunctionCall() ||
-      incoming_->kind() == CallDescriptor::kCallAddress) {
-    int offset;
-    int register_save_area_size = frame->GetRegisterSaveAreaSize();
-    if (spill_slot >= 0) {
-      // Local or spill slot. Skip the frame pointer, function, and
-      // context in the fixed part of the frame.
-      offset = -(spill_slot + 1) * kPointerSize - register_save_area_size;
-    } else {
-      // Incoming parameter. Skip the return address.
-      offset = -(spill_slot + 1) * kPointerSize + kFPOnStackSize +
-               frame->PCOnStackSize();
-    }
+  bool has_frame = frame->GetSpillSlotCount() > 0 ||
+                   incoming_->IsJSFunctionCall() ||
+                   incoming_->kind() == CallDescriptor::kCallAddress;
+  const int offset =
+      (StandardFrameConstants::kFixedSlotCountAboveFp - spill_slot - 1) *
+      kPointerSize;
+  if (has_frame) {
     return FrameOffset::FromFramePointer(offset);
   } else {
     // No frame. Retrieve all parameters relative to stack pointer.
     DCHECK(spill_slot < 0);  // Must be a parameter.
-    int register_save_area_size = frame->GetRegisterSaveAreaSize();
-    int offset = register_save_area_size - (spill_slot + 1) * kPointerSize +
-                 frame->PCOnStackSize();
-    return FrameOffset::FromStackPointer(offset);
+    int offsetSpToFp =
+        kPointerSize * (StandardFrameConstants::kFixedSlotCountAboveFp -
+                        frame->GetTotalFrameSlotCount());
+    return FrameOffset::FromStackPointer(offset - offsetSpToFp);
   }
 }
 
@@ -505,7 +500,8 @@ LinkageLocation Linkage::GetOsrValueLocation(int index) const {
     return incoming_->GetInputLocation(context_index);
   } else if (index >= first_stack_slot) {
     // Local variable stored in this (callee) stack.
-    int spill_index = index - first_stack_slot;
+    int spill_index =
+        index - first_stack_slot + StandardFrameConstants::kFixedSlotCount;
     return LinkageLocation::ForCalleeFrameSlot(spill_index);
   } else {
     // Parameter. Use the assigned location from the incoming call descriptor.
index 0c5ff85d2de1211973d07100a21d5d4d1bb7306b..560ef26692e32e45d128ccdc54a279e702cd713f 100644 (file)
@@ -6,6 +6,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/mips/macro-assembler-mips.h"
 #include "src/scopes.h"
 
@@ -1077,38 +1078,17 @@ void CodeGenerator::AssembleDeoptimizerCall(
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ Push(ra, fp);
     __ mov(fp, sp);
-
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    // Save callee-saved registers.
-    __ MultiPush(saves);
-    // kNumCalleeSaved includes the fp register, but the fp register
-    // is saved separately in TF.
-    DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves) + 1);
-    int register_save_area_size =
-        base::bits::CountPopulation32(saves) * kPointerSize;
-
-    const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
-    // Save callee-saved FPU registers.
-    __ MultiPushFPU(saves_fpu);
-    DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu));
-    register_save_area_size += kNumCalleeSavedFPU * kDoubleSize;
-
-    frame()->SetRegisterSaveAreaSize(register_save_area_size);
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else {
-    frame()->SetPCOnStack(false);
+    frame()->SetElidedFrameSizeInSlots(0);
   }
 
   if (info()->is_osr()) {
@@ -1123,34 +1103,56 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ lw(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ Subu(sp, sp, Operand(stack_shrink_slots * kPointerSize));
+  }
+
+  // Save callee-saved FPU registers.
+  if (saves_fpu != 0) {
+    __ MultiPushFPU(saves_fpu);
+    int count = base::bits::CountPopulation32(saves_fpu);
+    DCHECK(kNumCalleeSavedFPU == count);
+    frame()->AllocateSavedCalleeRegisterSlots(count *
+                                              (kDoubleSize / kPointerSize));
   }
 
-  if (stack_slots > 0) {
-    __ Subu(sp, sp, Operand(stack_slots * kPointerSize));
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ MultiPush(saves);
+    // kNumCalleeSaved includes the fp register, but the fp register
+    // is saved separately in TF.
+    int count = base::bits::CountPopulation32(saves);
+    DCHECK(kNumCalleeSaved == count + 1);
+    frame()->AllocateSavedCalleeRegisterSlots(count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   int pop_count = static_cast<int>(descriptor->StackParameterCount());
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ Addu(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore FPU registers.
-      const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
-      __ MultiPopFPU(saves_fpu);
 
-      // Restore GP registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      __ MultiPop(saves);
-    }
+  // Restore GP registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPop(saves);
+  }
+
+  // Restore FPU registers.
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    __ MultiPopFPU(saves_fpu);
+  }
+
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ mov(sp, fp);
     __ Pop(ra, fp);
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
index 505742e58281007e6dbe6a3915dda099b51bbd90..c72d9789b846a0013d1eb91de4fca8180a957ace 100644 (file)
@@ -6,6 +6,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/mips/macro-assembler-mips.h"
 #include "src/scopes.h"
 
@@ -1147,40 +1148,19 @@ void CodeGenerator::AssembleDeoptimizerCall(
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ Push(ra, fp);
     __ mov(fp, sp);
-
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    // Save callee-saved registers.
-    __ MultiPush(saves);
-    // kNumCalleeSaved includes the fp register, but the fp register
-    // is saved separately in TF.
-    DCHECK(kNumCalleeSaved == base::bits::CountPopulation32(saves) + 1);
-    int register_save_area_size =
-        base::bits::CountPopulation32(saves) * kPointerSize;
-
-    const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
-    // Save callee-saved FPU registers.
-    __ MultiPushFPU(saves_fpu);
-    DCHECK(kNumCalleeSavedFPU == base::bits::CountPopulation32(saves_fpu));
-    register_save_area_size += kNumCalleeSavedFPU * kDoubleSize;
-
-    frame()->SetRegisterSaveAreaSize(register_save_area_size);
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else {
-    frame()->SetPCOnStack(false);
+    frame()->SetElidedFrameSizeInSlots(0);
   }
 
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (info()->is_osr()) {
     // TurboFan OSR-compiled functions cannot be entered directly.
     __ Abort(kShouldNotDirectlyEnterOsrFunction);
@@ -1193,34 +1173,52 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ ld(a1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots();
+  }
+
+  if (stack_shrink_slots > 0) {
+    __ Dsubu(sp, sp, Operand(stack_shrink_slots * kPointerSize));
   }
 
-  if (stack_slots > 0) {
-    __ Dsubu(sp, sp, Operand(stack_slots * kPointerSize));
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    // Save callee-saved FPU registers.
+    __ MultiPushFPU(saves_fpu);
+    int count = base::bits::CountPopulation32(saves_fpu);
+    DCHECK(kNumCalleeSavedFPU == count);
+    frame()->AllocateSavedCalleeRegisterSlots(count *
+                                              (kDoubleSize / kPointerSize));
+  }
+
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    // Save callee-saved registers.
+    __ MultiPush(saves);
+    // kNumCalleeSaved includes the fp register, but the fp register
+    // is saved separately in TF.
+    int count = base::bits::CountPopulation32(saves);
+    DCHECK(kNumCalleeSaved == count + 1);
+    frame()->AllocateSavedCalleeRegisterSlots(count);
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
-  int pop_count = static_cast<int>(descriptor->StackParameterCount());
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ Daddu(sp, sp, Operand(stack_slots * kPointerSize));
-      }
-      // Restore FPU registers.
-      const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
-      __ MultiPopFPU(saves_fpu);
 
-      // Restore GP registers.
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      __ MultiPop(saves);
-    }
+  // Restore GP registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    __ MultiPop(saves);
+  }
+
+  // Restore FPU registers.
+  const RegList saves_fpu = descriptor->CalleeSavedFPRegisters();
+  if (saves_fpu != 0) {
+    __ MultiPopFPU(saves_fpu);
+  }
+
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ mov(sp, fp);
     __ Pop(ra, fp);
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
@@ -1234,6 +1232,7 @@ void CodeGenerator::AssembleReturn() {
       __ Pop(ra, fp);
     }
   }
+  int pop_count = static_cast<int>(descriptor->StackParameterCount());
   if (pop_count != 0) {
     __ DropAndRet(pop_count);
   } else {
index 6c4c49de7981657e86ef4c253668ea4cc16a6b7c..663cf57808715cd5dad5fe99dfa9bc9071a34982 100644 (file)
@@ -328,8 +328,6 @@ void OsrHelper::SetupFrame(Frame* frame) {
   // The optimized frame will subsume the unoptimized frame. Do so by reserving
   // the first spill slots.
   frame->ReserveSpillSlots(UnoptimizedFrameSlots());
-  // The frame needs to be adjusted by the number of unoptimized frame slots.
-  frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots()));
 }
 
 }  // namespace compiler
index a1b82318c2753ec883accf8abd7d425643a42fcc..e9545b8f3eff884902f8dcf7f21af3656dee4af6 100644 (file)
@@ -259,10 +259,17 @@ class PipelineData {
   }
 
   void InitializeRegisterAllocationData(const RegisterConfiguration* config,
+                                        CallDescriptor* descriptor,
                                         const char* debug_name) {
     DCHECK(frame_ == nullptr);
     DCHECK(register_allocation_data_ == nullptr);
-    frame_ = new (instruction_zone()) Frame();
+    int fixed_frame_size = 0;
+    if (descriptor != nullptr) {
+      fixed_frame_size = (descriptor->kind() == CallDescriptor::kCallAddress)
+                             ? StandardFrameConstants::kFixedSlotCountAboveFp
+                             : StandardFrameConstants::kFixedSlotCount;
+    }
+    frame_ = new (instruction_zone()) Frame(fixed_frame_size);
     register_allocation_data_ = new (register_allocation_zone())
         RegisterAllocationData(config, register_allocation_zone(), frame(),
                                sequence(), debug_name);
@@ -1190,7 +1197,7 @@ bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
   PipelineData data(&zone_pool, &info, sequence);
   Pipeline pipeline(&info);
   pipeline.data_ = &data;
-  pipeline.AllocateRegisters(config, run_verifier);
+  pipeline.AllocateRegisters(config, nullptr, run_verifier);
   return !data.compilation_failed();
 }
 
@@ -1234,7 +1241,8 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
 
   bool run_verifier = FLAG_turbo_verify_allocation;
   // Allocate registers.
-  AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
+  AllocateRegisters(RegisterConfiguration::ArchDefault(), call_descriptor,
+                    run_verifier);
   if (data->compilation_failed()) {
     info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
     return Handle<Code>();
@@ -1293,6 +1301,7 @@ Handle<Code> Pipeline::ScheduleAndGenerateCode(
 
 
 void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
+                                 CallDescriptor* descriptor,
                                  bool run_verifier) {
   PipelineData* data = this->data_;
 
@@ -1310,7 +1319,7 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
   debug_name = GetDebugName(data->info());
 #endif
 
-  data->InitializeRegisterAllocationData(config, debug_name.get());
+  data->InitializeRegisterAllocationData(config, descriptor, debug_name.get());
   if (info()->is_osr()) {
     OsrHelper osr_helper(info());
     osr_helper.SetupFrame(data->frame());
index 15ed8a0e373dd5ee8a33f60311b67e28a9e8a2b1..ea8b7e9b4bd0ccc5b4467c3da094b23e71b856e2 100644 (file)
@@ -67,7 +67,7 @@ class Pipeline {
   void RunPrintAndVerify(const char* phase, bool untyped = false);
   Handle<Code> ScheduleAndGenerateCode(CallDescriptor* call_descriptor);
   void AllocateRegisters(const RegisterConfiguration* config,
-                         bool run_verifier);
+                         CallDescriptor* descriptor, bool run_verifier);
 };
 
 }  // namespace compiler
index 28c99b95544ba4e7c3839730f5e4ab117f0e3087..101a10ae5b55ad4981d8c464df117d2c9d5ccae6 100644 (file)
@@ -1367,7 +1367,7 @@ void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
       // This value is produced on the stack, we never need to spill it.
       if (first_output->IsStackSlot()) {
         DCHECK(StackSlotOperand::cast(first_output)->index() <
-               data()->frame()->GetSpillSlotCount());
+               data()->frame()->GetTotalFrameSlotCount());
         range->SetSpillOperand(StackSlotOperand::cast(first_output));
         range->SetSpillStartIndex(instr_index + 1);
         assigned = true;
index 413fe635ac211779adc334516e81021a3b73922a..3ad07ad7de34e09d40abf226ecfc20bf894e332b 100644 (file)
@@ -7,6 +7,7 @@
 #include "src/compiler/code-generator-impl.h"
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/node-matchers.h"
+#include "src/compiler/osr.h"
 #include "src/scopes.h"
 #include "src/x64/assembler-x64.h"
 #include "src/x64/macro-assembler-x64.h"
@@ -1460,50 +1461,28 @@ void CodeGenerator::AssembleDeoptimizerCall(
 }
 
 
+namespace {
+
+static const int kQuadWordSize = 16;
+
+}  // namespace
+
+
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     __ pushq(rbp);
     __ movq(rbp, rsp);
-    int register_save_area_size = 0;
-    const RegList saves = descriptor->CalleeSavedRegisters();
-    if (saves != 0) {  // Save callee-saved registers.
-      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
-        if (!((1 << i) & saves)) continue;
-        __ pushq(Register::from_code(i));
-        register_save_area_size += kPointerSize;
-      }
-    }
-    const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
-    if (saves_fp != 0) {  // Save callee-saved XMM registers.
-      const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
-      const int stack_size = saves_fp_count * 16;
-      // Adjust the stack pointer.
-      __ subp(rsp, Immediate(stack_size));
-      // Store the registers on the stack.
-      int slot_idx = 0;
-      for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
-        if (!((1 << i) & saves_fp)) continue;
-        __ movdqu(Operand(rsp, 16 * slot_idx), XMMRegister::from_code(i));
-        slot_idx++;
-      }
-      register_save_area_size += stack_size;
-    }
-    if (register_save_area_size > 0) {
-      frame()->SetRegisterSaveAreaSize(register_save_area_size);
-    }
   } else if (descriptor->IsJSFunctionCall()) {
     CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
   } else if (needs_frame_) {
     __ StubPrologue();
-    frame()->SetRegisterSaveAreaSize(
-        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize);
   }
 
+  int stack_shrink_slots = frame()->GetSpillSlotCount();
   if (info()->is_osr()) {
     // TurboFan OSR-compiled functions cannot be entered directly.
     __ Abort(kShouldNotDirectlyEnterOsrFunction);
@@ -1516,53 +1495,76 @@ void CodeGenerator::AssemblePrologue() {
     osr_pc_offset_ = __ pc_offset();
     // TODO(titzer): cannot address target function == local #-1
     __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
-    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
-    stack_slots -= frame()->GetOsrStackSlotCount();
+    stack_shrink_slots -=
+        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
+  }
+
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    stack_shrink_slots += frame()->AlignSavedCalleeRegisterSlots();
+  }
+  if (stack_shrink_slots > 0) {
+    __ subq(rsp, Immediate(stack_shrink_slots * kPointerSize));
+  }
+
+  if (saves_fp != 0) {  // Save callee-saved XMM registers.
+    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
+    const int stack_size = saves_fp_count * kQuadWordSize;
+    // Adjust the stack pointer.
+    __ subp(rsp, Immediate(stack_size));
+    // Store the registers on the stack.
+    int slot_idx = 0;
+    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+      if (!((1 << i) & saves_fp)) continue;
+      __ movdqu(Operand(rsp, kQuadWordSize * slot_idx),
+                XMMRegister::from_code(i));
+      slot_idx++;
+    }
+    frame()->AllocateSavedCalleeRegisterSlots(saves_fp_count *
+                                              (kQuadWordSize / kPointerSize));
   }
 
-  if (stack_slots > 0) {
-    __ subq(rsp, Immediate(stack_slots * kPointerSize));
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {  // Save callee-saved registers.
+    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+      if (!((1 << i) & saves)) continue;
+      __ pushq(Register::from_code(i));
+      frame()->AllocateSavedCalleeRegisterSlots(1);
+    }
   }
 }
 
 
 void CodeGenerator::AssembleReturn() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  int stack_slots = frame()->GetSpillSlotCount();
-  if (descriptor->kind() == CallDescriptor::kCallAddress) {
-    if (frame()->GetRegisterSaveAreaSize() > 0) {
-      // Remove this frame's spill slots first.
-      if (stack_slots > 0) {
-        __ addq(rsp, Immediate(stack_slots * kPointerSize));
-      }
-      // Restore registers.
-      const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
-      if (saves_fp != 0) {
-        const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
-        const int stack_size = saves_fp_count * 16;
-        // Load the registers from the stack.
-        int slot_idx = 0;
-        for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
-          if (!((1 << i) & saves_fp)) continue;
-          __ movdqu(XMMRegister::from_code(i), Operand(rsp, 16 * slot_idx));
-          slot_idx++;
-        }
-        // Adjust the stack pointer.
-        __ addp(rsp, Immediate(stack_size));
-      }
-      const RegList saves = descriptor->CalleeSavedRegisters();
-      if (saves != 0) {
-        for (int i = 0; i < Register::kNumRegisters; i++) {
-          if (!((1 << i) & saves)) continue;
-          __ popq(Register::from_code(i));
-        }
-      }
-      __ popq(rbp);  // Pop caller's frame pointer.
-    } else {
-      // No saved registers.
-      __ movq(rsp, rbp);  // Move stack pointer back to frame pointer.
-      __ popq(rbp);       // Pop caller's frame pointer.
+
+  // Restore registers.
+  const RegList saves = descriptor->CalleeSavedRegisters();
+  if (saves != 0) {
+    for (int i = 0; i < Register::kNumRegisters; i++) {
+      if (!((1 << i) & saves)) continue;
+      __ popq(Register::from_code(i));
     }
+  }
+  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
+  if (saves_fp != 0) {
+    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
+    const int stack_size = saves_fp_count * kQuadWordSize;
+    // Load the registers from the stack.
+    int slot_idx = 0;
+    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
+      if (!((1 << i) & saves_fp)) continue;
+      __ movdqu(XMMRegister::from_code(i),
+                Operand(rsp, kQuadWordSize * slot_idx));
+      slot_idx++;
+    }
+    // Adjust the stack pointer.
+    __ addp(rsp, Immediate(stack_size));
+  }
+
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    __ movq(rsp, rbp);  // Move stack pointer back to frame pointer.
+    __ popq(rbp);       // Pop caller's frame pointer.
   } else if (descriptor->IsJSFunctionCall() || needs_frame_) {
     // Canonicalize JSFunction return sites for now.
     if (return_label_.is_bound()) {
index 4022a7e08523ea05f238aea464e80ccbfe42cd24..0efc4de369e0f78afcb44c2c0959756b013cf4ef 100644 (file)
@@ -2609,22 +2609,6 @@ int TranslatedValue::GetChildrenCount() const {
 }
 
 
-int TranslatedState::SlotOffsetFp(int slot_index) {
-  if (slot_index >= 0) {
-    const int offset = StandardFrameConstants::kExpressionsOffset;
-    return offset - (slot_index * kPointerSize);
-  } else {
-    const int offset = StandardFrameConstants::kCallerSPOffset;
-    return offset - ((slot_index + 1) * kPointerSize);
-  }
-}
-
-
-Address TranslatedState::SlotAddress(Address fp, int slot_index) {
-  return fp + SlotOffsetFp(slot_index);
-}
-
-
 uint32_t TranslatedState::GetUInt32Slot(Address fp, int slot_offset) {
   Address address = fp + slot_offset;
 #if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
@@ -2947,7 +2931,8 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
     }
 
     case Translation::STACK_SLOT: {
-      int slot_offset = SlotOffsetFp(iterator->Next());
+      int slot_offset =
+          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
       intptr_t value = *(reinterpret_cast<intptr_t*>(fp + slot_offset));
       if (trace_file != nullptr) {
         PrintF(trace_file, "0x%08" V8PRIxPTR " ; [fp %c %d] ", value,
@@ -2958,7 +2943,8 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
     }
 
     case Translation::INT32_STACK_SLOT: {
-      int slot_offset = SlotOffsetFp(iterator->Next());
+      int slot_offset =
+          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
       uint32_t value = GetUInt32Slot(fp, slot_offset);
       if (trace_file != nullptr) {
         PrintF(trace_file, "%d ; (int) [fp %c %d] ",
@@ -2969,7 +2955,8 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
     }
 
     case Translation::UINT32_STACK_SLOT: {
-      int slot_offset = SlotOffsetFp(iterator->Next());
+      int slot_offset =
+          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
       uint32_t value = GetUInt32Slot(fp, slot_offset);
       if (trace_file != nullptr) {
         PrintF(trace_file, "%u ; (uint) [fp %c %d] ", value,
@@ -2979,7 +2966,8 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
     }
 
     case Translation::BOOL_STACK_SLOT: {
-      int slot_offset = SlotOffsetFp(iterator->Next());
+      int slot_offset =
+          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
       uint32_t value = GetUInt32Slot(fp, slot_offset);
       if (trace_file != nullptr) {
         PrintF(trace_file, "%u ; (bool) [fp %c %d] ", value,
@@ -2989,7 +2977,8 @@ TranslatedValue TranslatedState::CreateNextTranslatedValue(
     }
 
     case Translation::DOUBLE_STACK_SLOT: {
-      int slot_offset = SlotOffsetFp(iterator->Next());
+      int slot_offset =
+          OptimizedFrame::StackSlotOffsetRelativeToFp(iterator->Next());
       double value = ReadDoubleValue(fp + slot_offset);
       if (trace_file != nullptr) {
         PrintF(trace_file, "%e ; (double) [fp %c %d] ", value,
index 68587abaf0305c4d2a00a1332b4e7decf274654f..b116ccd54da6019f9807e590c1ee4d9e416dd9de 100644 (file)
@@ -276,8 +276,6 @@ class TranslatedState {
   Handle<Object> MaterializeObjectAt(int object_index);
   bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index);
 
-  static int SlotOffsetFp(int slot_index);
-  static Address SlotAddress(Address fp, int slot_index);
   static uint32_t GetUInt32Slot(Address fp, int slot_index);
 
   std::vector<TranslatedFrame> frames_;
index 0b2a6b644930220e6ecd531d77560a3be3c24f62..8561e557e86fd78211ec5c1d08f163140841d642 100644 (file)
@@ -1079,18 +1079,14 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) {
 }
 
 
+int OptimizedFrame::StackSlotOffsetRelativeToFp(int slot_index) {
+  return StandardFrameConstants::kCallerSPOffset -
+         ((slot_index + 1) * kPointerSize);
+}
+
+
 Object* OptimizedFrame::StackSlotAt(int index) const {
-  // Positive index means the value is spilled to the locals
-  // area. Negative means it is stored in the incoming parameter
-  // area.
-  if (index >= 0) return GetExpression(index);
-
-  // Index -1 overlaps with last parameter, -n with the first parameter,
-  // (-n - 1) with the receiver with n being the number of parameters
-  // of the outermost, optimized frame.
-  int const parameter_count = ComputeParametersCount();
-  int const parameter_index = index + parameter_count;
-  return (parameter_index == -1) ? receiver() : GetParameter(parameter_index);
+  return Memory::Object_at(fp() + StackSlotOffsetRelativeToFp(index));
 }
 
 
index 9eee5a136e9b8d35cfa61215b7a06afb76e6e092..fecaec6fb75121f4a1aae774875c9caa2dfb5315 100644 (file)
@@ -120,8 +120,12 @@ class StandardFrameConstants : public AllStatic {
   static const int kCPSlotSize =
       FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
   static const int kFixedFrameSizeFromFp =  2 * kPointerSize + kCPSlotSize;
+  static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
   static const int kFixedFrameSize =
-      kPCOnStackSize + kFPOnStackSize + kFixedFrameSizeFromFp;
+      kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
+  static const int kFixedSlotCountAboveFp =
+      kFixedFrameSizeAboveFp / kPointerSize;
+  static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
   static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
   static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
   static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
@@ -678,6 +682,8 @@ class OptimizedFrame : public JavaScriptFrame {
 
   DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
 
+  static int StackSlotOffsetRelativeToFp(int slot_index);
+
  protected:
   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
 
index 7cc2d0c1ef20b530a4d8a7de0b96b37eb6959dd6..82b38ae515bee9c447ee35d7f21b23e6d484a3eb 100644 (file)
@@ -673,15 +673,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 5f38e70ce55488120a644ab282dafc0c3f950b46..32d17ed92283d1d711ce8a0e2a2e99a647214ed4 100644 (file)
@@ -645,15 +645,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 5d93fb504452b46a3315cfd390749d44fb532e53..50fd5266ae506fc6dc3c8ed9c49379248e7251ab 100644 (file)
@@ -633,15 +633,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 2b5def39c1050fe1d8f4d443a8e2f470e232fc6f..0398d7f5d1f1bcb5444ff38546ea322b2cf29524 100644 (file)
@@ -592,15 +592,23 @@ void LCodeGen::AddToTranslation(LEnvironment* environment,
   }
 
   if (op->IsStackSlot()) {
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
     if (is_tagged) {
-      translation->StoreStackSlot(op->index());
+      translation->StoreStackSlot(index);
     } else if (is_uint32) {
-      translation->StoreUint32StackSlot(op->index());
+      translation->StoreUint32StackSlot(index);
     } else {
-      translation->StoreInt32StackSlot(op->index());
+      translation->StoreInt32StackSlot(index);
     }
   } else if (op->IsDoubleStackSlot()) {
-    translation->StoreDoubleStackSlot(op->index());
+    int index = op->index();
+    if (index >= 0) {
+      index += StandardFrameConstants::kFixedFrameSize / kPointerSize;
+    }
+    translation->StoreDoubleStackSlot(index);
   } else if (op->IsRegister()) {
     Register reg = ToRegister(op);
     if (is_tagged) {
index 6b9b13114eecd618b2b9c4a660d4e098ca34c307..45293c3e99bf2d32419ffe54ee0517ae9c62d489 100644 (file)
         '../../src/compiler/dead-code-elimination.cc',
         '../../src/compiler/dead-code-elimination.h',
         '../../src/compiler/diamond.h',
+        '../../src/compiler/frame.cc',
         '../../src/compiler/frame.h',
         '../../src/compiler/frame-elider.cc',
         '../../src/compiler/frame-elider.h',