Revision: 20066
Author:   [email protected]
Date:     Wed Mar 19 12:50:00 2014 UTC
Log:      Merged r19834, r19843 into 3.24 branch.

Fix lazy deopt after tagged binary ops

BUG=chromium:350434
LOG=N
[email protected]

Review URL: https://codereview.chromium.org/201153020
http://code.google.com/p/v8/source/detail?r=20066

Modified:
 /branches/3.24/src/arm/lithium-arm.cc
 /branches/3.24/src/arm/lithium-codegen-arm.cc
 /branches/3.24/src/arm/lithium-codegen-arm.h
 /branches/3.24/src/deoptimizer.cc
 /branches/3.24/src/heap.cc
 /branches/3.24/src/hydrogen-instructions.cc
 /branches/3.24/src/hydrogen-instructions.h
 /branches/3.24/src/ia32/lithium-codegen-ia32.cc
 /branches/3.24/src/ia32/lithium-ia32.cc
 /branches/3.24/src/ia32/lithium-ia32.h
 /branches/3.24/src/mips/lithium-codegen-mips.cc
 /branches/3.24/src/mips/lithium-codegen-mips.h
 /branches/3.24/src/mips/lithium-mips.cc
 /branches/3.24/src/mips/lithium-mips.h
 /branches/3.24/src/safepoint-table.h
 /branches/3.24/src/serialize.h
 /branches/3.24/src/version.cc
 /branches/3.24/src/x64/lithium-codegen-x64.cc
 /branches/3.24/src/x64/lithium-codegen-x64.h
 /branches/3.24/src/x64/lithium-x64.cc
 /branches/3.24/src/x64/lithium-x64.h

=======================================
--- /branches/3.24/src/arm/lithium-arm.cc       Thu Feb  6 01:06:18 2014 UTC
+++ /branches/3.24/src/arm/lithium-arm.cc       Wed Mar 19 12:50:00 2014 UTC
@@ -614,15 +614,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);

-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -906,6 +897,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+ LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+ SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -2378,21 +2389,6 @@

 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LInstruction* result = new(zone()) LLazyBailout;
-    result = AssignEnvironment(result);
- // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }

=======================================
--- /branches/3.24/src/arm/lithium-codegen-arm.cc Mon Mar 3 09:38:07 2014 UTC +++ /branches/3.24/src/arm/lithium-codegen-arm.cc Wed Mar 19 12:50:00 2014 UTC
@@ -267,6 +267,13 @@
   ASSERT(slots >= 0);
   __ sub(sp, sp, Operand(slots * kPointerSize));
 }
+
+
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}


 bool LCodeGen::GenerateDeferredCode() {
@@ -2112,7 +2119,6 @@
   // is in the correct position.
   Assembler::BlockConstPoolScope block_const_pool(masm());
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }


=======================================
--- /branches/3.24/src/arm/lithium-codegen-arm.h Wed Jan 15 10:29:52 2014 UTC +++ /branches/3.24/src/arm/lithium-codegen-arm.h Wed Mar 19 12:50:00 2014 UTC
@@ -191,6 +191,7 @@

   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
=======================================
--- /branches/3.24/src/deoptimizer.cc   Tue Mar 11 09:00:16 2014 UTC
+++ /branches/3.24/src/deoptimizer.cc   Wed Mar 19 12:50:00 2014 UTC
@@ -392,10 +392,34 @@
     }
     element = next;
   }
+
+#ifdef DEBUG
+ // Make sure all activations of optimized code can deopt at their current PC.
+  for (StackFrameIterator it(isolate, isolate->thread_local_top());
+       !it.done(); it.Advance()) {
+    StackFrame::Type type = it.frame()->type();
+    if (type == StackFrame::OPTIMIZED) {
+      Code* code = it.frame()->LookupCode();
+      if (FLAG_trace_deopt) {
+        JSFunction* function =
+            static_cast<OptimizedFrame*>(it.frame())->function();
+        CodeTracer::Scope scope(isolate->GetCodeTracer());
+        PrintF(scope.file(), "[deoptimizer patches for lazy deopt: ");
+        function->PrintName(scope.file());
+        PrintF(scope.file(),
+ " / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
+      }
+      SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
+      int deopt_index = safepoint.deoptimization_index();
+      CHECK(deopt_index != Safepoint::kNoDeoptimizationIndex);
+    }
+  }
+#endif

// TODO(titzer): we need a handle scope only because of the macro assembler,
   // which is only used in EnsureCodeForDeoptimizationEntry.
   HandleScope scope(isolate);
+
   // Now patch all the codes for deoptimization.
   for (int i = 0; i < codes.length(); i++) {
     // It is finally time to die, code object.
=======================================
--- /branches/3.24/src/heap.cc  Mon Feb 10 09:01:23 2014 UTC
+++ /branches/3.24/src/heap.cc  Wed Mar 19 12:50:00 2014 UTC
@@ -590,6 +590,9 @@
   if (FLAG_code_stats) ReportCodeStatistics("After GC");
 #endif
   if (FLAG_deopt_every_n_garbage_collections > 0) {
+    // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that
+    // the topmost optimized frame can be deoptimized safely, because it
+    // might not have a lazy bailout point right after its current PC.
if (++gcs_since_last_deopt_ == FLAG_deopt_every_n_garbage_collections) {
       Deoptimizer::DeoptimizeAll(isolate());
       gcs_since_last_deopt_ = 0;
=======================================
--- /branches/3.24/src/hydrogen-instructions.cc Mon Mar 17 10:45:33 2014 UTC
+++ /branches/3.24/src/hydrogen-instructions.cc Wed Mar 19 12:50:00 2014 UTC
@@ -2413,6 +2413,7 @@


 void HSimulate::ReplayEnvironment(HEnvironment* env) {
+  if (done_with_replay_) return;
   ASSERT(env != NULL);
   env->set_ast_id(ast_id());
   env->Drop(pop_count());
@@ -2424,6 +2425,7 @@
       env->Push(value);
     }
   }
+  done_with_replay_ = true;
 }


=======================================
--- /branches/3.24/src/hydrogen-instructions.h  Mon Mar 17 09:49:32 2014 UTC
+++ /branches/3.24/src/hydrogen-instructions.h  Wed Mar 19 12:50:00 2014 UTC
@@ -1799,7 +1799,8 @@
         values_(2, zone),
         assigned_indexes_(2, zone),
         zone_(zone),
-        removable_(removable) {}
+        removable_(removable),
+        done_with_replay_(false) {}
   ~HSimulate() {}

   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
@@ -1882,7 +1883,8 @@
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
   Zone* zone_;
-  RemovableSimulate removable_;
+  RemovableSimulate removable_ : 2;
+  bool done_with_replay_ : 1;

 #ifdef DEBUG
   Handle<JSFunction> closure_;
=======================================
--- /branches/3.24/src/ia32/lithium-codegen-ia32.cc Mon Mar 3 09:38:07 2014 UTC +++ /branches/3.24/src/ia32/lithium-codegen-ia32.cc Wed Mar 19 12:50:00 2014 UTC
@@ -390,6 +390,9 @@


 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
   if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
 }

@@ -2274,7 +2277,6 @@

   BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }


=======================================
--- /branches/3.24/src/ia32/lithium-ia32.cc     Thu Feb  6 01:06:18 2014 UTC
+++ /branches/3.24/src/ia32/lithium-ia32.cc     Wed Mar 19 12:50:00 2014 UTC
@@ -679,15 +679,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);

-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -980,6 +971,26 @@
       chunk_->AddInstruction(clobber, current_block_);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+ LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+ SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -2486,22 +2497,6 @@

 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (!pending_deoptimization_ast_id_.IsNone()) {
-    ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
-    LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
-    LInstruction* result = AssignEnvironment(lazy_bailout);
- // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }

=======================================
--- /branches/3.24/src/ia32/lithium-ia32.h      Fri Jan 31 14:01:53 2014 UTC
+++ /branches/3.24/src/ia32/lithium-ia32.h      Wed Mar 19 12:50:00 2014 UTC
@@ -2591,9 +2591,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }

   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2736,8 +2734,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;

   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
=======================================
--- /branches/3.24/src/mips/lithium-codegen-mips.cc Mon Mar 3 09:38:07 2014 UTC +++ /branches/3.24/src/mips/lithium-codegen-mips.cc Wed Mar 19 12:50:00 2014 UTC
@@ -257,6 +257,13 @@
   ASSERT(slots >= 0);
   __ Subu(sp, sp, Operand(slots * kPointerSize));
 }
+
+
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}


 bool LCodeGen::GenerateDeferredCode() {
=======================================
--- /branches/3.24/src/mips/lithium-codegen-mips.h Wed Jan 15 10:29:52 2014 UTC +++ /branches/3.24/src/mips/lithium-codegen-mips.h Wed Mar 19 12:50:00 2014 UTC
@@ -191,6 +191,7 @@

   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
=======================================
--- /branches/3.24/src/mips/lithium-mips.cc     Thu Feb  6 01:06:18 2014 UTC
+++ /branches/3.24/src/mips/lithium-mips.cc     Wed Mar 19 12:50:00 2014 UTC
@@ -619,15 +619,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);

-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -914,6 +905,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+ LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+ SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -2307,21 +2318,6 @@

 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LInstruction* result = new(zone()) LLazyBailout;
-    result = AssignEnvironment(result);
- // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }

=======================================
--- /branches/3.24/src/mips/lithium-mips.h      Fri Jan 31 14:01:53 2014 UTC
+++ /branches/3.24/src/mips/lithium-mips.h      Wed Mar 19 12:50:00 2014 UTC
@@ -2554,9 +2554,7 @@
         current_block_(NULL),
         next_block_(NULL),
         allocator_(allocator),
-        position_(RelocInfo::kNoPosition),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        position_(RelocInfo::kNoPosition) { }

   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2691,8 +2689,6 @@
   HBasicBlock* next_block_;
   LAllocator* allocator_;
   int position_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;

   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
=======================================
--- /branches/3.24/src/safepoint-table.h        Fri Nov  8 10:23:52 2013 UTC
+++ /branches/3.24/src/safepoint-table.h        Wed Mar 19 12:50:00 2014 UTC
@@ -219,6 +219,9 @@
   // Record deoptimization index for lazy deoptimization for the last
   // outstanding safepoints.
   void RecordLazyDeoptimizationIndex(int index);
+  void BumpLastLazySafepointIndex() {
+    last_lazy_safepoint_ = deopt_index_list_.length();
+  }

   // Emit the safepoint table after the body. The number of bits per
   // entry must be enough to hold all the pointer indexes.
=======================================
--- /branches/3.24/src/serialize.h      Tue Dec 17 07:57:53 2013 UTC
+++ /branches/3.24/src/serialize.h      Wed Mar 19 12:50:00 2014 UTC
@@ -60,7 +60,7 @@
 const int kDebugRegisterBits = 4;
 const int kDebugIdShift = kDebugRegisterBits;

-const int kDeoptTableSerializeEntryCount = 8;
+const int kDeoptTableSerializeEntryCount = 12;

 // ExternalReferenceTable is a helper class that defines the relationship
 // between external references and their encodings. It is used to build
=======================================
--- /branches/3.24/src/version.cc       Mon Mar 17 10:45:33 2014 UTC
+++ /branches/3.24/src/version.cc       Wed Mar 19 12:50:00 2014 UTC
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     24
 #define BUILD_NUMBER      35
-#define PATCH_LEVEL       17
+#define PATCH_LEVEL       18
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.24/src/x64/lithium-codegen-x64.cc Mon Mar 17 10:45:33 2014 UTC +++ /branches/3.24/src/x64/lithium-codegen-x64.cc Wed Mar 19 12:50:00 2014 UTC
@@ -271,6 +271,13 @@
   ASSERT(slots >= 0);
   __ subq(rsp, Immediate(slots * kPointerSize));
 }
+
+
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}


 bool LCodeGen::GenerateJumpTable() {
@@ -1870,7 +1877,6 @@

   BinaryOpICStub stub(instr->op(), NO_OVERWRITE);
   CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-  __ nop();  // Signals no inlined code.
 }


=======================================
--- /branches/3.24/src/x64/lithium-codegen-x64.h Wed Jan 15 10:29:52 2014 UTC +++ /branches/3.24/src/x64/lithium-codegen-x64.h Wed Mar 19 12:50:00 2014 UTC
@@ -159,6 +159,7 @@

   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateJumpTable();
=======================================
--- /branches/3.24/src/x64/lithium-x64.cc       Mon Mar 17 09:49:32 2014 UTC
+++ /branches/3.24/src/x64/lithium-x64.cc       Wed Mar 19 12:50:00 2014 UTC
@@ -630,15 +630,6 @@
   instr->MarkAsCall();
   instr = AssignPointerMap(instr);

-  if (hinstr->HasObservableSideEffects()) {
-    ASSERT(hinstr->next()->IsSimulate());
-    HSimulate* sim = HSimulate::cast(hinstr->next());
-    ASSERT(instruction_pending_deoptimization_environment_ == NULL);
-    ASSERT(pending_deoptimization_ast_id_.IsNone());
-    instruction_pending_deoptimization_environment_ = instr;
-    pending_deoptimization_ast_id_ = sim->ast_id();
-  }
-
   // If instruction does not have side-effects lazy deoptimization
   // after the call will try to deoptimize to the point before the call.
   // Thus we still need to attach environment to this call even if
@@ -916,6 +907,26 @@
       instr = AssignEnvironment(instr);
     }
     chunk_->AddInstruction(instr, current_block_);
+
+    if (instr->IsCall()) {
+      HValue* hydrogen_value_for_lazy_bailout = current;
+      LInstruction* instruction_needing_environment = NULL;
+      if (current->HasObservableSideEffects()) {
+        HSimulate* sim = HSimulate::cast(current->next());
+        instruction_needing_environment = instr;
+        sim->ReplayEnvironment(current_block_->last_environment());
+        hydrogen_value_for_lazy_bailout = sim;
+      }
+ LInstruction* bailout = AssignEnvironment(new(zone()) LLazyBailout());
+      bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+      chunk_->AddInstruction(bailout, current_block_);
+      if (instruction_needing_environment != NULL) {
+        // Store the lazy deopt environment with the instruction if needed.
+        // Right now it is only used for LInstanceOfKnownGlobal.
+        instruction_needing_environment->
+ SetDeferredLazyDeoptimizationEnvironment(bailout->environment());
+      }
+    }
   }
   current_instruction_ = old_current;
 }
@@ -2334,21 +2345,6 @@

 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
   instr->ReplayEnvironment(current_block_->last_environment());
-
-  // If there is an instruction pending deoptimization environment create a
-  // lazy bailout instruction to capture the environment.
-  if (pending_deoptimization_ast_id_ == instr->ast_id()) {
-    LLazyBailout* lazy_bailout = new(zone()) LLazyBailout;
-    LInstruction* result = AssignEnvironment(lazy_bailout);
- // Store the lazy deopt environment with the instruction if needed. Right
-    // now it is only used for LInstanceOfKnownGlobal.
-    instruction_pending_deoptimization_environment_->
-        SetDeferredLazyDeoptimizationEnvironment(result->environment());
-    instruction_pending_deoptimization_environment_ = NULL;
-    pending_deoptimization_ast_id_ = BailoutId::None();
-    return result;
-  }
-
   return NULL;
 }

=======================================
--- /branches/3.24/src/x64/lithium-x64.h        Mon Mar 17 09:49:32 2014 UTC
+++ /branches/3.24/src/x64/lithium-x64.h        Wed Mar 19 12:50:00 2014 UTC
@@ -2510,9 +2510,7 @@
         current_instruction_(NULL),
         current_block_(NULL),
         next_block_(NULL),
-        allocator_(allocator),
-        instruction_pending_deoptimization_environment_(NULL),
-        pending_deoptimization_ast_id_(BailoutId::None()) { }
+        allocator_(allocator) { }

   // Build the sequence for the graph.
   LPlatformChunk* Build();
@@ -2648,8 +2646,6 @@
   HBasicBlock* current_block_;
   HBasicBlock* next_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;

   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };

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