Reviewers: Weiliang,

Message:
PTAL

Description:
X87: [turbofan] Unify referencing of stack slots

port cbbaf9ea6abbc0417ee5765a4c58f1dda939ead0 (r30224).

original commit message:

    [turbofan] Unify referencing of stack slots

    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.

BUG=

Please review this at https://codereview.chromium.org/1293103003/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+43, -44 lines):
  M src/compiler/x87/code-generator-x87.cc
  M src/x87/lithium-codegen-x87.cc


Index: src/compiler/x87/code-generator-x87.cc
diff --git a/src/compiler/x87/code-generator-x87.cc b/src/compiler/x87/code-generator-x87.cc index c3e999bcbffc40b1fb12c5c10f4ba20e4498e7b5..d5eebadc0d29bffe7b5c901ac39f4b9fe9d34620 100644
--- a/src/compiler/x87/code-generator-x87.cc
+++ b/src/compiler/x87/code-generator-x87.cc
@@ -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/x87/assembler-x87.h"
 #include "src/x87/frames-x87.h"
@@ -1508,34 +1509,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);
@@ -1548,13 +1537,23 @@ 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);
   }

   // Initailize FPU state.
@@ -1565,28 +1564,20 @@ void CodeGenerator::AssemblePrologue() {

 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) {
-    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: src/x87/lithium-codegen-x87.cc
diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc
index 092df73de6e4bda0832c0760d5a2c27edc9c8327..0c1306e1445b6b15ab2819807aeb33d51fedc049 100644
--- a/src/x87/lithium-codegen-x87.cc
+++ b/src/x87/lithium-codegen-x87.cc
@@ -943,15 +943,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) {


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to