Revision: 19834
Author:   [email protected]
Date:     Wed Mar 12 09:59:36 2014 UTC
Log:      Fix lazy deopt after tagged binary ops

Also add policing code to ensure that optimized frames can in fact lazily deopt
at their respective current PC when we patch them for lazy bailout.

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

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

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-crbug-350434.js
Modified:
 /branches/bleeding_edge/src/a64/lithium-a64.cc
 /branches/bleeding_edge/src/a64/lithium-a64.h
 /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc
 /branches/bleeding_edge/src/a64/lithium-codegen-a64.h
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.h
 /branches/bleeding_edge/src/deoptimizer.cc
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.h
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.h
 /branches/bleeding_edge/src/safepoint-table.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.h
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-crbug-350434.js Wed Mar 12 09:59:36 2014 UTC
@@ -0,0 +1,33 @@
+// Copyright 2014 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.
+
+// Flags: --gc-global --noincremental-marking --allow-natives-syntax
+
+function Ctor() {
+  this.foo = 1;
+}
+
+var o = new Ctor();
+var p = new Ctor();
+
+
+function crash(o, timeout) {
+  var s = "4000111222";  // Outside Smi range.
+  %SetAllocationTimeout(100000, timeout);
+  // This allocates a heap number, causing a GC, triggering lazy deopt.
+  var end = s >>> 0;
+  s = s.substring(0, end);
+  // This creates a map dependency, which gives the GC a reason to trigger
+  // a lazy deopt when that map dies.
+  o.bar = 2;
+}
+
+crash(o, 100000);
+crash(o, 100000);
+crash(p, 100000);
+%OptimizeFunctionOnNextCall(crash);
+crash(o, 100000);
+o = null;
+p = null;
+crash({}, 0);
=======================================
--- /branches/bleeding_edge/src/a64/lithium-a64.cc Tue Mar 11 17:12:34 2014 UTC +++ /branches/bleeding_edge/src/a64/lithium-a64.cc Wed Mar 12 09:59:36 2014 UTC
@@ -506,15 +506,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
@@ -736,6 +727,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;
 }
@@ -2106,21 +2117,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/bleeding_edge/src/a64/lithium-a64.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/a64/lithium-a64.h Wed Mar 12 09:59:36 2014 UTC
@@ -2976,9 +2976,7 @@
         status_(UNUSED),
         current_instruction_(NULL),
         current_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();
@@ -3115,8 +3113,6 @@
   HInstruction* current_instruction_;
   HBasicBlock* current_block_;
   LAllocator* allocator_;
-  LInstruction* instruction_pending_deoptimization_environment_;
-  BailoutId pending_deoptimization_ast_id_;

   DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
 };
=======================================
--- /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Tue Mar 11 17:12:34 2014 UTC +++ /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Wed Mar 12 09:59:36 2014 UTC
@@ -769,6 +769,13 @@
   ASSERT(slots >= 0);
   __ Claim(slots);
 }
+
+
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}


 bool LCodeGen::GenerateDeferredCode() {
=======================================
--- /branches/bleeding_edge/src/a64/lithium-codegen-a64.h Mon Mar 10 10:39:17 2014 UTC +++ /branches/bleeding_edge/src/a64/lithium-codegen-a64.h Wed Mar 12 09:59:36 2014 UTC
@@ -276,6 +276,7 @@
   void RestoreCallerDoubles();

// Code generation steps. Returns true if code generation should continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Mar 11 11:57:27 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Wed Mar 12 09:59:36 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
@@ -905,6 +896,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;
 }
@@ -2445,21 +2456,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/bleeding_edge/src/arm/lithium-arm.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.h Wed Mar 12 09:59:36 2014 UTC
@@ -2720,9 +2720,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();
@@ -2866,8 +2864,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/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Mar 12 09:59:36 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() {
@@ -2066,7 +2073,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/bleeding_edge/src/arm/lithium-codegen-arm.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.h Wed Mar 12 09:59:36 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/bleeding_edge/src/deoptimizer.cc  Wed Mar  5 12:57:18 2014 UTC
+++ /branches/bleeding_edge/src/deoptimizer.cc  Wed Mar 12 09:59:36 2014 UTC
@@ -391,10 +391,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/bleeding_edge/src/heap.cc Tue Mar 11 14:41:22 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Wed Mar 12 09:59:36 2014 UTC
@@ -614,6 +614,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/bleeding_edge/src/hydrogen-instructions.cc Wed Mar 12 06:49:28 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Mar 12 09:59:36 2014 UTC
@@ -2470,6 +2470,7 @@


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


=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Wed Mar 12 06:49:28 2014 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Mar 12 09:59:36 2014 UTC
@@ -1877,7 +1877,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;
@@ -1960,7 +1961,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/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Wed Mar 12 09:59:36 2014 UTC
@@ -390,6 +390,9 @@


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

@@ -2285,7 +2288,6 @@

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


=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Mar 11 11:57:27 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Mar 12 09:59:36 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;
 }
@@ -2585,22 +2596,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/bleeding_edge/src/ia32/lithium-ia32.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Wed Mar 12 09:59:36 2014 UTC
@@ -2752,9 +2752,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();
@@ -2906,8 +2904,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/bleeding_edge/src/mips/lithium-codegen-mips.cc Tue Mar 11 22:16:56 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Mar 12 09:59:36 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/bleeding_edge/src/mips/lithium-codegen-mips.h Tue Mar 11 22:16:56 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Wed Mar 12 09:59:36 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/bleeding_edge/src/mips/lithium-mips.cc Tue Mar 11 19:04:14 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Wed Mar 12 09:59:36 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
@@ -913,6 +904,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;
 }
@@ -2347,21 +2358,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/bleeding_edge/src/mips/lithium-mips.h Tue Mar 11 22:16:56 2014 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.h Wed Mar 12 09:59:36 2014 UTC
@@ -2642,9 +2642,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();
@@ -2784,8 +2782,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/bleeding_edge/src/safepoint-table.h Thu Nov 7 16:35:27 2013 UTC +++ /branches/bleeding_edge/src/safepoint-table.h Wed Mar 12 09:59:36 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/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Mar 12 09:59:36 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() {
@@ -1900,7 +1907,6 @@

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


=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.h Wed Mar 12 09:59:36 2014 UTC
@@ -157,6 +157,7 @@

   // Code generation passes.  Returns true if code generation should
   // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
   bool GeneratePrologue();
   bool GenerateDeferredCode();
   bool GenerateJumpTable();
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Mar 12 06:46:55 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Mar 12 09:59:36 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;
 }
@@ -2435,21 +2446,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/bleeding_edge/src/x64/lithium-x64.h Tue Mar 11 14:41:22 2014 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.h Wed Mar 12 09:59:36 2014 UTC
@@ -2666,9 +2666,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();
@@ -2813,8 +2811,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