Reviewers: Michael Starzinger,

Description:
[turbofan] Fix OSR into functions where the expression stack is not empty.

[email protected]
BUG=

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

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

Affected files (+54, -44 lines):
  M src/compiler.h
  M src/compiler/arm/code-generator-arm.cc
  M src/compiler/arm64/code-generator-arm64.cc
  M src/compiler/ast-graph-builder.h
  M src/compiler/ast-graph-builder.cc
  M src/compiler/common-operator.cc
  M src/compiler/frame.h
  M src/compiler/ia32/code-generator-ia32.cc
  M src/compiler/mips/code-generator-mips.cc
  M src/compiler/mips64/code-generator-mips64.cc
  M src/compiler/osr.cc
  M src/compiler/x64/code-generator-x64.cc


Index: src/compiler.h
diff --git a/src/compiler.h b/src/compiler.h
index 11cec55dc58ccec0b997fe41d970c35420a0e853..611a41ba80bd47c639a5cc921075a5c0e0b3bd47 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -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: src/compiler/arm/code-generator-arm.cc
diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc index 894584b8d39b9ffbeb4c454b5863b58518664800..0e297c35fba9ea26ec0689766298484aa708e7f8 100644
--- a/src/compiler/arm/code-generator-arm.cc
+++ b/src/compiler/arm/code-generator-arm.cc
@@ -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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {
Index: src/compiler/arm64/code-generator-arm64.cc
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc index bea4805f56132f111484b0a5a17b91728cac865d..18bc81bc4c1cff0ff7c28e743f75ad16265240b6 100644
--- a/src/compiler/arm64/code-generator-arm64.cc
+++ b/src/compiler/arm64/code-generator-arm64.cc
@@ -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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {
Index: src/compiler/ast-graph-builder.cc
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 9e8b951b04f36eb0bf1fbe981f92661f8ecaead0..874bacbb1875a920f9e83e817121b67114c300b4 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -603,7 +603,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());
@@ -615,7 +615,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);
@@ -628,7 +628,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();
@@ -713,7 +713,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.
@@ -792,7 +792,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();
@@ -2411,8 +2411,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: src/compiler/ast-graph-builder.h
diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h index 175228dd88c43225151b0d310e51bf291ab2bd4d..b23247b907c86eda9aa2c633acfea58356494a41 100644
--- a/src/compiler/ast-graph-builder.h
+++ b/src/compiler/ast-graph-builder.h
@@ -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: src/compiler/common-operator.cc
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc index 49307d0cad14eda49704bd6efd580a452937ca48..b9aadefdae80a8e18c7f177a797d540c619f30a0 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -315,11 +315,11 @@ const Operator* CommonOperatorBuilder::Parameter(int index) {


 const Operator* CommonOperatorBuilder::OsrValue(int index) {
-  return new (zone()) Operator1<int>(        // --
-      IrOpcode::kOsrValue, Operator::kPure,  // opcode
-      "OsrValue",                            // name
-      0, 0, 1, 1, 0, 0,                      // counts
-      index);                                // parameter
+  return new (zone()) Operator1<int>(                // --
+      IrOpcode::kOsrValue, Operator::kNoProperties,  // opcode
+      "OsrValue",                                    // name
+      0, 0, 1, 1, 0, 0,                              // counts
+      index);                                        // parameter
 }


Index: src/compiler/frame.h
diff --git a/src/compiler/frame.h b/src/compiler/frame.h
index 416d6eea59fda4d16357062ead22c3058afcef54..af3433c2b2dfd9d981568fe20eb103fb3bbf5d64 100644
--- a/src/compiler/frame.h
+++ b/src/compiler/frame.h
@@ -23,6 +23,7 @@ class Frame : public ZoneObject {
       : register_save_area_size_(0),
         spill_slot_count_(0),
         double_spill_slot_count_(0),
+        osr_stack_slots_(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 SetOsrStackSlots(int slots) {
+    DCHECK(slots >= 0);
+    osr_stack_slots_ = slots;
+  }
+
+  int GetOsrStackSlots() { return osr_stack_slots_; }
+
   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_slots_;
   BitVector* allocated_registers_;
   BitVector* allocated_double_registers_;

Index: src/compiler/ia32/code-generator-ia32.cc
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index 525451a13b3868716b981daf8b91cca8fb18c55d..ba82b7f37bc9d8017338faf966f9c3ef72d81ff3 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -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"
@@ -1013,10 +1012,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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {
Index: src/compiler/mips/code-generator-mips.cc
diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc index ada0337c5229970b6699c82a09382e7b7637cca7..28d15d9700456a99b600cd3eefce90b11bfbb8ad 100644
--- a/src/compiler/mips/code-generator-mips.cc
+++ b/src/compiler/mips/code-generator-mips.cc
@@ -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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {
Index: src/compiler/mips64/code-generator-mips64.cc
diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc index 559beead8d7f374c588d8e7d47a9074069204dca..c36df5b1ccbba2fda5872e2b4af9a38adf467f95 100644
--- a/src/compiler/mips64/code-generator-mips64.cc
+++ b/src/compiler/mips64/code-generator-mips64.cc
@@ -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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {
Index: src/compiler/osr.cc
diff --git a/src/compiler/osr.cc b/src/compiler/osr.cc
index a4b845249f0ed3649f5f963f2c371dc84f168c5e..b97762b1cd64df75c6e503ba9ccf20c1fe06cb54 100644
--- a/src/compiler/osr.cc
+++ b/src/compiler/osr.cc
@@ -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->SetOsrStackSlots(UnoptimizedFrameSlots());
 }


Index: src/compiler/x64/code-generator-x64.cc
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index c4258a387d1f4c9f48cc1ad6b839c551a78b7274..7e4906d8abfec9503201e89c5b933dd0ee2a266e 100644
--- a/src/compiler/x64/code-generator-x64.cc
+++ b/src/compiler/x64/code-generator-x64.cc
@@ -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()->GetOsrStackSlots());
+    stack_slots -= frame()->GetOsrStackSlots();
   }

   if (stack_slots > 0) {


--
--
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