[turbofan] Fix OSR into functions where the expression stack is not empty.
authortitzer <titzer@chromium.org>
Mon, 2 Feb 2015 10:19:52 +0000 (02:19 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 2 Feb 2015 10:20:08 +0000 (10:20 +0000)
R=mstarzinger@chromium.org
BUG=

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

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

src/compiler.h
src/compiler/arm/code-generator-arm.cc
src/compiler/arm64/code-generator-arm64.cc
src/compiler/ast-graph-builder.cc
src/compiler/ast-graph-builder.h
src/compiler/frame.h
src/compiler/ia32/code-generator-ia32.cc
src/compiler/mips/code-generator-mips.cc
src/compiler/mips64/code-generator-mips64.cc
src/compiler/osr.cc
src/compiler/x64/code-generator-x64.cc

index 11cec55dc58ccec0b997fe41d970c35420a0e853..611a41ba80bd47c639a5cc921075a5c0e0b3bd47 100644 (file)
@@ -405,6 +405,12 @@ class CompilationInfo {
     ast_value_factory_owned_ = owned;
   }
 
+  int osr_expr_stack_height() { return osr_expr_stack_height_; }
+  void set_osr_expr_stack_height(int height) {
+    DCHECK(height >= 0);
+    osr_expr_stack_height_ = height;
+  }
+
 #if DEBUG
   void PrintAstForTesting();
 #endif
@@ -531,6 +537,8 @@ class CompilationInfo {
   // should be abandoned due to dependency change.
   bool aborted_due_to_dependency_change_;
 
+  int osr_expr_stack_height_;
+
   DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
 };
 
index 894584b8d39b9ffbeb4c454b5863b58518664800..f3d2cce5c9fe2014c9cd85cf1c564aa4668be212 100644 (file)
@@ -8,7 +8,6 @@
 #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 {
@@ -807,10 +806,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {
index bea4805f56132f111484b0a5a17b91728cac865d..1aa20207e73abfa90c5b9082e72242eded0c3d99 100644 (file)
@@ -8,7 +8,6 @@
 #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 {
@@ -900,10 +899,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {
index 3bec6648a52e6dbdd705cbaaae1287834bfa0ccf..18475d1dca6d6d1958d998be8dfc299da6f4c0ea 100644 (file)
@@ -604,7 +604,7 @@ void AstGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
 
 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   VisitIterationBody(stmt, &while_loop, 0);
   while_loop.EndBody();
   VisitForTest(stmt->cond());
@@ -616,7 +616,7 @@ void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
 
 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   VisitForTest(stmt->cond());
   Node* condition = environment()->Pop();
   while_loop.BreakUnless(condition);
@@ -629,7 +629,7 @@ void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
   LoopBuilder for_loop(this);
   VisitIfNotNull(stmt->init());
-  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   if (stmt->cond() != NULL) {
     VisitForTest(stmt->cond());
     Node* condition = environment()->Pop();
@@ -714,7 +714,7 @@ void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
 // TODO(dcarney): this is a big function.  Try to clean up some.
 void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
   LoopBuilder for_loop(this);
-  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
 
   // These stack values are renamed in the case of OSR, so reload them
   // from the environment.
@@ -793,7 +793,7 @@ void AstGraphBuilder::VisitForInBody(ForInStatement* stmt) {
 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
   LoopBuilder for_loop(this);
   VisitForEffect(stmt->assign_iterator());
-  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), IsOsrLoopEntry(stmt));
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt), CheckOsrEntry(stmt));
   VisitForEffect(stmt->next_result());
   VisitForTest(stmt->result_done());
   Node* condition = environment()->Pop();
@@ -2412,8 +2412,13 @@ Node* AstGraphBuilder::BuildStackCheck() {
 }
 
 
-bool AstGraphBuilder::IsOsrLoopEntry(IterationStatement* stmt) {
-  return info()->osr_ast_id() == stmt->OsrEntryId();
+bool AstGraphBuilder::CheckOsrEntry(IterationStatement* stmt) {
+  if (info()->osr_ast_id() == stmt->OsrEntryId()) {
+    info()->set_osr_expr_stack_height(std::max(
+        environment()->stack_height(), info()->osr_expr_stack_height()));
+    return true;
+  }
+  return false;
 }
 
 
index 175228dd88c43225151b0d310e51bf291ab2bd4d..b23247b907c86eda9aa2c633acfea58356494a41 100644 (file)
@@ -116,7 +116,9 @@ class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
   // Builder for stack-check guards.
   Node* BuildStackCheck();
 
-  bool IsOsrLoopEntry(IterationStatement* stmt);
+  // Check if the given statement is an OSR entry.
+  // If so, record the stack height into the compilation and return {true}.
+  bool CheckOsrEntry(IterationStatement* stmt);
 
 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
 
index 416d6eea59fda4d16357062ead22c3058afcef54..ce1ecd061cc5e5e9eb8e4b6802d0ac782c3a442c 100644 (file)
@@ -23,6 +23,7 @@ class Frame : public ZoneObject {
       : register_save_area_size_(0),
         spill_slot_count_(0),
         double_spill_slot_count_(0),
+        osr_stack_slot_count_(0),
         allocated_registers_(NULL),
         allocated_double_registers_(NULL) {}
 
@@ -50,6 +51,14 @@ class Frame : public ZoneObject {
 
   int GetRegisterSaveAreaSize() { return register_save_area_size_; }
 
+  // OSR stack slots, including locals and expression stack slots.
+  void SetOsrStackSlotCount(int slots) {
+    DCHECK(slots >= 0);
+    osr_stack_slot_count_ = slots;
+  }
+
+  int GetOsrStackSlotCount() { return osr_stack_slot_count_; }
+
   int AllocateSpillSlot(bool is_double) {
     // If 32-bit, skip one if the new slot is a double.
     if (is_double) {
@@ -72,6 +81,7 @@ class Frame : public ZoneObject {
   int register_save_area_size_;
   int spill_slot_count_;
   int double_spill_slot_count_;
+  int osr_stack_slot_count_;
   BitVector* allocated_registers_;
   BitVector* allocated_double_registers_;
 
index 525451a13b3868716b981daf8b91cca8fb18c55d..54336dc31ee6f8abf1d321b22bfe16d2673cfcf9 100644 (file)
@@ -7,7 +7,6 @@
 #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/macro-assembler-ia32.h"
 #include "src/scopes.h"
@@ -974,8 +973,7 @@ void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  Frame* frame = this->frame();
-  int stack_slots = frame->GetSpillSlotCount();
+  int stack_slots = frame()->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     // Assemble a prologue similar the to cdecl calling convention.
     __ push(ebp);
@@ -988,18 +986,18 @@ void CodeGenerator::AssemblePrologue() {
         __ push(Register::from_code(i));
         register_save_area_size += kPointerSize;
       }
-      frame->SetRegisterSaveAreaSize(register_save_area_size);
+      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(
+    frame()->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
   } else {
     __ StubPrologue();
-    frame->SetRegisterSaveAreaSize(
+    frame()->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
   }
 
@@ -1013,10 +1011,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {
index c081f51bdbd9f89194cf4cd046c016040235bf07..39d1d4ad96c8efcdca8884fefc38dbc6d363f4e7 100644 (file)
@@ -6,7 +6,6 @@
 #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"
 
@@ -916,10 +915,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {
index 9fef60994344fe2a3a7f0e03115f8038028d7d3b..853346f1c35f09b3b96873509235d2bc39de43da 100644 (file)
@@ -6,7 +6,6 @@
 #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"
 
@@ -1086,10 +1085,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {
index a4b845249f0ed3649f5f963f2c371dc84f168c5e..e3da5c52973c7264f815493a7fcb0c1a3b6df09e 100644 (file)
@@ -20,7 +20,8 @@ namespace compiler {
 
 OsrHelper::OsrHelper(CompilationInfo* info)
     : parameter_count_(info->scope()->num_parameters()),
-      stack_slot_count_(info->scope()->num_stack_slots()) {}
+      stack_slot_count_(info->scope()->num_stack_slots() +
+                        info->osr_expr_stack_height()) {}
 
 
 bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common,
@@ -75,6 +76,8 @@ 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()));
 }
 
 
index c4258a387d1f4c9f48cc1ad6b839c551a78b7274..f5117f292a8cc300c98ec0273e40edb6f473fd7f 100644 (file)
@@ -7,7 +7,6 @@
 #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"
@@ -1179,10 +1178,8 @@ void CodeGenerator::AssemblePrologue() {
     // remaining stack slots.
     if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
     osr_pc_offset_ = __ pc_offset();
-    int unoptimized_slots =
-        static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
-    DCHECK(stack_slots >= unoptimized_slots);
-    stack_slots -= unoptimized_slots;
+    DCHECK(stack_slots >= frame()->GetOsrStackSlotCount());
+    stack_slots -= frame()->GetOsrStackSlotCount();
   }
 
   if (stack_slots > 0) {