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());
+})();