| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 74 | 74 | 
| 75 function assertKind(expected, obj, name_opt) { | 75 function assertKind(expected, obj, name_opt) { | 
| 76   if (!support_smi_only_arrays && | 76   if (!support_smi_only_arrays && | 
| 77       expected == elements_kind.fast_smi_only) { | 77       expected == elements_kind.fast_smi_only) { | 
| 78     expected = elements_kind.fast; | 78     expected = elements_kind.fast; | 
| 79   } | 79   } | 
| 80   assertEquals(expected, getKind(obj), name_opt); | 80   assertEquals(expected, getKind(obj), name_opt); | 
| 81 } | 81 } | 
| 82 | 82 | 
| 83 if (support_smi_only_arrays) { | 83 if (support_smi_only_arrays) { | 
| 84   function bar0(t) { |  | 
| 85     return new t(); |  | 
| 86   } |  | 
| 87 | 84 | 
| 88   a = bar0(Array); | 85   // Test: If a call site goes megamorphic, it loses the ability to | 
| 89   a[0] = 3.5; | 86   // use allocation site feedback. | 
| 90   b = bar0(Array); | 87   (function() { | 
| 91   assertKind(elements_kind.fast_double, b); | 88     function bar(t, len) { | 
| 92   %OptimizeFunctionOnNextCall(bar0); | 89       return new t(len); | 
| 93   b = bar0(Array); | 90     } | 
| 94   assertKind(elements_kind.fast_double, b); | 91 | 
| 95   assertTrue(2 != %GetOptimizationStatus(bar0)); | 92     a = bar(Array, 10); | 
| 96   // bar0 should deopt | 93     a[0] = 3.5; | 
| 97   b = bar0(Object); | 94     b = bar(Array, 1); | 
| 98   assertTrue(1 != %GetOptimizationStatus(bar0)); | 95     assertKind(elements_kind.fast_double, b); | 
|  | 96     c = bar(Object, 3); | 
|  | 97     b = bar(Array, 10); | 
|  | 98     assertKind(elements_kind.fast_smi_only, b); | 
|  | 99     b[0] = 3.5; | 
|  | 100     c = bar(Array, 10); | 
|  | 101     assertKind(elements_kind.fast_smi_only, c); | 
|  | 102   })(); | 
|  | 103 | 
|  | 104 | 
|  | 105   // Test: ensure that crankshafted array constructor sites are deopted | 
|  | 106   // if another function is used. | 
|  | 107   (function() { | 
|  | 108     function bar0(t) { | 
|  | 109       return new t(); | 
|  | 110     } | 
|  | 111     a = bar0(Array); | 
|  | 112     a[0] = 3.5; | 
|  | 113     b = bar0(Array); | 
|  | 114     assertKind(elements_kind.fast_double, b); | 
|  | 115     %OptimizeFunctionOnNextCall(bar0); | 
|  | 116     b = bar0(Array); | 
|  | 117     assertKind(elements_kind.fast_double, b); | 
|  | 118     assertTrue(2 != %GetOptimizationStatus(bar0)); | 
|  | 119     // bar0 should deopt | 
|  | 120     b = bar0(Object); | 
|  | 121     assertTrue(1 != %GetOptimizationStatus(bar0)); | 
|  | 122     // When it's re-optimized, we should call through the full stub | 
|  | 123     bar0(Array); | 
|  | 124     %OptimizeFunctionOnNextCall(bar0); | 
|  | 125     b = bar0(Array); | 
|  | 126     // We also lost our ability to record kind feedback, as the site | 
|  | 127     // is megamorphic now. | 
|  | 128     assertKind(elements_kind.fast_smi_only, b); | 
|  | 129     assertTrue(2 != %GetOptimizationStatus(bar0)); | 
|  | 130     b[0] = 3.5; | 
|  | 131     c = bar0(Array); | 
|  | 132     assertKind(elements_kind.fast_smi_only, c); | 
|  | 133   })(); | 
|  | 134 | 
|  | 135 | 
|  | 136   // Test: Ensure that bailouts from the stub don't deopt a crankshafted | 
|  | 137   // method with a call to that stub. | 
|  | 138   (function() { | 
|  | 139     function bar(len) { | 
|  | 140       return new Array(len); | 
|  | 141     } | 
|  | 142     a = bar(10); | 
|  | 143     a[0] = "a string"; | 
|  | 144     a = bar(10); | 
|  | 145     assertKind(elements_kind.fast, a); | 
|  | 146     %OptimizeFunctionOnNextCall(bar); | 
|  | 147     a = bar(10); | 
|  | 148     assertKind(elements_kind.fast, a); | 
|  | 149     assertTrue(2 != %GetOptimizationStatus(bar)); | 
|  | 150     // The stub bails out, but the method call should be fine. | 
|  | 151     a = bar(100000); | 
|  | 152     assertTrue(2 != %GetOptimizationStatus(bar)); | 
|  | 153     assertKind(elements_kind.dictionary, a); | 
|  | 154 | 
|  | 155     // If the argument isn't a smi, it bails out as well | 
|  | 156     a = bar("oops"); | 
|  | 157     assertTrue(2 != %GetOptimizationStatus(bar)); | 
|  | 158     assertKind(elements_kind.fast, a); | 
|  | 159 | 
|  | 160     function barn(one, two, three) { | 
|  | 161       return new Array(one, two, three); | 
|  | 162     } | 
|  | 163 | 
|  | 164     barn(1, 2, 3); | 
|  | 165     barn(1, 2, 3); | 
|  | 166     %OptimizeFunctionOnNextCall(barn); | 
|  | 167     barn(1, 2, 3); | 
|  | 168     assertTrue(2 != %GetOptimizationStatus(barn)); | 
|  | 169     a = barn(1, "oops", 3); | 
|  | 170     // The stub should bail out but the method should remain optimized. | 
|  | 171     assertKind(elements_kind.fast, a); | 
|  | 172     assertTrue(2 != %GetOptimizationStatus(barn)); | 
|  | 173   })(); | 
|  | 174 | 
|  | 175 | 
|  | 176   // Test: When a method with array constructor is crankshafted, the type | 
|  | 177   // feedback for elements kind is baked in. Verify that transitions don't | 
|  | 178   // change it anymore | 
|  | 179   (function() { | 
|  | 180     function bar() { | 
|  | 181       return new Array(); | 
|  | 182     } | 
|  | 183     a = bar(); | 
|  | 184     bar(); | 
|  | 185     %OptimizeFunctionOnNextCall(bar); | 
|  | 186     b = bar(); | 
|  | 187     // This only makes sense to test if we allow crankshafting | 
|  | 188     if (4 != %GetOptimizationStatus(bar)) { | 
|  | 189       assertTrue(2 != %GetOptimizationStatus(bar)); | 
|  | 190       %DebugPrint(3); | 
|  | 191       b[0] = 3.5; | 
|  | 192       c = bar(); | 
|  | 193       assertKind(elements_kind.fast_smi_only, c); | 
|  | 194       assertTrue(2 != %GetOptimizationStatus(bar)); | 
|  | 195     } | 
|  | 196   })(); | 
|  | 197 | 
|  | 198 | 
|  | 199   // Test: create arrays in two contexts, verifying that the correct | 
|  | 200   // map for Array in that context will be used. | 
|  | 201   (function() { | 
|  | 202     function bar() { return new Array(); } | 
|  | 203     bar(); | 
|  | 204     bar(); | 
|  | 205     %OptimizeFunctionOnNextCall(bar); | 
|  | 206     a = bar(); | 
|  | 207     assertTrue(a instanceof Array); | 
|  | 208 | 
|  | 209     var contextB = Realm.create(); | 
|  | 210     Realm.eval(contextB, "function bar2() { return new Array(); };"); | 
|  | 211     Realm.eval(contextB, "bar2(); bar2();"); | 
|  | 212     Realm.eval(contextB, "%OptimizeFunctionOnNextCall(bar2);"); | 
|  | 213     Realm.eval(contextB, "bar2();"); | 
|  | 214     assertFalse(Realm.eval(contextB, "bar2();") instanceof Array); | 
|  | 215     assertTrue(Realm.eval(contextB, "bar2() instanceof Array")); | 
|  | 216   })(); | 
| 99 } | 217 } | 
| OLD | NEW | 
|---|