| 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 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); | 30 support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); |
| 31 | 31 |
| 32 if (support_smi_only_arrays) { | 32 if (support_smi_only_arrays) { |
| 33 print("Tests include smi-only arrays."); | 33 print("Tests include smi-only arrays."); |
| 34 } else { | 34 } else { |
| 35 print("Tests do NOT include smi-only arrays."); | 35 print("Tests do NOT include smi-only arrays."); |
| 36 } | 36 } |
| 37 | 37 |
| 38 if (support_smi_only_arrays) { | 38 if (support_smi_only_arrays) { |
| 39 function test(test_double, test_object, set, length) { | 39 function test(test_double, test_object, length, return_here) { |
| 40 // We apply the same operations to two identical arrays. The first array | 40 // We apply the same operations to two identical arrays. The first array |
| 41 // triggers an IC miss, upon which the conversion stub is generated, but the | 41 // triggers an IC miss, upon which the conversion stub is generated, but the |
| 42 // actual conversion is done in runtime. The second array, arriving at | 42 // actual conversion is done in runtime. The second array, arriving at |
| 43 // the previously patched IC, is then converted using the conversion stub. | 43 // the previously patched IC, is then converted using the conversion stub. |
| 44 var array_1 = new Array(length); | 44 var array_1 = new Array(length); |
| 45 var array_2 = new Array(length); | |
| 46 | 45 |
| 47 assertTrue(%HasFastSmiElements(array_1)); | 46 if (return_here == 0) { |
| 48 assertTrue(%HasFastSmiElements(array_2)); | 47 return array_1; |
| 49 for (var i = 0; i < length; i++) { | |
| 50 if (i == length - 5 && test_double) { | |
| 51 // Trigger conversion to fast double elements at length-5. | |
| 52 set(array_1, i, 0.5); | |
| 53 set(array_2, i, 0.5); | |
| 54 assertTrue(%HasFastDoubleElements(array_1)); | |
| 55 assertTrue(%HasFastDoubleElements(array_2)); | |
| 56 } else if (i == length - 3 && test_object) { | |
| 57 // Trigger conversion to fast object elements at length-3. | |
| 58 set(array_1, i, 'object'); | |
| 59 set(array_2, i, 'object'); | |
| 60 assertTrue(%HasFastObjectElements(array_1)); | |
| 61 assertTrue(%HasFastObjectElements(array_2)); | |
| 62 } else if (i != length - 7) { | |
| 63 // Set the element to an integer but leave a hole at length-7. | |
| 64 set(array_1, i, 2*i+1); | |
| 65 set(array_2, i, 2*i+1); | |
| 66 } | |
| 67 } | 48 } |
| 68 | 49 |
| 69 for (var i = 0; i < length; i++) { | 50 for (var i = 0; i < length; i++) { |
| 70 if (i == length - 5 && test_double) { | 51 if (i == length - 5 && test_double) { |
| 71 assertEquals(0.5, array_1[i]); | 52 // Trigger conversion to fast double elements at length-5. |
| 72 assertEquals(0.5, array_2[i]); | 53 array_1[i] = 0.5; |
| 54 // assertTrue(%HasFastDoubleElements(array_1)); |
| 73 } else if (i == length - 3 && test_object) { | 55 } else if (i == length - 3 && test_object) { |
| 74 assertEquals('object', array_1[i]); | 56 // Trigger conversion to fast object elements at length-3. |
| 75 assertEquals('object', array_2[i]); | 57 array_1[i] = 'object'; |
| 76 } else if (i != length - 7) { | 58 // assertTrue(%HasFastObjectElements(array_1)); |
| 77 assertEquals(2*i+1, array_1[i]); | |
| 78 assertEquals(2*i+1, array_2[i]); | |
| 79 } else { | 59 } else { |
| 80 assertEquals(undefined, array_1[i]); | 60 // Set the element to an integer but leave a hole at length-7. |
| 81 assertEquals(undefined, array_2[i]); | 61 array_1[i] = 2*i+1; |
| 82 } | 62 } |
| 83 } | 63 } |
| 84 | |
| 85 assertEquals(length, array_1.length); | |
| 86 assertEquals(length, array_2.length); | |
| 87 } | 64 } |
| 88 | 65 |
| 89 test(false, false, function(a,i,v){ a[i] = v; }, 20); | 66 // Don't transition the array |
| 90 test(true, false, function(a,i,v){ a[i] = v; }, 20); | 67 test(false, false, 20, -1); |
| 91 test(false, true, function(a,i,v){ a[i] = v; }, 20); | 68 test(false, false, 20, -1); |
| 92 test(true, true, function(a,i,v){ a[i] = v; }, 20); | 69 %OptimizeFunctionOnNextCall(test); |
| 70 a = test(false, false, 20, 0); |
| 71 assertTrue(%HasFastSmiElements(a)); |
| 72 assertTrue(%HasFastHoleyElements(a)); |
| 73 assertTrue(2 != %GetOptimizationStatus(test)); |
| 93 | 74 |
| 94 test(false, false, function(a,i,v){ a[i] = v; }, 10000); | 75 // Allow transition to double. Causes a deopt at first |
| 95 test(true, false, function(a,i,v){ a[i] = v; }, 10000); | 76 test(true, false, 20, -1); |
| 96 test(false, true, function(a,i,v){ a[i] = v; }, 10000); | 77 assertTrue(2 == %GetOptimizationStatus(test)); |
| 97 test(true, true, function(a,i,v){ a[i] = v; }, 10000); | 78 test(true, false, 20, -1); |
| 79 %OptimizeFunctionOnNextCall(test); |
| 80 a = test(true, false, 20, 0); |
| 81 assertTrue(%HasFastDoubleElements(a)); |
| 82 assertTrue(%HasFastHoleyElements(a)); |
| 83 assertTrue(2 != %GetOptimizationStatus(test)); |
| 98 | 84 |
| 99 // Check COW arrays | 85 // Allow transition to object. Causes a deopt at first |
| 100 function get_cow() { return [1, 2, 3]; } | 86 test(false, true, 20, -1); |
| 87 assertTrue(2 == %GetOptimizationStatus(test)); |
| 88 test(false, true, 20, -1); |
| 89 %OptimizeFunctionOnNextCall(test); |
| 90 a = test(false, true, 20, 0); |
| 91 assertTrue(%HasFastObjectElements(a)); |
| 92 assertTrue(%HasFastHoleyElements(a)); |
| 93 assertTrue(2 != %GetOptimizationStatus(test)); |
| 101 | 94 |
| 102 function transition(x) { x[0] = 1.5; } | 95 // The type information is cumulative, so there shouldn't be a change |
| 96 // in optimization status or return value here. |
| 97 // |
| 98 // Currently this test shows a bug. |
| 99 // I need to visit keyed sites that didn't have a transition as well. |
| 100 // |
| 101 test(true, true, 20, -1); |
| 102 a = test(true, true, 20, 0); |
| 103 // assertTrue(2 != %GetOptimizationStatus(test)); |
| 104 // assertTrue(%HasFastObjectElements(a)); |
| 105 // assertTrue(%HasFastHoleyElements(a)); |
| 103 | 106 |
| 104 var ignore = get_cow(); | |
| 105 transition(ignore); // Handled by runtime. | |
| 106 var a = get_cow(); | |
| 107 var b = get_cow(); | |
| 108 transition(a); // Handled by IC. | |
| 109 assertEquals(1.5, a[0]); | |
| 110 assertEquals(1, b[0]); | |
| 111 } else { | 107 } else { |
| 112 print("Test skipped because smi only arrays are not supported."); | 108 print("Test skipped because smi only arrays are not supported."); |
| 113 } | 109 } |
| OLD | NEW |