| // 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(); |