Reviewers: Michael Starzinger,

Message:
Could you take a look, please?

Unfortunately, the clusterfuzz repro ends up in an infinite loop, so I cannot
use it as a regression test (and I did not find a way to make it terminate
without breaking the repro).

Description:
Fix deoptimization of context.

We need to handle the case where the context was removed by dead code
elimination. In that case, we just use the context from the activation
(or from the inlined function if we are inlined).

For reference, here is the CL that introduced the bug:
https://codereview.chromium.org/522873002

BUG=410566
LOG=N

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

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+24, -6 lines):
  M src/deoptimizer.cc
  M test/cctest/compiler/test-codegen-deopt.cc


Index: src/deoptimizer.cc
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 6b381dade9f84080493b10b15efdb5bbf8da8ebc..e874122e133703715d1e5d7af654def060a2775a 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -1067,6 +1067,18 @@ void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
   // The context should not be a placeholder for a materialized object.
   CHECK(value !=
         reinterpret_cast<intptr_t>(isolate_->heap()->arguments_marker()));
+  if (value ==
+      reinterpret_cast<intptr_t>(isolate_->heap()->undefined_value())) {
+    // If the context was optimized away, just use the context from
+    // the activation. This should only apply to Crankshaft code.
+    CHECK(!compiled_code_->is_turbofanned());
+    if (is_bottommost) {
+      value = input_->GetFrameSlot(input_offset);
+    } else {
+      value = reinterpret_cast<intptr_t>(function->context());
+    }
+    output_frame->SetFrameSlot(output_offset, value);
+  }
   output_frame->SetContext(value);
   if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
   if (trace_scope_ != NULL) {
Index: test/cctest/compiler/test-codegen-deopt.cc
diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc index 551cc96df988bc4cc145540ee41a39fb7f6bc1b3..7b7a3c26f824c152cd6f789bd2450b7ddc2a58f7 100644
--- a/test/cctest/compiler/test-codegen-deopt.cc
+++ b/test/cctest/compiler/test-codegen-deopt.cc
@@ -139,10 +139,11 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester { PrintableUnique<Object>::CreateUninitialized(zone(), deopt_function); Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));

- Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
-    PrintableUnique<Object> context_constant =
-        PrintableUnique<Object>::CreateUninitialized(zone(), context);
-    Node* context_node = m.NewNode(common.HeapConstant(context_constant));
+ Handle<Context> caller_context(function->context(), CcTest::i_isolate());
+    PrintableUnique<Object> caller_context_constant =
+ PrintableUnique<Object>::CreateUninitialized(zone(), caller_context);
+    Node* caller_context_node =
+        m.NewNode(common.HeapConstant(caller_context_constant));

     bailout_id = GetCallBailoutId();
Node* parameters = m.NewNode(common.StateValues(1), m.UndefinedConstant()); @@ -151,7 +152,12 @@ class TrivialDeoptCodegenTester : public DeoptCodegenTester {

     Node* state_node =
         m.NewNode(common.FrameState(bailout_id, kIgnoreOutput), parameters,
- locals, stack, m.UndefinedConstant(), m.UndefinedConstant()); + locals, stack, caller_context_node, m.UndefinedConstant());
+
+ Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
+    PrintableUnique<Object> context_constant =
+        PrintableUnique<Object>::CreateUninitialized(zone(), context);
+    Node* context_node = m.NewNode(common.HeapConstant(context_constant));

m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);

@@ -260,7 +266,7 @@ class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {

     Node* state_node =
         m.NewNode(common.FrameState(bailout_id, kIgnoreOutput), parameters,
- locals, stack, m.UndefinedConstant(), m.UndefinedConstant());
+                  locals, stack, context_node, m.UndefinedConstant());

m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
                    state_node);


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