Version 4.9.385.36 (cherry-pick)

Merged c2e82d6e828a6108e1599cc5da79ec2d63291ecc

[crankshaft] Fix inlining to always connect both branches of test context.

BUG=v8:4839
LOG=N
R=jarin@chromium.org

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

Cr-Commit-Position: refs/branch-heads/4.9@{#42}
Cr-Branched-From: 2fea296569597e5064f81fd8fce58f1848de261a-refs/heads/4.9.385@{#1}
Cr-Branched-From: 0c1430ac2b65847559d6a09f883ee7e5a91063c9-refs/heads/master@{#33306}
diff --git a/include/v8-version.h b/include/v8-version.h
index 1213993..f89ad64 100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 4
 #define V8_MINOR_VERSION 9
 #define V8_BUILD_NUMBER 385
-#define V8_PATCH_LEVEL 35
+#define V8_PATCH_LEVEL 36
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/crankshaft/hydrogen.cc b/src/crankshaft/hydrogen.cc
index 98337be..522a679 100644
--- a/src/crankshaft/hydrogen.cc
+++ b/src/crankshaft/hydrogen.cc
@@ -4955,9 +4955,8 @@
     // will always evaluate to true, in a value context the return value needs
     // to be a JSObject.
     if (context->IsTest()) {
-      TestContext* test = TestContext::cast(context);
       CHECK_ALIVE(VisitForEffect(stmt->expression()));
-      Goto(test->if_true(), state);
+      context->ReturnValue(graph()->GetConstantTrue());
     } else if (context->IsEffect()) {
       CHECK_ALIVE(VisitForEffect(stmt->expression()));
       Goto(function_return(), state);
@@ -8531,7 +8530,7 @@
       // return value will always evaluate to true, in a value context the
       // return value is the newly allocated receiver.
       if (call_context()->IsTest()) {
-        Goto(inlined_test_context()->if_true(), state);
+        inlined_test_context()->ReturnValue(graph()->GetConstantTrue());
       } else if (call_context()->IsEffect()) {
         Goto(function_return(), state);
       } else {
@@ -8554,7 +8553,7 @@
       // Falling off the end of a normal inlined function. This basically means
       // returning undefined.
       if (call_context()->IsTest()) {
-        Goto(inlined_test_context()->if_false(), state);
+        inlined_test_context()->ReturnValue(graph()->GetConstantFalse());
       } else if (call_context()->IsEffect()) {
         Goto(function_return(), state);
       } else {
diff --git a/test/mjsunit/regress/regress-v8-4839.js b/test/mjsunit/regress/regress-v8-4839.js
new file mode 100644
index 0000000..120685b
--- /dev/null
+++ b/test/mjsunit/regress/regress-v8-4839.js
@@ -0,0 +1,62 @@
+// Copyright 2016 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: --allow-natives-syntax
+
+function dummy() { }
+
+(function InlinedFunctionTestContext() {
+  var f = function() { }
+
+  function g() {
+   var s = "hey";
+   dummy();  // Force a deopt point.
+   if (f()) return s;
+  }
+
+  g();
+  g();
+  g();
+  %OptimizeFunctionOnNextCall(g);
+  f = function() { return true; }
+  assertEquals("hey", g());
+})();
+
+(function InlinedConstructorReturnTestContext() {
+  function c() { return 1; }
+
+  var f = function() { return !(new c());  }
+
+  function g() {
+   var s = "hey";
+   dummy();  // Force a deopt point.
+   if (f()) return s;
+  }
+
+  g();
+  g();
+  g();
+  %OptimizeFunctionOnNextCall(g);
+  f = function() { return true; }
+  assertEquals("hey", g());
+})();
+
+(function InlinedConstructorNoReturnTestContext() {
+  function c() { }
+
+  var f = function() { return !(new c());  }
+
+  function g() {
+   var s = "hey";
+   dummy();  // Force a deopt point.
+   if (f()) return s;
+  }
+
+  g();
+  g();
+  g();
+  %OptimizeFunctionOnNextCall(g);
+  f = function() { return true; }
+  assertEquals("hey", g());
+})();