Upgrade to 3.29

Update V8 to 3.29.88.17 and update makefiles to support building on
all the relevant platforms.

Bug: 17370214

Change-Id: Ia3407c157fd8d72a93e23d8318ccaf6ecf77fa4e
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 32f78a7..108b9f2 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -25,7 +25,13 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax --expose-gc
+// Flags: --allow-natives-syntax
+
+// Helper
+function assertInstance(o, f) {
+  assertSame(o.constructor, f);
+  assertInstanceof(o, f);
+}
 
 // This is a regression test for overlapping key and value registers.
 function f(a) {
@@ -43,22 +49,65 @@
 assertEquals(0, a[0]);
 assertEquals(0, a[1]);
 
-// No-parameter constructor should fail right now.
-function abfunc1() {
-  return new ArrayBuffer();
-}
-assertThrows(abfunc1);
-
 // Test derivation from an ArrayBuffer
 var ab = new ArrayBuffer(12);
+assertInstance(ab, ArrayBuffer);
 var derived_uint8 = new Uint8Array(ab);
+assertInstance(derived_uint8, Uint8Array);
+assertSame(ab, derived_uint8.buffer);
 assertEquals(12, derived_uint8.length);
+assertEquals(12, derived_uint8.byteLength);
+assertEquals(0, derived_uint8.byteOffset);
+assertEquals(1, derived_uint8.BYTES_PER_ELEMENT);
+var derived_uint8_2 = new Uint8Array(ab,7);
+assertInstance(derived_uint8_2, Uint8Array);
+assertSame(ab, derived_uint8_2.buffer);
+assertEquals(5, derived_uint8_2.length);
+assertEquals(5, derived_uint8_2.byteLength);
+assertEquals(7, derived_uint8_2.byteOffset);
+assertEquals(1, derived_uint8_2.BYTES_PER_ELEMENT);
+var derived_int16 = new Int16Array(ab);
+assertInstance(derived_int16, Int16Array);
+assertSame(ab, derived_int16.buffer);
+assertEquals(6, derived_int16.length);
+assertEquals(12, derived_int16.byteLength);
+assertEquals(0, derived_int16.byteOffset);
+assertEquals(2, derived_int16.BYTES_PER_ELEMENT);
+var derived_int16_2 = new Int16Array(ab,6);
+assertInstance(derived_int16_2, Int16Array);
+assertSame(ab, derived_int16_2.buffer);
+assertEquals(3, derived_int16_2.length);
+assertEquals(6, derived_int16_2.byteLength);
+assertEquals(6, derived_int16_2.byteOffset);
+assertEquals(2, derived_int16_2.BYTES_PER_ELEMENT);
 var derived_uint32 = new Uint32Array(ab);
+assertInstance(derived_uint32, Uint32Array);
+assertSame(ab, derived_uint32.buffer);
 assertEquals(3, derived_uint32.length);
+assertEquals(12, derived_uint32.byteLength);
+assertEquals(0, derived_uint32.byteOffset);
+assertEquals(4, derived_uint32.BYTES_PER_ELEMENT);
 var derived_uint32_2 = new Uint32Array(ab,4);
+assertInstance(derived_uint32_2, Uint32Array);
+assertSame(ab, derived_uint32_2.buffer);
 assertEquals(2, derived_uint32_2.length);
+assertEquals(8, derived_uint32_2.byteLength);
+assertEquals(4, derived_uint32_2.byteOffset);
+assertEquals(4, derived_uint32_2.BYTES_PER_ELEMENT);
 var derived_uint32_3 = new Uint32Array(ab,4,1);
+assertInstance(derived_uint32_3, Uint32Array);
+assertSame(ab, derived_uint32_3.buffer);
 assertEquals(1, derived_uint32_3.length);
+assertEquals(4, derived_uint32_3.byteLength);
+assertEquals(4, derived_uint32_3.byteOffset);
+assertEquals(4, derived_uint32_3.BYTES_PER_ELEMENT);
+var derived_float64 = new Float64Array(ab,0,1);
+assertInstance(derived_float64, Float64Array);
+assertSame(ab, derived_float64.buffer);
+assertEquals(1, derived_float64.length);
+assertEquals(8, derived_float64.byteLength);
+assertEquals(0, derived_float64.byteOffset);
+assertEquals(8, derived_float64.BYTES_PER_ELEMENT);
 
 // If a given byteOffset and length references an area beyond the end of the
 // ArrayBuffer an exception is raised.
@@ -87,12 +136,29 @@
 }
 assertThrows(abfunc6);
 
-// Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
-// "constant", but not read-only).
+// Test that an array constructed without an array buffer creates one properly.
+a = new Uint8Array(31);
+assertEquals(a.byteLength, a.buffer.byteLength);
+assertEquals(a.length, a.buffer.byteLength);
+assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
+a = new Int16Array(5);
+assertEquals(a.byteLength, a.buffer.byteLength);
+assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
+a = new Float64Array(7);
+assertEquals(a.byteLength, a.buffer.byteLength);
+assertEquals(a.length * a.BYTES_PER_ELEMENT, a.buffer.byteLength);
+
+// Test that an implicitly created buffer is a valid buffer.
+a = new Float64Array(7);
+assertSame(a.buffer, (new Uint16Array(a.buffer)).buffer);
+assertSame(a.buffer, (new Float32Array(a.buffer,4)).buffer);
+assertSame(a.buffer, (new Int8Array(a.buffer,3,51)).buffer);
+assertInstance(a.buffer, ArrayBuffer);
+
+// Test the correct behavior of the |BYTES_PER_ELEMENT| property
 a = new Int32Array(2);
 assertEquals(4, a.BYTES_PER_ELEMENT);
 a.BYTES_PER_ELEMENT = 42;
-assertEquals(42, a.BYTES_PER_ELEMENT);
 a = new Uint8Array(2);
 assertEquals(1, a.BYTES_PER_ELEMENT);
 a = new Int16Array(2);
@@ -128,19 +194,10 @@
 // Test non-number parameters.
 var array_with_length_from_non_number = new Int32Array("2");
 assertEquals(2, array_with_length_from_non_number.length);
-array_with_length_from_non_number = new Int32Array(undefined);
-assertEquals(0, array_with_length_from_non_number.length);
-var foo = { valueOf: function() { return 3; } };
-array_with_length_from_non_number = new Int32Array(foo);
-assertEquals(3, array_with_length_from_non_number.length);
-foo = { toString: function() { return "4"; } };
-array_with_length_from_non_number = new Int32Array(foo);
-assertEquals(4, array_with_length_from_non_number.length);
-
 
 // Test loads and stores.
 types = [Array, Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array,
-         Uint32Array, PixelArray, Float32Array, Float64Array];
+         Uint32Array, Uint8ClampedArray, Float32Array, Float64Array];
 
 test_result_nan = [NaN, 0, 0, 0, 0, 0, 0, 0, NaN, NaN];
 test_result_low_int = [-1, -1, 255, -1, 65535, -1, 0xFFFFFFFF, 0, -1, -1];
@@ -244,7 +301,7 @@
   }
   assertEquals(expected_result, sum);
   %DeoptimizeFunction(test_func);
-  gc();  // Makes V8 forget about type information for test_func.
+  %ClearFunctionTypeFeedback(test_func);
 }
 
 function run_bounds_test(test_func, array, expected_result) {
@@ -285,8 +342,6 @@
     a.length = 2;
     assertEquals(kElementCount, a.length);
     assertTrue(delete a.length);
-    a.length = 2;
-    assertEquals(2, a.length);
 
     // Make sure bounds checks are handled correctly for external arrays.
     run_bounds_test(a);
@@ -295,8 +350,7 @@
     %OptimizeFunctionOnNextCall(run_bounds_test);
     run_bounds_test(a);
     %DeoptimizeFunction(run_bounds_test);
-    gc();  // Makes V8 forget about type information for test_func.
-
+    %ClearFunctionTypeFeedback(run_bounds_test);
   }
 
   function array_load_set_smi_check(a) {
@@ -315,7 +369,7 @@
   array_load_set_smi_check2(a);
   array_load_set_smi_check2(0);
   %DeoptimizeFunction(array_load_set_smi_check2);
-  gc();  // Makes V8 forget about type information for array_load_set_smi_check.
+  %ClearFunctionTypeFeedback(array_load_set_smi_check2);
 }
 
 // Check handling of undefined in 32- and 64-bit external float arrays.
@@ -351,3 +405,311 @@
 %OptimizeFunctionOnNextCall(store_float64_undefined);
 store_float64_undefined(float64_array);
 assertTrue(isNaN(float64_array[0]));
+
+
+// Check handling of 0-sized buffers and arrays.
+ab = new ArrayBuffer(0);
+assertInstance(ab, ArrayBuffer);
+assertEquals(0, ab.byteLength);
+a = new Int8Array(ab);
+assertInstance(a, Int8Array);
+assertEquals(0, a.byteLength);
+assertEquals(0, a.length);
+a[0] = 1;
+assertEquals(undefined, a[0]);
+ab = new ArrayBuffer(16);
+assertInstance(ab, ArrayBuffer);
+a = new Float32Array(ab,4,0);
+assertInstance(a, Float32Array);
+assertEquals(0, a.byteLength);
+assertEquals(0, a.length);
+a[0] = 1;
+assertEquals(undefined, a[0]);
+a = new Uint16Array(0);
+assertInstance(a, Uint16Array);
+assertEquals(0, a.byteLength);
+assertEquals(0, a.length);
+a[0] = 1;
+assertEquals(undefined, a[0]);
+
+// Check construction from arrays.
+a = new Uint32Array([]);
+assertInstance(a, Uint32Array);
+assertEquals(0, a.length);
+assertEquals(0, a.byteLength);
+assertEquals(0, a.buffer.byteLength);
+assertEquals(4, a.BYTES_PER_ELEMENT);
+assertInstance(a.buffer, ArrayBuffer);
+a = new Uint16Array([1,2,3]);
+assertInstance(a, Uint16Array);
+assertEquals(3, a.length);
+assertEquals(6, a.byteLength);
+assertEquals(6, a.buffer.byteLength);
+assertEquals(2, a.BYTES_PER_ELEMENT);
+assertEquals(1, a[0]);
+assertEquals(3, a[2]);
+assertInstance(a.buffer, ArrayBuffer);
+a = new Uint32Array(a);
+assertInstance(a, Uint32Array);
+assertEquals(3, a.length);
+assertEquals(12, a.byteLength);
+assertEquals(12, a.buffer.byteLength);
+assertEquals(4, a.BYTES_PER_ELEMENT);
+assertEquals(1, a[0]);
+assertEquals(3, a[2]);
+assertInstance(a.buffer, ArrayBuffer);
+
+// Check subarrays.
+a = new Uint16Array([1,2,3,4,5,6]);
+aa = a.subarray(3);
+assertInstance(aa, Uint16Array);
+assertEquals(3, aa.length);
+assertEquals(6, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(3,5);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(4,8);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(9);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-4);
+assertInstance(aa, Uint16Array);
+assertEquals(4, aa.length);
+assertEquals(8, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-3,-1);
+assertInstance(aa, Uint16Array);
+assertEquals(2, aa.length);
+assertEquals(4, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(3,2);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(-3,-4);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+aa = a.subarray(0,-8);
+assertInstance(aa, Uint16Array);
+assertEquals(0, aa.length);
+assertEquals(0, aa.byteLength);
+assertEquals(2, aa.BYTES_PER_ELEMENT);
+assertSame(a.buffer, aa.buffer);
+
+assertThrows(function(){ a.subarray.call({}, 0) });
+assertThrows(function(){ a.subarray.call([], 0) });
+
+// Try to call constructors directly as functions, and through .call
+// and .apply. Should fail.
+
+assertThrows(function() { ArrayBuffer(100); }, TypeError);
+assertThrows(function() { Int8Array(b, 5, 77); }, TypeError);
+assertThrows(function() { ArrayBuffer.call(null, 10); }, TypeError);
+assertThrows(function() { Uint16Array.call(null, b, 2, 4); }, TypeError);
+assertThrows(function() { ArrayBuffer.apply(null, [1000]); }, TypeError);
+assertThrows(function() { Float32Array.apply(null, [b, 128, 1]); }, TypeError);
+
+// Test array.set in different combinations.
+var b = new ArrayBuffer(4)
+
+function assertArrayPrefix(expected, array) {
+  for (var i = 0; i < expected.length; ++i) {
+    assertEquals(expected[i], array[i]);
+  }
+}
+
+var a11 = new Int16Array([1, 2, 3, 4, 0, -1])
+var a12 = new Uint16Array(15)
+a12.set(a11, 3)
+assertArrayPrefix([0, 0, 0, 1, 2, 3, 4, 0, 0xffff, 0, 0], a12)
+assertThrows(function(){ a11.set(a12) })
+
+var a21 = [1, undefined, 10, NaN, 0, -1, {valueOf: function() {return 3}}]
+var a22 = new Int32Array(12)
+a22.set(a21, 2)
+assertArrayPrefix([0, 0, 1, 0, 10, 0, 0, -1, 3, 0], a22)
+
+var a31 = new Float32Array([2, 4, 6, 8, 11, NaN, 1/0, -3])
+var a32 = a31.subarray(2, 6)
+a31.set(a32, 4)
+assertArrayPrefix([2, 4, 6, 8, 6, 8, 11, NaN], a31)
+assertArrayPrefix([6, 8, 6, 8], a32)
+
+var a4 = new Uint8ClampedArray([3,2,5,6])
+a4.set(a4)
+assertArrayPrefix([3, 2, 5, 6], a4)
+
+// Cases with overlapping backing store but different element sizes.
+var b = new ArrayBuffer(4)
+var a5 = new Int16Array(b)
+var a50 = new Int8Array(b)
+var a51 = new Int8Array(b, 0, 2)
+var a52 = new Int8Array(b, 1, 2)
+var a53 = new Int8Array(b, 2, 2)
+
+a5.set([0x5050, 0x0a0a])
+assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+assertArrayPrefix([0x50, 0x50], a51)
+assertArrayPrefix([0x50, 0x0a], a52)
+assertArrayPrefix([0x0a, 0x0a], a53)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a51.set(a5)
+assertArrayPrefix([0x50, 0x0a, 0x0a, 0x0a], a50)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a52.set(a5)
+assertArrayPrefix([0x50, 0x50, 0x0a, 0x0a], a50)
+
+a50.set([0x50, 0x50, 0x0a, 0x0a])
+a53.set(a5)
+assertArrayPrefix([0x50, 0x50, 0x50, 0x0a], a50)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a51)
+assertArrayPrefix([0x0050, 0x0051], a5)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a52)
+assertArrayPrefix([0x0051, 0x000a], a5)
+
+a50.set([0x50, 0x51, 0x0a, 0x0b])
+a5.set(a53)
+assertArrayPrefix([0x000a, 0x000b], a5)
+
+// Mixed types of same size.
+var a61 = new Float32Array([1.2, 12.3])
+var a62 = new Int32Array(2)
+a62.set(a61)
+assertArrayPrefix([1, 12], a62)
+a61.set(a62)
+assertArrayPrefix([1, 12], a61)
+
+// Invalid source
+assertThrows(function() { a.set(0); }, TypeError);
+assertArrayPrefix([1,2,3,4,5,6], a);
+a.set({}); // does not throw
+assertArrayPrefix([1,2,3,4,5,6], a);
+
+
+// Test arraybuffer.slice
+
+var a0 = new Int8Array([1, 2, 3, 4, 5, 6])
+var b0 = a0.buffer
+
+var b1 = b0.slice(0)
+assertEquals(b0.byteLength, b1.byteLength)
+assertArrayPrefix([1, 2, 3, 4, 5, 6], new Int8Array(b1))
+
+var b2 = b0.slice(3)
+assertEquals(b0.byteLength - 3, b2.byteLength)
+assertArrayPrefix([4, 5, 6], new Int8Array(b2))
+
+var b3 = b0.slice(2, 4)
+assertEquals(2, b3.byteLength)
+assertArrayPrefix([3, 4], new Int8Array(b3))
+
+function goo(a, i) {
+  return a[i];
+}
+
+function boo(a, i, v) {
+  return a[i] = v;
+}
+
+function do_tagged_index_external_array_test(constructor) {
+  var t_array = new constructor([1, 2, 3, 4, 5, 6]);
+  assertEquals(1, goo(t_array, 0));
+  assertEquals(1, goo(t_array, 0));
+  boo(t_array, 0, 13);
+  assertEquals(13, goo(t_array, 0));
+  %OptimizeFunctionOnNextCall(goo);
+  %OptimizeFunctionOnNextCall(boo);
+  boo(t_array, 0, 15);
+  assertEquals(15, goo(t_array, 0));
+  %ClearFunctionTypeFeedback(goo);
+  %ClearFunctionTypeFeedback(boo);
+}
+
+do_tagged_index_external_array_test(Int8Array);
+do_tagged_index_external_array_test(Uint8Array);
+do_tagged_index_external_array_test(Int16Array);
+do_tagged_index_external_array_test(Uint16Array);
+do_tagged_index_external_array_test(Int32Array);
+do_tagged_index_external_array_test(Uint32Array);
+do_tagged_index_external_array_test(Float32Array);
+do_tagged_index_external_array_test(Float64Array);
+
+var built_in_array = new Array(1, 2, 3, 4, 5, 6);
+assertEquals(1, goo(built_in_array, 0));
+assertEquals(1, goo(built_in_array, 0));
+%OptimizeFunctionOnNextCall(goo);
+%OptimizeFunctionOnNextCall(boo);
+boo(built_in_array, 0, 11);
+assertEquals(11, goo(built_in_array, 0));
+%ClearFunctionTypeFeedback(goo);
+%ClearFunctionTypeFeedback(boo);
+
+built_in_array = new Array(1.5, 2, 3, 4, 5, 6);
+assertEquals(1.5, goo(built_in_array, 0));
+assertEquals(1.5, goo(built_in_array, 0));
+%OptimizeFunctionOnNextCall(goo);
+%OptimizeFunctionOnNextCall(boo);
+boo(built_in_array, 0, 2.5);
+assertEquals(2.5, goo(built_in_array, 0));
+%ClearFunctionTypeFeedback(goo);
+%ClearFunctionTypeFeedback(boo);
+
+// Check all int range edge cases
+function checkRange() {
+  var e32 = Math.pow(2,32); var e31 = Math.pow(2,31);
+  var e16 = Math.pow(2,16); var e15 = Math.pow(2,15);
+  var e8 = Math.pow(2,8);   var e7 = Math.pow(2,7);
+  var a7 = new Uint32Array(2);  var a71 = new Int32Array(2);
+  var a72 = new Uint16Array(2); var a73 = new Int16Array(2);
+  var a74 = new Uint8Array(2);  var a75 = new Int8Array(2);
+  for (i = 1; i <= Math.pow(2,33); i *= 2) {
+    var j = i-1;
+    a7[0] = i; a71[0] = i; a72[0] = i; a73[0] = i; a74[0] = i; a75[0] = i;
+    a7[1] = j; a71[1] = j; a72[1] = j; a73[1] = j; a74[1] = j; a75[1] = j;
+
+    if (i < e32) { assertEquals(a7[0], i); } else { assertEquals(a7[0], 0); }
+    if (j < e32) { assertEquals(a7[1], j); } else { assertEquals(a7[1],e32-1); }
+    if (i < e31) { assertEquals(a71[0], i); } else {
+      assertEquals(a71[0], (i < e32) ? -e31 : 0 ); }
+    if (j < e31) { assertEquals(a71[1], j); } else { assertEquals(a71[1], -1); }
+
+    if (i < e16) { assertEquals(a72[0], i); } else { assertEquals(a72[0], 0); }
+    if (j < e16) { assertEquals(a72[1], j); } else { assertEquals(a72[1], e16-1); }
+    if (i < e15) { assertEquals(a73[0], i); } else {
+      assertEquals(a73[0], (i < e16) ? -e15 : 0 ); }
+    if (j < e15) { assertEquals(a73[1], j); } else { assertEquals(a73[1], -1); }
+
+    if (i < e8) { assertEquals(a74[0], i); } else { assertEquals(a74[0], 0); }
+    if (j < e8) { assertEquals(a74[1], j); } else { assertEquals(a74[1], e8-1); }
+    if (i < e7) { assertEquals(a75[0], i); } else {
+      assertEquals(a75[0], (i < e8) ? -e7 : 0); }
+    if (j < e7) { assertEquals(a75[1], j); } else { assertEquals(a75[1], -1); }
+  }
+}
+checkRange();