diff options
Diffstat (limited to 'js/src/jit-test/tests/cacheir/bug1494537.js')
-rw-r--r-- | js/src/jit-test/tests/cacheir/bug1494537.js | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/cacheir/bug1494537.js b/js/src/jit-test/tests/cacheir/bug1494537.js new file mode 100644 index 0000000000..7bf139819c --- /dev/null +++ b/js/src/jit-test/tests/cacheir/bug1494537.js @@ -0,0 +1,125 @@ +setJitCompilerOption("ion.forceinlineCaches", 1); + +let offsets = [213, 559, 255, 515, 30, 507, 252, 329, 487, 7]; + +function update_index(i, j) { + var offset = offsets[j % offsets.length]; + return i + offset; +} + +function compute_index(initial, count) { + for (var i = 0; i < count; i++) { + initial = update_index(initial, i); + } + return initial; +} + +// This is written so that the IC added in the bug activates. +function mutate_array(array, count, epsilon = 0) { + var index = 0; + for (var i = 0; i < count; i++) { + index = update_index(index, i); + array[index] = i + epsilon; + } + return array[offsets[0]+offsets[1]] === (1 + epsilon) && + array[10] === undefined; +} + +// Monomorphizing mutate_array to ensure we get the IC chains we want +function create_variant(variant) { + var source = mutate_array.toString().replace("mutate_array", "mutate_array_"+variant); + return source; +} + +function test_basic() { + eval(create_variant("basic")); + var x = []; + + var count = 100; + assertEq(mutate_array_basic(x, count), true); + var end = compute_index(0, count); + assertEq(x[end], count - 1); + assertEq(x[end - 1], undefined); +} + +// Ensure the IC respects frozen. +function test_frozen() { + eval(create_variant("frozen")); + var x = []; + Object.freeze(x); + + var count = 100; + assertEq(mutate_array_frozen(x, count), false); + assertEq(x.length, 0); + + var end = compute_index(0, count); + + var y = []; + assertEq(mutate_array_frozen(y, count), true); + assertEq(y[end], count - 1); + Object.freeze(y); + + // After a mutated array is frozen, can't subsequently modify elements + assertEq(mutate_array_frozen(x, count, 10), false); + assertEq(y[end], count - 1); +} + +// Let's make sure updates to the array happen as expected. +function test_update() { + eval(create_variant("update")); + + var x = []; + var count = 100; + assertEq(mutate_array_update(x, count), true); + var end = compute_index(0, count); + assertEq(x[end], count - 1); + assertEq(x[end - 1], undefined); + + var epsilon = 2; + mutate_array_update(x, 200, epsilon); + assertEq(x[end], count -1 + epsilon) +} + +// Elements may be non-writable, let us not write them. +function test_nonwritable() { + eval(create_variant("nonwritable")); + var x = []; + var count = 100; + var index = compute_index(0, 10); + Object.defineProperty(x, index, {value: -10, writable: false}); + mutate_array_nonwritable(x, count); + assertEq(x[index], -10); +} + +// Random indices can get setters, let's make sure we honour those. +function test_setter() { + eval(create_variant("setter")); + var x = []; + var count = 100; + var index = compute_index(0, 80); + var sigil = 0; + Object.defineProperty(x, index, {set(newVal) {sigil++; }}); + mutate_array_setter(x, count); + assertEq(sigil, 1); + assertEq(x[index], undefined); +} + +// Ensure indexes on the prototype don't break things; +// +function test_proto_indices() { + eval(create_variant("proto_indices")); + var x = []; + var count = 100; + var index = compute_index(0, 80); + x.__proto__[index] = "hello"; + mutate_array_proto_indices(x, count); + assertEq(x.__proto__[index], "hello"); + assertEq(x[index], 79); +} + +test_basic(); +test_frozen(); +test_update(); +test_nonwritable(); +test_setter(); +test_proto_indices(); |