| 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"));
 | 
| +  })();
 | 
|  }
 | 
| 
 |