| 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 | 
|   11 //       with the distribution. |   11 //       with the distribution. | 
|   12 //     * Neither the name of Google Inc. nor the names of its |   12 //     * Neither the name of Google Inc. nor the names of its | 
|   13 //       contributors may be used to endorse or promote products derived |   13 //       contributors may be used to endorse or promote products derived | 
|   14 //       from this software without specific prior written permission. |   14 //       from this software without specific prior written permission. | 
|   15 // |   15 // | 
|   16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |   16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|   17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |   17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|   18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |   18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|   19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |   19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|   20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |   20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|   21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |   21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|   22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |   22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |   23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |   24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |   25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |   26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|   27  |   27  | 
|   28 // Flags: --allow-natives-syntax --smi-only-arrays --expose-gc |   28 // Flags: --allow-natives-syntax --smi-only-arrays --noparallel-recompilation | 
|   29 // Flags: --noparallel-recompilation |  | 
|   30  |   29  | 
|   31 // Ensure that ElementsKind transitions in various situations are hoisted (or |   30 // Ensure that ElementsKind transitions in various situations are hoisted (or | 
|   32 // not hoisted) correctly, don't change the semantics programs and don't trigger |   31 // not hoisted) correctly, don't change the semantics programs and don't trigger | 
|   33 // deopt through hoisting in important situations. |   32 // deopt through hoisting in important situations. | 
|   34  |   33  | 
|   35 support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6)); |   34 support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6)); | 
|   36  |   35  | 
|   37 if (support_smi_only_arrays) { |   36 if (support_smi_only_arrays) { | 
|   38   print("Tests include smi-only arrays."); |   37   print("Tests include smi-only arrays."); | 
|   39 } else { |   38 } else { | 
|   40   print("Tests do NOT include smi-only arrays."); |   39   print("Tests do NOT include smi-only arrays."); | 
|   41 } |   40 } | 
|   42  |   41  | 
|   43 // Force existing ICs from previous stress runs to be flushed, otherwise the |  | 
|   44 // assumptions in this test about when deoptimizations get triggered are not |  | 
|   45 // valid. |  | 
|   46 gc(); |  | 
|   47  |  | 
|   48 if (support_smi_only_arrays) { |   42 if (support_smi_only_arrays) { | 
|   49   // Make sure that a simple elements array transitions inside a loop before |   43   // Make sure that a simple elements array transitions inside a loop before | 
|   50   // stores to an array gets hoisted in a way that doesn't generate a deopt in |   44   // stores to an array gets hoisted in a way that doesn't generate a deopt in | 
|   51   // simple cases.} |   45   // simple cases.} | 
|   52   function testDoubleConversion4(a) { |   46   function testDoubleConversion4(a) { | 
|   53     var object = new Object(); |   47     var object = new Object(); | 
|   54     a[0] = 0; |   48     a[0] = 0; | 
|   55     var count = 3; |   49     var count = 3; | 
|   56     do { |   50     do { | 
|   57       a[0] = object; |   51       a[0] = object; | 
|   58     } while (--count > 0); |   52     } while (--count > 0); | 
|   59   } |   53   } | 
|   60  |   54  | 
|   61   testDoubleConversion4(new Array(5)); |   55   testDoubleConversion4(new Array(5)); | 
|   62   testDoubleConversion4(new Array(5));  // Call twice to make sure that second |   56   testDoubleConversion4(new Array(5));  // Call twice to make sure that second | 
|   63                                         // store is a transition and not |   57                                         // store is a transition and not | 
|   64                                         // optimistically MONOMORPHIC |   58                                         // optimistically MONOMORPHIC | 
|   65   %OptimizeFunctionOnNextCall(testDoubleConversion4); |   59   %OptimizeFunctionOnNextCall(testDoubleConversion4); | 
|   66   testDoubleConversion4(new Array(5)); |   60   testDoubleConversion4(new Array(5)); | 
|   67   testDoubleConversion4(new Array(5)); |   61   testDoubleConversion4(new Array(5)); | 
|   68   assertTrue(2 != %GetOptimizationStatus(testDoubleConversion4)); |   62   assertTrue(2 != %GetOptimizationStatus(testDoubleConversion4)); | 
 |   63   %ClearFunctionTypeFeedback(testDoubleConversion4); | 
|   69  |   64  | 
|   70   // Make sure that non-element related map checks that are not preceded by |   65   // Make sure that non-element related map checks that are not preceded by | 
|   71   // transitions in a loop still get hoisted in a way that doesn't generate a |   66   // transitions in a loop still get hoisted in a way that doesn't generate a | 
|   72   // deopt in simple cases. |   67   // deopt in simple cases. | 
|   73   function testExactMapHoisting(a) { |   68   function testExactMapHoisting(a) { | 
|   74     var object = new Object(); |   69     var object = new Object(); | 
|   75     a.foo = 0; |   70     a.foo = 0; | 
|   76     a[0] = 0; |   71     a[0] = 0; | 
|   77     a[1] = 1; |   72     a[1] = 1; | 
|   78     var count = 3; |   73     var count = 3; | 
|   79     do { |   74     do { | 
|   80       a.foo = object;  // This map check should be hoistable |   75       a.foo = object;  // This map check should be hoistable | 
|   81       a[1] = object; |   76       a[1] = object; | 
|   82       result = a.foo == object && a[1] == object; |   77       result = a.foo == object && a[1] == object; | 
|   83     } while (--count > 0); |   78     } while (--count > 0); | 
|   84   } |   79   } | 
|   85  |   80  | 
|   86   testExactMapHoisting(new Array(5)); |   81   testExactMapHoisting(new Array(5)); | 
|   87   testExactMapHoisting(new Array(5));  // Call twice to make sure that second |   82   testExactMapHoisting(new Array(5));  // Call twice to make sure that second | 
|   88                                        // store is a transition and not |   83                                        // store is a transition and not | 
|   89                                        // optimistically MONOMORPHIC |   84                                        // optimistically MONOMORPHIC | 
|   90   %OptimizeFunctionOnNextCall(testExactMapHoisting); |   85   %OptimizeFunctionOnNextCall(testExactMapHoisting); | 
|   91   testExactMapHoisting(new Array(5)); |   86   testExactMapHoisting(new Array(5)); | 
|   92   testExactMapHoisting(new Array(5)); |   87   testExactMapHoisting(new Array(5)); | 
|   93   assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting)); |   88   assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting)); | 
 |   89   %ClearFunctionTypeFeedback(testExactMapHoisting); | 
|   94  |   90  | 
|   95   // Make sure that non-element related map checks do NOT get hoisted if they |   91   // Make sure that non-element related map checks do NOT get hoisted if they | 
|   96   // depend on an elements transition before them and it's not possible to hoist |   92   // depend on an elements transition before them and it's not possible to hoist | 
|   97   // that transition. |   93   // that transition. | 
|   98   function testExactMapHoisting2(a) { |   94   function testExactMapHoisting2(a) { | 
|   99     var object = new Object(); |   95     var object = new Object(); | 
|  100     a.foo = 0; |   96     a.foo = 0; | 
|  101     a[0] = 0; |   97     a[0] = 0; | 
|  102     a[1] = 1; |   98     a[1] = 1; | 
|  103     var count = 3; |   99     var count = 3; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  115  |  111  | 
|  116   testExactMapHoisting2(new Array(5)); |  112   testExactMapHoisting2(new Array(5)); | 
|  117   testExactMapHoisting2(new Array(5));  // Call twice to make sure that second |  113   testExactMapHoisting2(new Array(5));  // Call twice to make sure that second | 
|  118                                         // store is a transition and not |  114                                         // store is a transition and not | 
|  119                                         // optimistically MONOMORPHIC |  115                                         // optimistically MONOMORPHIC | 
|  120   %OptimizeFunctionOnNextCall(testExactMapHoisting2); |  116   %OptimizeFunctionOnNextCall(testExactMapHoisting2); | 
|  121   testExactMapHoisting2(new Array(5)); |  117   testExactMapHoisting2(new Array(5)); | 
|  122   testExactMapHoisting2(new Array(5)); |  118   testExactMapHoisting2(new Array(5)); | 
|  123   // Temporarily disabled - see bug 2176. |  119   // Temporarily disabled - see bug 2176. | 
|  124   // assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting2)); |  120   // assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting2)); | 
 |  121   %ClearFunctionTypeFeedback(testExactMapHoisting2); | 
|  125  |  122  | 
|  126   // Make sure that non-element related map checks do get hoisted if they use |  123   // Make sure that non-element related map checks do get hoisted if they use | 
|  127   // the transitioned map for the check and all transitions that they depend |  124   // the transitioned map for the check and all transitions that they depend | 
|  128   // upon can hoisted, too. |  125   // upon can hoisted, too. | 
|  129   function testExactMapHoisting3(a) { |  126   function testExactMapHoisting3(a) { | 
|  130     var object = new Object(); |  127     var object = new Object(); | 
|  131     a.foo = 0; |  128     a.foo = 0; | 
|  132     a[0] = 0; |  129     a[0] = 0; | 
|  133     a[1] = 1; |  130     a[1] = 1; | 
|  134     var count = 3; |  131     var count = 3; | 
|  135     do { |  132     do { | 
|  136       a[1] = 2.5; |  133       a[1] = 2.5; | 
|  137       a.foo = object;  // This map check should be hoistable because all element
     s |  134       a.foo = object;  // This map check should be hoistable because all element
     s | 
|  138                        // transitions in the loop can also be hoisted. |  135                        // transitions in the loop can also be hoisted. | 
|  139     } while (--count > 0); |  136     } while (--count > 0); | 
|  140   } |  137   } | 
|  141  |  138  | 
|  142   var add_transition = new Array(5); |  139   var add_transition = new Array(5); | 
|  143   add_transition.foo = 0; |  140   add_transition.foo = 0; | 
|  144   add_transition[0] = new Object();  // For FAST_ELEMENT transition to be create
     d |  141   add_transition[0] = new Object();  // For FAST_ELEMENT transition to be create
     d | 
|  145   testExactMapHoisting3(new Array(5)); |  142   testExactMapHoisting3(new Array(5)); | 
|  146   testExactMapHoisting3(new Array(5));  // Call twice to make sure that second |  143   testExactMapHoisting3(new Array(5));  // Call twice to make sure that second | 
|  147                                         // store is a transition and not |  144                                         // store is a transition and not | 
|  148                                         // optimistically MONOMORPHIC |  145                                         // optimistically MONOMORPHIC | 
|  149   %OptimizeFunctionOnNextCall(testExactMapHoisting3); |  146   %OptimizeFunctionOnNextCall(testExactMapHoisting3); | 
|  150   testExactMapHoisting3(new Array(5)); |  147   testExactMapHoisting3(new Array(5)); | 
|  151   testExactMapHoisting3(new Array(5)); |  148   testExactMapHoisting3(new Array(5)); | 
|  152   assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting3)); |  149   assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting3)); | 
 |  150   %ClearFunctionTypeFeedback(testExactMapHoisting3); | 
|  153  |  151  | 
|  154   function testDominatingTransitionHoisting1(a) { |  152   function testDominatingTransitionHoisting1(a) { | 
|  155     var object = new Object(); |  153     var object = new Object(); | 
|  156     a[0] = 0; |  154     a[0] = 0; | 
|  157     var count = 3; |  155     var count = 3; | 
|  158     do { |  156     do { | 
|  159       if (a.baz != true) { |  157       if (a.baz != true) { | 
|  160         a[1] = 2.5; |  158         a[1] = 2.5; | 
|  161       } |  159       } | 
|  162       a[0] = object; |  160       a[0] = object; | 
|  163     } while (--count > 3); |  161     } while (--count > 3); | 
|  164   } |  162   } | 
|  165  |  163  | 
|  166   /* |  164   /* | 
|  167   testDominatingTransitionHoisting1(new Array(5)); |  165   testDominatingTransitionHoisting1(new Array(5)); | 
|  168   testDominatingTransitionHoisting1(new Array(5));  // Call twice to make sure |  166   testDominatingTransitionHoisting1(new Array(5));  // Call twice to make sure | 
|  169                                                     // that second store is a |  167                                                     // that second store is a | 
|  170                                                     // transition and not |  168                                                     // transition and not | 
|  171                                                     // optimistically MONOMORPHI
     C |  169                                                     // optimistically MONOMORPHI
     C | 
|  172   %OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1); |  170   %OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1); | 
|  173   testDominatingTransitionHoisting1(new Array(5)); |  171   testDominatingTransitionHoisting1(new Array(5)); | 
|  174   testDominatingTransitionHoisting1(new Array(5)); |  172   testDominatingTransitionHoisting1(new Array(5)); | 
|  175   // TODO(verwaest) With current changes the elements transition gets hoisted |  173   // TODO(verwaest) With current changes the elements transition gets hoisted | 
|  176   // above the access, causing a deopt. We should update the type of access |  174   // above the access, causing a deopt. We should update the type of access | 
|  177   // rather than forbid hoisting the transition. |  175   // rather than forbid hoisting the transition. | 
|  178   assertTrue(2 != %GetOptimizationStatus(testDominatingTransitionHoisting1)); |  176   assertTrue(2 != %GetOptimizationStatus(testDominatingTransitionHoisting1)); | 
 |  177   %ClearFunctionTypeFeedback(testDominatingTransitionHoisting1); | 
|  179   */ |  178   */ | 
|  180  |  179  | 
|  181   function testHoistingWithSideEffect(a) { |  180   function testHoistingWithSideEffect(a) { | 
|  182     var object = new Object(); |  181     var object = new Object(); | 
|  183     a[0] = 0; |  182     a[0] = 0; | 
|  184     var count = 3; |  183     var count = 3; | 
|  185     do { |  184     do { | 
|  186       assertTrue(true); |  185       assertTrue(true); | 
|  187       a[0] = object; |  186       a[0] = object; | 
|  188     } while (--count > 3); |  187     } while (--count > 3); | 
|  189   } |  188   } | 
|  190  |  189  | 
|  191   testHoistingWithSideEffect(new Array(5)); |  190   testHoistingWithSideEffect(new Array(5)); | 
|  192   testHoistingWithSideEffect(new Array(5));  // Call twice to make sure that |  191   testHoistingWithSideEffect(new Array(5));  // Call twice to make sure that | 
|  193                                              // second store is a transition and |  192                                              // second store is a transition and | 
|  194                                              // not optimistically MONOMORPHIC |  193                                              // not optimistically MONOMORPHIC | 
|  195   %OptimizeFunctionOnNextCall(testHoistingWithSideEffect); |  194   %OptimizeFunctionOnNextCall(testHoistingWithSideEffect); | 
|  196   testHoistingWithSideEffect(new Array(5)); |  195   testHoistingWithSideEffect(new Array(5)); | 
|  197   testHoistingWithSideEffect(new Array(5)); |  196   testHoistingWithSideEffect(new Array(5)); | 
|  198   assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect)); |  197   assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect)); | 
 |  198   %ClearFunctionTypeFeedback(testHoistingWithSideEffect); | 
|  199  |  199  | 
|  200   function testStraightLineDupeElinination(a,b,c,d,e,f) { |  200   function testStraightLineDupeElinination(a,b,c,d,e,f) { | 
|  201     var count = 3; |  201     var count = 3; | 
|  202     do { |  202     do { | 
|  203       assertTrue(true); |  203       assertTrue(true); | 
|  204       a[0] = b; |  204       a[0] = b; | 
|  205       a[1] = c; |  205       a[1] = c; | 
|  206       a[2] = d; |  206       a[2] = d; | 
|  207       assertTrue(true); |  207       assertTrue(true); | 
|  208       a[3] = e;  // TransitionElementsKind should be eliminated despite call. |  208       a[3] = e;  // TransitionElementsKind should be eliminated despite call. | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  227   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); |  227   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); | 
|  228   testStraightLineDupeElinination(new Array(5),.5,0,0,0,0); |  228   testStraightLineDupeElinination(new Array(5),.5,0,0,0,0); | 
|  229   testStraightLineDupeElinination(new Array(5),0,.5,0,0,0); |  229   testStraightLineDupeElinination(new Array(5),0,.5,0,0,0); | 
|  230   testStraightLineDupeElinination(new Array(5),0,0,.5,0,0); |  230   testStraightLineDupeElinination(new Array(5),0,0,.5,0,0); | 
|  231   testStraightLineDupeElinination(new Array(5),0,0,0,.5,0); |  231   testStraightLineDupeElinination(new Array(5),0,0,0,.5,0); | 
|  232   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); |  232   testStraightLineDupeElinination(new Array(5),0,0,0,0,.5); | 
|  233   %OptimizeFunctionOnNextCall(testStraightLineDupeElinination); |  233   %OptimizeFunctionOnNextCall(testStraightLineDupeElinination); | 
|  234   testStraightLineDupeElinination(new Array(5),0,0,0,0,0); |  234   testStraightLineDupeElinination(new Array(5),0,0,0,0,0); | 
|  235   testStraightLineDupeElinination(new Array(5),0,0,0,0,0); |  235   testStraightLineDupeElinination(new Array(5),0,0,0,0,0); | 
|  236   assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination)); |  236   assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination)); | 
 |  237   %ClearFunctionTypeFeedback(testStraightLineDupeElinination); | 
|  237 } |  238 } | 
| OLD | NEW |