Update V8 to r4851 as required by WebKit r61121

Change-Id: Ib01b7c8e38d5b82b254192fc06365aa5b85780c5
diff --git a/test/mjsunit/keyed-call-ic.js b/test/mjsunit/keyed-call-ic.js
new file mode 100644
index 0000000..9d82965
--- /dev/null
+++ b/test/mjsunit/keyed-call-ic.js
@@ -0,0 +1,205 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// A test for keyed call ICs.
+
+var toStringName = 'toString';
+var global = this;
+
+function globalFunction1() {
+  return 'function1';
+}
+
+function globalFunction2() {
+  return 'function2';
+}
+
+assertEquals("[object global]", this[toStringName]());
+assertEquals("[object global]", global[toStringName]());
+
+function testGlobals() {
+  assertEquals("[object global]", this[toStringName]());
+  assertEquals("[object global]", global[toStringName]());
+}
+
+testGlobals();
+
+
+function F() {}
+
+F.prototype.one = function() {return 'one'; }
+F.prototype.two = function() {return 'two'; }
+F.prototype.three = function() {return 'three'; }
+
+var keys =
+    ['one', 'one', 'one',  'one', 'two', 'two', 'one', 'three', 'one', 'two'];
+
+function testKeyTransitions() {
+  var i, key, result, message;
+
+  var f = new F();
+
+  // Custom call generators
+  var array = [];
+  for (i = 0; i != 10; i++) {
+    key = (i < 8) ? 'push' : 'pop';
+    array[key](i);
+  }
+
+  assertEquals(6, array.length);
+  for (i = 0; i != array.length; i++) {
+    assertEquals(i, array[i]);
+  }
+
+  for (i = 0; i != 10; i++) {
+    key = (i < 3) ? 'pop' : 'push';
+    array[key](i);
+  }
+
+  assertEquals(10, array.length);
+  for (i = 0; i != array.length; i++) {
+    assertEquals(i, array[i]);
+  }
+
+  var string = 'ABCDEFGHIJ';
+  for (i = 0; i != 10; i++) {
+    key = ((i < 5) ? 'charAt' : 'charCodeAt');
+    result = string[key](i);
+    message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
+    if (i < 5) {
+      assertEquals(string.charAt(i), result, message);
+    } else {
+      assertEquals(string.charCodeAt(i), result, message);
+    }
+  }
+
+  for (i = 0; i != 10; i++) {
+    key = ((i < 5) ? 'charCodeAt' : 'charAt');
+    result = string[key](i);
+    message = '\'' + string + '\'[\'' + key + '\'](' + i + ')';
+    if (i < 5) {
+      assertEquals(string.charCodeAt(i), result, message);
+    } else {
+      assertEquals(string.charAt(i), result, message);
+    }
+  }
+
+  // Function is a constant property
+  key = 'one';
+  for (i = 0; i != 10; i++) {
+    assertEquals(key, f[key]());
+    if (i == 5) {
+      key = 'two';  // the name change should case a miss
+    }
+  }
+
+  // Function is a fast property
+  f.field = function() { return 'field'; }
+  key = 'field';
+  for (i = 0; i != 10; i++) {
+    assertEquals(key, f[key]());
+    if (i == 5) {
+      key = 'two';  // the name change should case a miss
+    }
+  }
+
+  // Calling on slow case object
+  f.prop = 0;
+  delete f.prop; // force the object to the slow case
+  f.four = function() { return 'four'; }
+  f.five = function() { return 'five'; }
+
+  key = 'four';
+  for (i = 0; i != 10; i++) {
+    assertEquals(key, f[key]());
+    if (i == 5) {
+      key = 'five';
+    }
+  }
+
+  // Calling on global object
+  key = 'globalFunction1';
+  var expect = 'function1';
+  for (i = 0; i != 10; i++) {
+    assertEquals(expect, global[key]());
+    if (i == 5) {
+      key = 'globalFunction2';
+      expect = 'function2';
+    }
+  }
+}
+
+testKeyTransitions();
+
+function testTypeTransitions() {
+  var f = new F();
+  var s = '';
+  var m = 'one';
+  var i;
+
+  s = '';
+  for (i = 0; i != 10; i++) {
+    if (i == 5)  { F.prototype.one = function() { return '1'; } }
+    s += f[m]();
+  }
+  assertEquals("oneoneoneoneone11111", s);
+
+  s = '';
+  for (i = 0; i != 10; i++) {
+    if (i == 5)  { f.__proto__ = { one: function() { return 'I'; } } }
+    s += f[m]();
+  }
+  assertEquals("11111IIIII", s);
+
+  s = '';
+  for (i = 0; i != 10; i++) {
+    if (i == 5)  { f.one = function() { return 'ONE'; } }
+    s += f[m]();
+  }
+  assertEquals("IIIIIONEONEONEONEONE", s);
+
+  m = 'toString';
+
+  s = '';
+  var obj = { toString: function() { return '2'; } };
+  for (i = 0; i != 10; i++) {
+    if (i == 5)  { obj = "TWO"; }
+    s += obj[m]();
+  }
+  assertEquals("22222TWOTWOTWOTWOTWO", s);
+
+  s = '';
+  obj = { toString: function() { return 'ONE'; } };
+  m = 'toString';
+  for (i = 0; i != 10; i++) {
+    if (i == 5)  { obj = 1; }
+    s += obj[m]();
+  }
+  assertEquals("ONEONEONEONEONE11111", s);
+}
+
+testTypeTransitions();