// Get early out-of-bound data. function opaqueGetByValOnInt32ArrayEarlyOutOfBounds(array, index) { return array[index]; } noInline(opaqueGetByValOnInt32ArrayEarlyOutOfBounds); function testInt32ArrayEarlyOutOfBounds() { // Warm up with an immediate out of bounds. var int32Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (var i = 0; i <= 10; ++i) { var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, i); if ((i < 10 && value !== i) || (i >= 10 && value !== undefined)) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, i) warmup with i = " + i + " value = " + value; } // We then do plenty of in-bounds accesses. for (var i = 0; i < 1e4; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j); if (j < 10 && value !== j) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j) in-bounds with j = " + j + " value = " + value; } } // Followed by plenty of out-of-bounds accesses. for (var i = 0; i < 1e4; ++i) { for (var j = 0; j <= 10; ++j) { var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j); if ((j < 10 && value !== j) || (j >= 10 && value !== undefined)) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(int32Array, j) out-of-bounds with j = " + j + " value = " + value; } } } testInt32ArrayEarlyOutOfBounds(); // One more access, with a completely different array type. function testIndexingTypeChangesOnInt32Array() { var doubleArray = [-0, 5.5, -42.1]; var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 0); if (value || 1 / value !== -Infinity) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 0)"; var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 1); if (value !== 5.5) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 1)"; var value = opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 2); if (value !== -42.1) throw "Failed opaqueGetByValOnInt32ArrayEarlyOutOfBounds(doubleArray, 2)"; } testIndexingTypeChangesOnInt32Array(); // Get out-of-bound data after a thousand run. function opaqueGetByValOnStringArrayHotOutOfBounds(array, index) { return array[index]; } noInline(opaqueGetByValOnStringArrayHotOutOfBounds); function testStringArrayHotOutOfBounds() { // Warm up with in bounds access. var stringArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; for (var i = 0; i < 1e2; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j); if (value !== "" + j) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value; } } // Do a single out of bounds after warmup. var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, 10); if (value !== undefined) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, 10) with i = " + i + " value = " + value; // We then do plenty of in-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j); if (value !== "" + j) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value; } } // Followed by plenty of out-of-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j <= 10; ++j) { var value = opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j); if ((j < 10 && value !== "" + j) || (j >= 10 && value !== undefined)) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(stringArray, j) out-of-bounds with j = " + j + " value = " + value; } } } testStringArrayHotOutOfBounds(); function testIndexingTypeChangesOnStringArray() { var doubleArray = [-0, 5.5, -42.1]; var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 0); if (value || 1 / value !== -Infinity) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 0)"; var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 1); if (value !== 5.5) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 1)"; var value = opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 2); if (value !== -42.1) throw "Failed opaqueGetByValOnStringArrayHotOutOfBounds(doubleArray, 2)"; } testIndexingTypeChangesOnStringArray(); // Get out-of-bound data after a thousand run, but from a different array type. function opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(array, index) { return array[index]; } noInline(opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds); function testStringAndInt32ArrayHotOutOfBounds() { // Warm up with in bounds access. var stringArray = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; for (var i = 0; i < 1e2; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j); if (value !== "" + j) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value; } } // Do a single out of bounds after warmup. var int32Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, 10); if (value !== undefined) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, 10) with i = " + i + " value = " + value; // We then do plenty of in-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j); if (value !== "" + j) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) in-bounds with j = " + j + " value = " + value; var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j); if (value !== j) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j) in-bounds with j = " + j + " value = " + value; } } // Followed by plenty of out-of-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j <= 10; ++j) { var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j); if ((j < 10 && value !== j) || (j >= 10 && value !== undefined)) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(int32Array, j) out-of-bounds with j = " + j + " value = " + value; var value = opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j); if ((j < 10 && value !== "" + j) || (j >= 10 && value !== undefined)) throw "Failed opaqueGetByValOnStringAndInt32ArrayHotOutOfBounds(stringArray, j) out-of-bounds with j = " + j + " value = " + value; } } } testStringAndInt32ArrayHotOutOfBounds(); // Get out-of-bound data from a hole after a thousand run. function opaqueGetByValOnDoubleArrayHotOutOfBounds(array, index) { return array[index]; } noInline(opaqueGetByValOnDoubleArrayHotOutOfBounds); function testStringArrayHotOutOfBounds() { // Warm up with in bounds access. var doubleArray = new Array(10); for (var i = 0; i < 10; ++i) { if (i !== 5) doubleArray[i] = i + 0.5; } for (var i = 0; i < 1e2; ++i) { for (var j = 0; j < 10; ++j) { if (j !== 5) { var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j); if (value !== j + 0.5) throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) in-bounds with j = " + j + " value = " + value; } } } // Do a single out of bounds after warmup. var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, 5); if (value !== undefined) throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, 5) with i = " + i + " value = " + value; // We then do plenty of in-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j < 10; ++j) { if (j !== 5) { var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j); if (value !== j + 0.5) throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) in-bounds with j = " + j + " value = " + value; } } } // Followed by plenty of out-of-bounds accesses. for (var i = 0; i < 1e3; ++i) { for (var j = 0; j < 10; ++j) { var value = opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j); if ((j !== 5 && value !== j + 0.5) || (j === 10 && value !== undefined)) throw "Failed opaqueGetByValOnDoubleArrayHotOutOfBounds(doubleArray, j) out-of-bounds with j = " + j + " value = " + value; } } } testStringArrayHotOutOfBounds();