Upgrade V8 to 5.1.281.57  DO NOT MERGE

FPIIM-449

Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/test/mjsunit/es6/tail-call-megatest.js b/test/mjsunit/es6/tail-call-megatest.js
index 0057961..1de8ec6 100644
--- a/test/mjsunit/es6/tail-call-megatest.js
+++ b/test/mjsunit/es6/tail-call-megatest.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --allow-natives-syntax --harmony-tailcalls --no-turbo-inlining
+// Flags: --allow-natives-syntax --harmony-tailcalls
 
 
 Error.prepareStackTrace = (error,stack) => {
@@ -11,23 +11,15 @@
 }
 
 
-function CheckStackTrace(expected) {
+function checkStackTrace(expected) {
   var e = new Error();
   e.stack;  // prepare stack trace
   var stack = e.strace;
-  assertEquals("CheckStackTrace", stack[0].getFunctionName());
+  assertEquals("checkStackTrace", stack[0].getFunctionName());
   for (var i = 0; i < expected.length; i++) {
     assertEquals(expected[i].name, stack[i + 1].getFunctionName());
   }
 }
-%NeverOptimizeFunction(CheckStackTrace);
-
-
-function CheckArguments(expected, args) {
-  args = Array.prototype.slice.call(args);
-  assertEquals(expected, args);
-}
-%NeverOptimizeFunction(CheckArguments);
 
 
 var CAN_INLINE_COMMENT  = "// Let it be inlined.";
@@ -45,28 +37,59 @@
   return ident + source.replace(/\n/gi, "\n" + ident);
 }
 
-var global = Function('return this')();
-var the_receiver = {receiver: 1};
+var SHARDS_COUNT = 10;
 
-function run_tests() {
+function run_tests(shard) {
   function inlinable_comment(inlinable) {
     return inlinable ? CAN_INLINE_COMMENT : DONT_INLINE_COMMENT;
   }
 
+  // Check arguments manually to avoid bailing out with reason "bad value
+  // context for arguments value".
+  function check_arguments_template(expected_name) {
+    var lines = [
+      `  assertEquals_(${expected_name}.length, arguments.length);`,
+      `  for (var i = 0; i < ${expected_name}.length; i++) {`,
+      `    assertEquals_(${expected_name}[i], arguments[i]);`,
+      `  }`,
+    ];
+    return lines.join("\n");
+  }
+  var check_arguments = check_arguments_template("expected_args");
+
+  function deopt_template(deopt_mode) {
+    switch(deopt_mode) {
+      case "none":
+        return "  // Don't deoptimize";
+      case "f":
+      case "g":
+      case "test":
+        return `  %DeoptimizeFunction(${deopt_mode});`;
+      default:
+        assertUnreachable();
+    }
+  }
+
   var f_cfg_sloppy = {
     func_name: 'f',
     source_template: function(cfg) {
       var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
                                                  : "global";
+      var do_checks = [
+        `  assertEquals_(${receiver}, this);`,
+        `  ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.target);`,
+        check_arguments,
+        `  checkStackTrace_([f, test]);`,
+      ].join("\n");
+
       var lines = [
         `function f(a) {`,
         `  ${inlinable_comment(cfg.f_inlinable)}`,
-        `  assertEquals(${receiver}, this);`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
-        `  %DeoptimizeNow();`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
+        `  counter++;`,
+        `  var expected_args = [${cfg.f_args}];`,
+        do_checks,
+        deopt_template(cfg.deopt_mode),
+        do_checks,
         `  return 42;`,
         `}`,
       ];
@@ -79,16 +102,22 @@
     source_template: function(cfg) {
       var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
                                                  : "undefined";
+      var do_checks = [
+        `  assertEquals_(${receiver}, this);`,
+        `  ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.target);`,
+        check_arguments,
+        `  checkStackTrace_([f, test]);`,
+      ].join("\n");
+
       var lines = [
         `function f(a) {`,
         `  "use strict";`,
         `  ${inlinable_comment(cfg.f_inlinable)}`,
-        `  assertEquals(${receiver}, this);`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
-        `  %DeoptimizeNow();`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
+        `  counter++;`,
+        `  var expected_args = [${cfg.f_args}];`,
+        do_checks,
+        deopt_template(cfg.deopt_mode),
+        do_checks,
         `  return 42;`,
         `}`,
       ];
@@ -101,15 +130,21 @@
     source_template: function(cfg) {
       var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
                                                  : "global";
+      var do_checks = [
+        `  assertEquals_(${receiver}, this);`,
+        `  ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.target);`,
+        check_arguments,
+        `  checkStackTrace_([f, test]);`,
+      ].join("\n");
+
       var lines = [
         `function f(a) {`,
         `  ${inlinable_comment(cfg.f_inlinable)}`,
-        `  assertEquals(${receiver}, this);`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
-        `  %DeoptimizeNow();`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
+        `  counter++;`,
+        `  var expected_args = [${cfg.f_args}];`,
+        do_checks,
+        deopt_template(cfg.deopt_mode),
+        do_checks,
         `  return 42;`,
         `}`,
         `var eval = f;`,
@@ -121,16 +156,22 @@
   var f_cfg_bound = {
     func_name: 'bound',
     source_template: function(cfg) {
+      var do_checks = [
+        `  assertEquals_(receiver, this);`,
+        `  ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.target);`,
+        check_arguments,
+        `  checkStackTrace_([f, test]);`,
+      ].join("\n");
+
       var lines = [
         `function f(a) {`,
         `  "use strict";`,
         `  ${inlinable_comment(cfg.f_inlinable)}`,
-        `  assertEquals(receiver, this);`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
-        `  %DeoptimizeNow();`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
+        `  counter++;`,
+        `  var expected_args = [${cfg.f_args}];`,
+        do_checks,
+        deopt_template(cfg.deopt_mode),
+        do_checks,
         `  return 42;`,
         `}`,
         `var receiver = {a: 153};`,
@@ -145,15 +186,21 @@
     source_template: function(cfg) {
       var receiver = cfg.f_receiver != undefined ? cfg.f_receiver
                                                  : "global";
+      var do_checks = [
+        `  assertEquals_(${receiver}, this);`,
+        `  ${!cfg.check_new_target ? "// " : ""}assertEquals_(undefined, new.target);`,
+        check_arguments,
+        `  checkStackTrace_([f, test]);`,
+      ].join("\n");
+
       var lines = [
         `function f(a) {`,
         `  ${inlinable_comment(cfg.f_inlinable)}`,
-        `  assertEquals(${receiver}, this);`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
-        `  %DeoptimizeNow();`,
-        `  CheckArguments([${cfg.f_args}], arguments);`,
-        `  CheckStackTrace([f, test]);`,
+        `  counter++;`,
+        `  var expected_args = [${cfg.f_args}];`,
+        do_checks,
+        deopt_template(cfg.deopt_mode),
+        do_checks,
         `  return 42;`,
         `}`,
         `var p = new Proxy(f, {});`,
@@ -169,7 +216,8 @@
         `function g(a) {`,
         `  "use strict";`,
         `  ${inlinable_comment(cfg.g_inlinable)}`,
-        `  CheckArguments([${cfg.g_args}], arguments);`,
+        `  var expected_args = [${cfg.g_args}];`,
+        check_arguments,
         `  return ${cfg.f_name}(${cfg.f_args});`,
         `}`,
       ];
@@ -178,6 +226,23 @@
   };
 
 
+  var g_cfg_reflect_apply = {
+    receiver: "the_receiver",
+    source_template: function(cfg) {
+      var lines = [
+        `function g(a) {`,
+        `  "use strict";`,
+        `  ${inlinable_comment(cfg.g_inlinable)}`,
+        `  var expected_args = [${cfg.g_args}];`,
+        check_arguments,
+        `  return Reflect.apply(${cfg.f_name}, the_receiver, [${cfg.f_args}]);`,
+        `}`,
+      ];
+      return lines.join("\n");
+    },
+  };
+
+
   var g_cfg_function_apply = {
     receiver: "the_receiver",
     source_template: function(cfg) {
@@ -185,7 +250,8 @@
         `function g(a) {`,
         `  "use strict";`,
         `  ${inlinable_comment(cfg.g_inlinable)}`,
-        `  CheckArguments([${cfg.g_args}], arguments);`,
+        `  var expected_args = [${cfg.g_args}];`,
+        check_arguments,
         `  return ${cfg.f_name}.apply(the_receiver, [${cfg.f_args}]);`,
         `}`,
       ];
@@ -194,6 +260,24 @@
   };
 
 
+  var g_cfg_function_apply_arguments_object = {
+    receiver: "the_receiver",
+    source_template: function(cfg) {
+      cfg.f_args = cfg.g_args;
+      var lines = [
+        `function g(a) {`,
+        `  "use strict";`,
+        `  ${inlinable_comment(cfg.g_inlinable)}`,
+        `  var expected_args = [${cfg.g_args}];`,
+        check_arguments,
+        `  return ${cfg.f_name}.apply(the_receiver, arguments);`,
+        `}`,
+      ];
+      return lines.join("\n");
+    },
+  };
+
+
   var g_cfg_function_call = {
     receiver: "the_receiver",
     source_template: function(cfg) {
@@ -205,7 +289,8 @@
         `function g(a) {`,
         `  "use strict";`,
         `  ${inlinable_comment(cfg.g_inlinable)}`,
-        `  CheckArguments([${cfg.g_args}], arguments);`,
+        `  var expected_args = [${cfg.g_args}];`,
+        check_arguments,
         `  return ${cfg.f_name}.call(${f_args});`,
         `}`,
       ];
@@ -215,27 +300,39 @@
 
 
   function test_template(cfg) {
-    var f_source = cfg.f_source_template(cfg);
+    // Note: g_source_template modifies cfg.f_args in some cases.
     var g_source = cfg.g_source_template(cfg);
-    f_source = ident_source(f_source, 2);
     g_source = ident_source(g_source, 2);
 
+    var f_source = cfg.f_source_template(cfg);
+    f_source = ident_source(f_source, 2);
+
     var lines = [
       `(function() {`,
+      `  // Avoid bailing out because of "Reference to a variable which requires dynamic lookup".`,
+      `  var assertEquals_ = assertEquals;`,
+      `  var checkStackTrace_ = checkStackTrace;`,
+      `  var undefined = void 0;`,
+      `  var global = Function('return this')();`,
+      `  var the_receiver = {receiver: 1};`,
+      `  var counter = 0;`,
+      ``,
+      `  // Don't inline helper functions`,
+      `  %NeverOptimizeFunction(assertEquals);`,
+      `  %NeverOptimizeFunction(checkStackTrace);`,
+      ``,
       f_source,
       g_source,
       `  function test() {`,
       `    "use strict";`,
-      `    assertEquals(42, g(${cfg.g_args}));`,
+      `    assertEquals_(42, g(${cfg.g_args}));`,
       `  }`,
-      `  ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : ""};`,
-      `  ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : ""};`,
-      ``,
-      `  test();`,
+      `  ${"test();".repeat(cfg.test_warmup_count)}`,
+      `  ${cfg.f_inlinable ? "%SetForceInlineFlag(f)" : "%OptimizeFunctionOnNextCall(f)"};`,
+      `  ${cfg.g_inlinable ? "%SetForceInlineFlag(g)" : "%OptimizeFunctionOnNextCall(g)"};`,
       `  %OptimizeFunctionOnNextCall(test);`,
-      `  %OptimizeFunctionOnNextCall(f);`,
-      `  %OptimizeFunctionOnNextCall(g);`,
       `  test();`,
+      `  assertEquals(${1 + cfg.test_warmup_count}, counter);`,
       `})();`,
       ``,
     ];
@@ -243,11 +340,13 @@
     return source;
   }
 
-  // TODO(v8:4698), TODO(ishell): support all commented cases.
   var f_args_variants = ["", "1", "1, 2"];
-  var g_args_variants = [/*"",*/ "10", /*"10, 20"*/];
-  var f_inlinable_variants = [/*true,*/ false];
+  var g_args_variants = ["", "10", "10, 20"];
+  var f_inlinable_variants = [true, false];
   var g_inlinable_variants = [true, false];
+  // This is to avoid bailing out because of referencing new.target.
+  var check_new_target_variants = [true, false];
+  var deopt_mode_variants = ["none", "f", "g", "test"];
   var f_variants = [
       f_cfg_sloppy,
       f_cfg_strict,
@@ -257,36 +356,60 @@
   ];
   var g_variants = [
       g_cfg_normal,
-      g_cfg_function_call,
+      g_cfg_reflect_apply,
       g_cfg_function_apply,
+      g_cfg_function_apply_arguments_object,
+      g_cfg_function_call,
   ];
+  var test_warmup_counts = [0, 1, 2];
 
+  var iter = 0;
+  var tests_executed = 0;
+  if (shard !== undefined) {
+    print("Running shard #" + shard);
+  }
   f_variants.forEach((f_cfg) => {
-    g_variants.forEach((g_cfg) => {
-      f_args_variants.forEach((f_args) => {
-        g_args_variants.forEach((g_args) => {
-          f_inlinable_variants.forEach((f_inlinable) => {
-            g_inlinable_variants.forEach((g_inlinable) => {
-              var cfg = {
-                f_source_template: f_cfg.source_template,
-                f_inlinable,
-                f_args,
-                f_name: f_cfg.func_name,
-                f_receiver: g_cfg.receiver,
-                g_source_template: g_cfg.source_template,
-                g_inlinable,
-                g_args,
-              };
-              var source = test_template(cfg);
-              print("====================");
-              print(source);
-              eval(source);
+    check_new_target_variants.forEach((check_new_target) => {
+      deopt_mode_variants.forEach((deopt_mode) => {
+        g_variants.forEach((g_cfg) => {
+          f_args_variants.forEach((f_args) => {
+            g_args_variants.forEach((g_args) => {
+              f_inlinable_variants.forEach((f_inlinable) => {
+                g_inlinable_variants.forEach((g_inlinable) => {
+                  test_warmup_counts.forEach((test_warmup_count) => {
+                    if (shard !== undefined && (iter++) % SHARDS_COUNT != shard) {
+                      print("skipping...");
+                      return;
+                    }
+                    tests_executed++;
+                    var cfg = {
+                      f_source_template: f_cfg.source_template,
+                      f_inlinable,
+                      f_args,
+                      f_name: f_cfg.func_name,
+                      f_receiver: g_cfg.receiver,
+                      g_source_template: g_cfg.source_template,
+                      g_inlinable,
+                      g_args,
+                      test_warmup_count,
+                      check_new_target,
+                      deopt_mode,
+                    };
+                    var source = test_template(cfg);
+                    print("====================");
+                    print(source);
+                    eval(source);
+                  });
+                });
+              });
             });
           });
         });
       });
     });
   });
+  print("Number of tests executed: " + tests_executed);
 }
 
-run_tests();
+// Uncomment to run all the tests at once or use shard runners.
+//run_tests();