| Index: test/mjsunit/array-constructor-feedback.js
|
| diff --git a/test/mjsunit/array-constructor-feedback.js b/test/mjsunit/array-constructor-feedback.js
|
| index 302239b79c173c9987fb0a2127278c6a57caa6c9..e29e7694654ea0b3e4ceb2cb3e9c06ecfe0d8dab 100644
|
| --- a/test/mjsunit/array-constructor-feedback.js
|
| +++ b/test/mjsunit/array-constructor-feedback.js
|
| @@ -81,19 +81,137 @@ function assertKind(expected, obj, name_opt) {
|
| }
|
|
|
| if (support_smi_only_arrays) {
|
| - function bar0(t) {
|
| - return new t();
|
| - }
|
|
|
| - a = bar0(Array);
|
| - a[0] = 3.5;
|
| - b = bar0(Array);
|
| - assertKind(elements_kind.fast_double, b);
|
| - %OptimizeFunctionOnNextCall(bar0);
|
| - b = bar0(Array);
|
| - assertKind(elements_kind.fast_double, b);
|
| - assertTrue(2 != %GetOptimizationStatus(bar0));
|
| - // bar0 should deopt
|
| - b = bar0(Object);
|
| - assertTrue(1 != %GetOptimizationStatus(bar0));
|
| + // Test: If a call site goes megamorphic, it loses the ability to
|
| + // use allocation site feedback.
|
| + (function() {
|
| + function bar(t, len) {
|
| + return new t(len);
|
| + }
|
| +
|
| + a = bar(Array, 10);
|
| + a[0] = 3.5;
|
| + b = bar(Array, 1);
|
| + assertKind(elements_kind.fast_double, b);
|
| + c = bar(Object, 3);
|
| + b = bar(Array, 10);
|
| + assertKind(elements_kind.fast_smi_only, b);
|
| + b[0] = 3.5;
|
| + c = bar(Array, 10);
|
| + assertKind(elements_kind.fast_smi_only, c);
|
| + })();
|
| +
|
| +
|
| + // Test: ensure that crankshafted array constructor sites are deopted
|
| + // if another function is used.
|
| + (function() {
|
| + function bar0(t) {
|
| + return new t();
|
| + }
|
| + a = bar0(Array);
|
| + a[0] = 3.5;
|
| + b = bar0(Array);
|
| + assertKind(elements_kind.fast_double, b);
|
| + %OptimizeFunctionOnNextCall(bar0);
|
| + b = bar0(Array);
|
| + assertKind(elements_kind.fast_double, b);
|
| + assertTrue(2 != %GetOptimizationStatus(bar0));
|
| + // bar0 should deopt
|
| + b = bar0(Object);
|
| + assertTrue(1 != %GetOptimizationStatus(bar0));
|
| + // When it's re-optimized, we should call through the full stub
|
| + bar0(Array);
|
| + %OptimizeFunctionOnNextCall(bar0);
|
| + b = bar0(Array);
|
| + // We also lost our ability to record kind feedback, as the site
|
| + // is megamorphic now.
|
| + assertKind(elements_kind.fast_smi_only, b);
|
| + assertTrue(2 != %GetOptimizationStatus(bar0));
|
| + b[0] = 3.5;
|
| + c = bar0(Array);
|
| + assertKind(elements_kind.fast_smi_only, c);
|
| + })();
|
| +
|
| +
|
| + // Test: Ensure that bailouts from the stub don't deopt a crankshafted
|
| + // method with a call to that stub.
|
| + (function() {
|
| + function bar(len) {
|
| + return new Array(len);
|
| + }
|
| + a = bar(10);
|
| + a[0] = "a string";
|
| + a = bar(10);
|
| + assertKind(elements_kind.fast, a);
|
| + %OptimizeFunctionOnNextCall(bar);
|
| + a = bar(10);
|
| + assertKind(elements_kind.fast, a);
|
| + assertTrue(2 != %GetOptimizationStatus(bar));
|
| + // The stub bails out, but the method call should be fine.
|
| + a = bar(100000);
|
| + assertTrue(2 != %GetOptimizationStatus(bar));
|
| + assertKind(elements_kind.dictionary, a);
|
| +
|
| + // If the argument isn't a smi, it bails out as well
|
| + a = bar("oops");
|
| + assertTrue(2 != %GetOptimizationStatus(bar));
|
| + assertKind(elements_kind.fast, a);
|
| +
|
| + function barn(one, two, three) {
|
| + return new Array(one, two, three);
|
| + }
|
| +
|
| + barn(1, 2, 3);
|
| + barn(1, 2, 3);
|
| + %OptimizeFunctionOnNextCall(barn);
|
| + barn(1, 2, 3);
|
| + assertTrue(2 != %GetOptimizationStatus(barn));
|
| + a = barn(1, "oops", 3);
|
| + // The stub should bail out but the method should remain optimized.
|
| + assertKind(elements_kind.fast, a);
|
| + assertTrue(2 != %GetOptimizationStatus(barn));
|
| + })();
|
| +
|
| +
|
| + // Test: When a method with array constructor is crankshafted, the type
|
| + // feedback for elements kind is baked in. Verify that transitions don't
|
| + // change it anymore
|
| + (function() {
|
| + function bar() {
|
| + return new Array();
|
| + }
|
| + a = bar();
|
| + bar();
|
| + %OptimizeFunctionOnNextCall(bar);
|
| + b = bar();
|
| + // This only makes sense to test if we allow crankshafting
|
| + if (4 != %GetOptimizationStatus(bar)) {
|
| + assertTrue(2 != %GetOptimizationStatus(bar));
|
| + %DebugPrint(3);
|
| + b[0] = 3.5;
|
| + c = bar();
|
| + assertKind(elements_kind.fast_smi_only, c);
|
| + assertTrue(2 != %GetOptimizationStatus(bar));
|
| + }
|
| + })();
|
| +
|
| +
|
| + // Test: create arrays in two contexts, verifying that the correct
|
| + // map for Array in that context will be used.
|
| + (function() {
|
| + function bar() { return new Array(); }
|
| + bar();
|
| + bar();
|
| + %OptimizeFunctionOnNextCall(bar);
|
| + a = bar();
|
| + assertTrue(a instanceof Array);
|
| +
|
| + var contextB = Realm.create();
|
| + Realm.eval(contextB, "function bar2() { return new Array(); };");
|
| + Realm.eval(contextB, "bar2(); bar2();");
|
| + Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);");
|
| + Realm.eval(contextB, "bar2();");
|
| + assertFalse(Realm.eval(contextB, "bar2();") instanceof Array);
|
| + assertTrue(Realm.eval(contextB, "bar2() instanceof Array"));
|
| + })();
|
| }
|
|
|