Index: test/mjsunit/allocation-site-info.js |
diff --git a/test/mjsunit/allocation-site-info.js b/test/mjsunit/allocation-site-info.js |
index 0545754aa3c2aa8de15d48f8837270feb954af80..8fa4941033bc8461a719c6109e7d6e6fb01ffa63 100644 |
--- a/test/mjsunit/allocation-site-info.js |
+++ b/test/mjsunit/allocation-site-info.js |
@@ -25,25 +25,9 @@ |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc |
+// Flags: --allow-natives-syntax --expose-gc |
// Flags: --noalways-opt |
-// Test element kind of objects. |
-// Since --smi-only-arrays affects builtins, its default setting at compile |
-// time sticks if built with snapshot. If --smi-only-arrays is deactivated |
-// by default, only a no-snapshot build actually has smi-only arrays enabled |
-// in this test case. Depending on whether smi-only arrays are actually |
-// enabled, this test takes the appropriate code path to check smi-only arrays. |
- |
-// support_smi_only_arrays = %HasFastSmiElements(new Array(1,2,3,4,5,6,7,8)); |
-support_smi_only_arrays = true; |
- |
-if (support_smi_only_arrays) { |
- print("Tests include smi-only arrays."); |
-} else { |
- print("Tests do NOT include smi-only arrays."); |
-} |
- |
var elements_kind = { |
fast_smi_only : 'fast smi only elements', |
fast : 'fast elements', |
@@ -73,10 +57,6 @@ function isHoley(obj) { |
} |
function assertKind(expected, obj, name_opt) { |
- if (!support_smi_only_arrays && |
- expected == elements_kind.fast_smi_only) { |
- expected = elements_kind.fast; |
- } |
assertEquals(expected, getKind(obj), name_opt); |
} |
@@ -88,408 +68,406 @@ function assertNotHoley(obj, name_opt) { |
assertEquals(false, isHoley(obj), name_opt); |
} |
-if (support_smi_only_arrays) { |
- obj = []; |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = []; |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = [1, 2, 3]; |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = [1, 2, 3]; |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = new Array(); |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = new Array(); |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = new Array(0); |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = new Array(0); |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = new Array(2); |
- assertHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = new Array(2); |
+assertHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = new Array(1,2,3); |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast_smi_only, obj); |
+obj = new Array(1,2,3); |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast_smi_only, obj); |
- obj = new Array(1, "hi", 2, undefined); |
- assertNotHoley(obj); |
- assertKind(elements_kind.fast, obj); |
+obj = new Array(1, "hi", 2, undefined); |
+assertNotHoley(obj); |
+assertKind(elements_kind.fast, obj); |
- function fastliteralcase(literal, value) { |
- literal[0] = value; |
- return literal; |
- } |
+function fastliteralcase(literal, value) { |
+ literal[0] = value; |
+ return literal; |
+} |
- function get_standard_literal() { |
- var literal = [1, 2, 3]; |
- return literal; |
- } |
+function get_standard_literal() { |
+ var literal = [1, 2, 3]; |
+ return literal; |
+} |
- // Case: [1,2,3] as allocation site |
- obj = fastliteralcase(get_standard_literal(), 1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = fastliteralcase(get_standard_literal(), 1.5); |
+// Case: [1,2,3] as allocation site |
+obj = fastliteralcase(get_standard_literal(), 1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = fastliteralcase(get_standard_literal(), 1.5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = fastliteralcase(get_standard_literal(), 2); |
+assertKind(elements_kind.fast_double, obj); |
+ |
+// The test below is in a loop because arrays that live |
+// at global scope without the chance of being recreated |
+// don't have allocation site information attached. |
+for (i = 0; i < 2; i++) { |
+ obj = fastliteralcase([5, 3, 2], 1.5); |
assertKind(elements_kind.fast_double, obj); |
- obj = fastliteralcase(get_standard_literal(), 2); |
+ obj = fastliteralcase([3, 6, 2], 1.5); |
assertKind(elements_kind.fast_double, obj); |
- // The test below is in a loop because arrays that live |
- // at global scope without the chance of being recreated |
- // don't have allocation site information attached. |
- for (i = 0; i < 2; i++) { |
- obj = fastliteralcase([5, 3, 2], 1.5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = fastliteralcase([3, 6, 2], 1.5); |
- assertKind(elements_kind.fast_double, obj); |
- |
- // Note: thanks to pessimistic transition store stubs, we'll attempt |
- // to transition to the most general elements kind seen at a particular |
- // store site. So, the elements kind will be double. |
- obj = fastliteralcase([2, 6, 3], 2); |
- assertKind(elements_kind.fast_double, obj); |
- } |
+ // Note: thanks to pessimistic transition store stubs, we'll attempt |
+ // to transition to the most general elements kind seen at a particular |
+ // store site. So, the elements kind will be double. |
+ obj = fastliteralcase([2, 6, 3], 2); |
+ assertKind(elements_kind.fast_double, obj); |
+} |
- // Verify that we will not pretransition the double->fast path. |
- obj = fastliteralcase(get_standard_literal(), "elliot"); |
- assertKind(elements_kind.fast, obj); |
- obj = fastliteralcase(get_standard_literal(), 3); |
- assertKind(elements_kind.fast, obj); |
+// Verify that we will not pretransition the double->fast path. |
+obj = fastliteralcase(get_standard_literal(), "elliot"); |
+assertKind(elements_kind.fast, obj); |
+obj = fastliteralcase(get_standard_literal(), 3); |
+assertKind(elements_kind.fast, obj); |
- // Make sure this works in crankshafted code too. |
+// Make sure this works in crankshafted code too. |
%OptimizeFunctionOnNextCall(get_standard_literal); |
- get_standard_literal(); |
- obj = get_standard_literal(); |
- assertKind(elements_kind.fast, obj); |
+get_standard_literal(); |
+obj = get_standard_literal(); |
+assertKind(elements_kind.fast, obj); |
+ |
+function fastliteralcase_smifast(value) { |
+ var literal = [1, 2, 3, 4]; |
+ literal[0] = value; |
+ return literal; |
+} |
- function fastliteralcase_smifast(value) { |
- var literal = [1, 2, 3, 4]; |
- literal[0] = value; |
- return literal; |
- } |
+obj = fastliteralcase_smifast(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = fastliteralcase_smifast("carter"); |
+assertKind(elements_kind.fast, obj); |
+obj = fastliteralcase_smifast(2); |
+assertKind(elements_kind.fast, obj); |
+ |
+// Case: make sure transitions from packed to holey are tracked |
+function fastliteralcase_smiholey(index, value) { |
+ var literal = [1, 2, 3, 4]; |
+ literal[index] = value; |
+ return literal; |
+} |
- obj = fastliteralcase_smifast(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = fastliteralcase_smifast("carter"); |
- assertKind(elements_kind.fast, obj); |
- obj = fastliteralcase_smifast(2); |
- assertKind(elements_kind.fast, obj); |
+obj = fastliteralcase_smiholey(5, 1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+assertHoley(obj); |
+obj = fastliteralcase_smiholey(0, 1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+assertHoley(obj); |
+ |
+function newarraycase_smidouble(value) { |
+ var a = new Array(); |
+ a[0] = value; |
+ return a; |
+} |
- // Case: make sure transitions from packed to holey are tracked |
- function fastliteralcase_smiholey(index, value) { |
- var literal = [1, 2, 3, 4]; |
- literal[index] = value; |
- return literal; |
- } |
+// Case: new Array() as allocation site, smi->double |
+obj = newarraycase_smidouble(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_smidouble(1.5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = newarraycase_smidouble(2); |
+assertKind(elements_kind.fast_double, obj); |
+ |
+function newarraycase_smiobj(value) { |
+ var a = new Array(); |
+ a[0] = value; |
+ return a; |
+} |
- obj = fastliteralcase_smiholey(5, 1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- assertHoley(obj); |
- obj = fastliteralcase_smiholey(0, 1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- assertHoley(obj); |
+// Case: new Array() as allocation site, smi->fast |
+obj = newarraycase_smiobj(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_smiobj("gloria"); |
+assertKind(elements_kind.fast, obj); |
+obj = newarraycase_smiobj(2); |
+assertKind(elements_kind.fast, obj); |
+ |
+function newarraycase_length_smidouble(value) { |
+ var a = new Array(3); |
+ a[0] = value; |
+ return a; |
+} |
- function newarraycase_smidouble(value) { |
- var a = new Array(); |
- a[0] = value; |
- return a; |
- } |
+// Case: new Array(length) as allocation site |
+obj = newarraycase_length_smidouble(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_length_smidouble(1.5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = newarraycase_length_smidouble(2); |
+assertKind(elements_kind.fast_double, obj); |
+ |
+// Try to continue the transition to fast object. |
+// TODO(mvstanton): re-enable commented out code when |
+// FLAG_pretenuring_call_new is turned on in the build. |
+obj = newarraycase_length_smidouble("coates"); |
+assertKind(elements_kind.fast, obj); |
+obj = newarraycase_length_smidouble(2); |
+// assertKind(elements_kind.fast, obj); |
+ |
+function newarraycase_length_smiobj(value) { |
+ var a = new Array(3); |
+ a[0] = value; |
+ return a; |
+} |
- // Case: new Array() as allocation site, smi->double |
- obj = newarraycase_smidouble(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_smidouble(1.5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = newarraycase_smidouble(2); |
- assertKind(elements_kind.fast_double, obj); |
+// Case: new Array(<length>) as allocation site, smi->fast |
+obj = newarraycase_length_smiobj(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_length_smiobj("gloria"); |
+assertKind(elements_kind.fast, obj); |
+obj = newarraycase_length_smiobj(2); |
+assertKind(elements_kind.fast, obj); |
+ |
+function newarraycase_list_smidouble(value) { |
+ var a = new Array(1, 2, 3); |
+ a[0] = value; |
+ return a; |
+} |
+ |
+obj = newarraycase_list_smidouble(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_list_smidouble(1.5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = newarraycase_list_smidouble(2); |
+assertKind(elements_kind.fast_double, obj); |
+ |
+function newarraycase_list_smiobj(value) { |
+ var a = new Array(4, 5, 6); |
+ a[0] = value; |
+ return a; |
+} |
- function newarraycase_smiobj(value) { |
- var a = new Array(); |
- a[0] = value; |
+obj = newarraycase_list_smiobj(1); |
+assertKind(elements_kind.fast_smi_only, obj); |
+obj = newarraycase_list_smiobj("coates"); |
+assertKind(elements_kind.fast, obj); |
+obj = newarraycase_list_smiobj(2); |
+assertKind(elements_kind.fast, obj); |
+ |
+// Case: array constructor calls with out of date feedback. |
+// The boilerplate should incorporate all feedback, but the input array |
+// should be minimally transitioned based on immediate need. |
+(function() { |
+ function foo(i) { |
+ // We have two cases, one for literals one for constructed arrays. |
+ var a = (i == 0) |
+ ? [1, 2, 3] |
+ : new Array(1, 2, 3); |
return a; |
} |
- // Case: new Array() as allocation site, smi->fast |
- obj = newarraycase_smiobj(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_smiobj("gloria"); |
- assertKind(elements_kind.fast, obj); |
- obj = newarraycase_smiobj(2); |
- assertKind(elements_kind.fast, obj); |
- |
- function newarraycase_length_smidouble(value) { |
- var a = new Array(3); |
- a[0] = value; |
- return a; |
+ for (i = 0; i < 2; i++) { |
+ a = foo(i); |
+ b = foo(i); |
+ b[5] = 1; // boilerplate goes holey |
+ assertHoley(foo(i)); |
+ a[0] = 3.5; // boilerplate goes holey double |
+ assertKind(elements_kind.fast_double, a); |
+ assertNotHoley(a); |
+ c = foo(i); |
+ assertKind(elements_kind.fast_double, c); |
+ assertHoley(c); |
} |
+})(); |
- // Case: new Array(length) as allocation site |
- obj = newarraycase_length_smidouble(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_length_smidouble(1.5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = newarraycase_length_smidouble(2); |
- assertKind(elements_kind.fast_double, obj); |
+function newarraycase_onearg(len, value) { |
+ var a = new Array(len); |
+ a[0] = value; |
+ return a; |
+} |
- // Try to continue the transition to fast object. |
- // TODO(mvstanton): re-enable commented out code when |
- // FLAG_pretenuring_call_new is turned on in the build. |
- obj = newarraycase_length_smidouble("coates"); |
- assertKind(elements_kind.fast, obj); |
- obj = newarraycase_length_smidouble(2); |
- // assertKind(elements_kind.fast, obj); |
+obj = newarraycase_onearg(5, 3.5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = newarraycase_onearg(10, 5); |
+assertKind(elements_kind.fast_double, obj); |
+obj = newarraycase_onearg(0, 5); |
+assertKind(elements_kind.fast_double, obj); |
+// Now pass a length that forces the dictionary path. |
+obj = newarraycase_onearg(100000, 5); |
+assertKind(elements_kind.dictionary, obj); |
+assertTrue(obj.length == 100000); |
+ |
+// Verify that cross context calls work |
+var realmA = Realm.current(); |
+var realmB = Realm.create(); |
+assertEquals(0, realmA); |
+assertEquals(1, realmB); |
+ |
+function instanceof_check(type) { |
+ assertTrue(new type() instanceof type); |
+ assertTrue(new type(5) instanceof type); |
+ assertTrue(new type(1,2,3) instanceof type); |
+} |
- function newarraycase_length_smiobj(value) { |
- var a = new Array(3); |
- a[0] = value; |
- return a; |
- } |
+function instanceof_check2(type) { |
+ assertTrue(new type() instanceof type); |
+ assertTrue(new type(5) instanceof type); |
+ assertTrue(new type(1,2,3) instanceof type); |
+} |
- // Case: new Array(<length>) as allocation site, smi->fast |
- obj = newarraycase_length_smiobj(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_length_smiobj("gloria"); |
- assertKind(elements_kind.fast, obj); |
- obj = newarraycase_length_smiobj(2); |
- assertKind(elements_kind.fast, obj); |
+var realmBArray = Realm.eval(realmB, "Array"); |
+instanceof_check(Array); |
+instanceof_check(realmBArray); |
- function newarraycase_list_smidouble(value) { |
- var a = new Array(1, 2, 3); |
- a[0] = value; |
- return a; |
- } |
+// instanceof_check2 is here because the call site goes through a state. |
+// Since instanceof_check(Array) was first called with the current context |
+// Array function, it went from (uninit->Array) then (Array->megamorphic). |
+// We'll get a different state traversal if we start with realmBArray. |
+// It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize |
+// that state "Array" implies an AllocationSite is present, and code is |
+// configured to use it. |
+instanceof_check2(realmBArray); |
+instanceof_check2(Array); |
- obj = newarraycase_list_smidouble(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_list_smidouble(1.5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = newarraycase_list_smidouble(2); |
- assertKind(elements_kind.fast_double, obj); |
+ %OptimizeFunctionOnNextCall(instanceof_check); |
- function newarraycase_list_smiobj(value) { |
- var a = new Array(4, 5, 6); |
- a[0] = value; |
- return a; |
+// No de-opt will occur because HCallNewArray wasn't selected, on account of |
+// the call site not being monomorphic to Array. |
+instanceof_check(Array); |
+assertOptimized(instanceof_check); |
+instanceof_check(realmBArray); |
+assertOptimized(instanceof_check); |
+ |
+// Try to optimize again, but first clear all type feedback, and allow it |
+// to be monomorphic on first call. Only after crankshafting do we introduce |
+// realmBArray. This should deopt the method. |
+ %DeoptimizeFunction(instanceof_check); |
+ %ClearFunctionTypeFeedback(instanceof_check); |
+instanceof_check(Array); |
+instanceof_check(Array); |
+ %OptimizeFunctionOnNextCall(instanceof_check); |
+instanceof_check(Array); |
+assertOptimized(instanceof_check); |
+ |
+instanceof_check(realmBArray); |
+assertUnoptimized(instanceof_check); |
+ |
+// Case: make sure nested arrays benefit from allocation site feedback as |
+// well. |
+(function() { |
+ // Make sure we handle nested arrays |
+ function get_nested_literal() { |
+ var literal = [[1,2,3,4], [2], [3]]; |
+ return literal; |
} |
- obj = newarraycase_list_smiobj(1); |
- assertKind(elements_kind.fast_smi_only, obj); |
- obj = newarraycase_list_smiobj("coates"); |
- assertKind(elements_kind.fast, obj); |
- obj = newarraycase_list_smiobj(2); |
+ obj = get_nested_literal(); |
assertKind(elements_kind.fast, obj); |
- |
- // Case: array constructor calls with out of date feedback. |
- // The boilerplate should incorporate all feedback, but the input array |
- // should be minimally transitioned based on immediate need. |
- (function() { |
- function foo(i) { |
- // We have two cases, one for literals one for constructed arrays. |
- var a = (i == 0) |
- ? [1, 2, 3] |
- : new Array(1, 2, 3); |
- return a; |
- } |
- |
- for (i = 0; i < 2; i++) { |
- a = foo(i); |
- b = foo(i); |
- b[5] = 1; // boilerplate goes holey |
- assertHoley(foo(i)); |
- a[0] = 3.5; // boilerplate goes holey double |
- assertKind(elements_kind.fast_double, a); |
- assertNotHoley(a); |
- c = foo(i); |
- assertKind(elements_kind.fast_double, c); |
- assertHoley(c); |
- } |
- })(); |
- |
- function newarraycase_onearg(len, value) { |
- var a = new Array(len); |
- a[0] = value; |
- return a; |
+ obj[0][0] = 3.5; |
+ obj[2][0] = "hello"; |
+ obj = get_nested_literal(); |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast_smi_only, obj[1]); |
+ assertKind(elements_kind.fast, obj[2]); |
+ |
+ // A more complex nested literal case. |
+ function get_deep_nested_literal() { |
+ var literal = [[1], [[2], "hello"], 3, [4]]; |
+ return literal; |
} |
- obj = newarraycase_onearg(5, 3.5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = newarraycase_onearg(10, 5); |
- assertKind(elements_kind.fast_double, obj); |
- obj = newarraycase_onearg(0, 5); |
- assertKind(elements_kind.fast_double, obj); |
- // Now pass a length that forces the dictionary path. |
- obj = newarraycase_onearg(100000, 5); |
- assertKind(elements_kind.dictionary, obj); |
- assertTrue(obj.length == 100000); |
- |
- // Verify that cross context calls work |
- var realmA = Realm.current(); |
- var realmB = Realm.create(); |
- assertEquals(0, realmA); |
- assertEquals(1, realmB); |
- |
- function instanceof_check(type) { |
- assertTrue(new type() instanceof type); |
- assertTrue(new type(5) instanceof type); |
- assertTrue(new type(1,2,3) instanceof type); |
+ obj = get_deep_nested_literal(); |
+ assertKind(elements_kind.fast_smi_only, obj[1][0]); |
+ obj[0][0] = 3.5; |
+ obj[1][0][0] = "goodbye"; |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast, obj[1][0]); |
+ |
+ obj = get_deep_nested_literal(); |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast, obj[1][0]); |
+})(); |
+ |
+// Perform a gc because without it the test below can experience an |
+// allocation failure at an inconvenient point. Allocation mementos get |
+// cleared on gc, and they can't deliver elements kind feedback when that |
+// happens. |
+gc(); |
+ |
+// Make sure object literals with array fields benefit from the type feedback |
+// that allocation mementos provide. |
+(function() { |
+ // A literal in an object |
+ function get_object_literal() { |
+ var literal = { |
+ array: [1,2,3], |
+ data: 3.5 |
+ }; |
+ return literal; |
} |
- function instanceof_check2(type) { |
- assertTrue(new type() instanceof type); |
- assertTrue(new type(5) instanceof type); |
- assertTrue(new type(1,2,3) instanceof type); |
+ obj = get_object_literal(); |
+ assertKind(elements_kind.fast_smi_only, obj.array); |
+ obj.array[1] = 3.5; |
+ assertKind(elements_kind.fast_double, obj.array); |
+ obj = get_object_literal(); |
+ assertKind(elements_kind.fast_double, obj.array); |
+ |
+ function get_nested_object_literal() { |
+ var literal = { |
+ array: [[1],[2],[3]], |
+ data: 3.5 |
+ }; |
+ return literal; |
} |
- var realmBArray = Realm.eval(realmB, "Array"); |
- instanceof_check(Array); |
- instanceof_check(realmBArray); |
- |
- // instanceof_check2 is here because the call site goes through a state. |
- // Since instanceof_check(Array) was first called with the current context |
- // Array function, it went from (uninit->Array) then (Array->megamorphic). |
- // We'll get a different state traversal if we start with realmBArray. |
- // It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize |
- // that state "Array" implies an AllocationSite is present, and code is |
- // configured to use it. |
- instanceof_check2(realmBArray); |
- instanceof_check2(Array); |
+ obj = get_nested_object_literal(); |
+ assertKind(elements_kind.fast, obj.array); |
+ assertKind(elements_kind.fast_smi_only, obj.array[1]); |
+ obj.array[1][0] = 3.5; |
+ assertKind(elements_kind.fast_double, obj.array[1]); |
+ obj = get_nested_object_literal(); |
+ assertKind(elements_kind.fast_double, obj.array[1]); |
- %OptimizeFunctionOnNextCall(instanceof_check); |
+ %OptimizeFunctionOnNextCall(get_nested_object_literal); |
+ get_nested_object_literal(); |
+ obj = get_nested_object_literal(); |
+ assertKind(elements_kind.fast_double, obj.array[1]); |
- // No de-opt will occur because HCallNewArray wasn't selected, on account of |
- // the call site not being monomorphic to Array. |
- instanceof_check(Array); |
- assertOptimized(instanceof_check); |
- instanceof_check(realmBArray); |
- assertOptimized(instanceof_check); |
+ // Make sure we handle nested arrays |
+ function get_nested_literal() { |
+ var literal = [[1,2,3,4], [2], [3]]; |
+ return literal; |
+ } |
- // Try to optimize again, but first clear all type feedback, and allow it |
- // to be monomorphic on first call. Only after crankshafting do we introduce |
- // realmBArray. This should deopt the method. |
- %DeoptimizeFunction(instanceof_check); |
- %ClearFunctionTypeFeedback(instanceof_check); |
- instanceof_check(Array); |
- instanceof_check(Array); |
- %OptimizeFunctionOnNextCall(instanceof_check); |
- instanceof_check(Array); |
- assertOptimized(instanceof_check); |
- |
- instanceof_check(realmBArray); |
- assertUnoptimized(instanceof_check); |
- |
- // Case: make sure nested arrays benefit from allocation site feedback as |
- // well. |
- (function() { |
- // Make sure we handle nested arrays |
- function get_nested_literal() { |
- var literal = [[1,2,3,4], [2], [3]]; |
- return literal; |
- } |
- |
- obj = get_nested_literal(); |
- assertKind(elements_kind.fast, obj); |
- obj[0][0] = 3.5; |
- obj[2][0] = "hello"; |
- obj = get_nested_literal(); |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast_smi_only, obj[1]); |
- assertKind(elements_kind.fast, obj[2]); |
- |
- // A more complex nested literal case. |
- function get_deep_nested_literal() { |
- var literal = [[1], [[2], "hello"], 3, [4]]; |
- return literal; |
- } |
- |
- obj = get_deep_nested_literal(); |
- assertKind(elements_kind.fast_smi_only, obj[1][0]); |
- obj[0][0] = 3.5; |
- obj[1][0][0] = "goodbye"; |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast, obj[1][0]); |
- |
- obj = get_deep_nested_literal(); |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast, obj[1][0]); |
- })(); |
- |
- // Perform a gc because without it the test below can experience an |
- // allocation failure at an inconvenient point. Allocation mementos get |
- // cleared on gc, and they can't deliver elements kind feedback when that |
- // happens. |
- gc(); |
- |
- // Make sure object literals with array fields benefit from the type feedback |
- // that allocation mementos provide. |
- (function() { |
- // A literal in an object |
- function get_object_literal() { |
- var literal = { |
- array: [1,2,3], |
- data: 3.5 |
- }; |
- return literal; |
- } |
- |
- obj = get_object_literal(); |
- assertKind(elements_kind.fast_smi_only, obj.array); |
- obj.array[1] = 3.5; |
- assertKind(elements_kind.fast_double, obj.array); |
- obj = get_object_literal(); |
- assertKind(elements_kind.fast_double, obj.array); |
- |
- function get_nested_object_literal() { |
- var literal = { |
- array: [[1],[2],[3]], |
- data: 3.5 |
- }; |
- return literal; |
- } |
- |
- obj = get_nested_object_literal(); |
- assertKind(elements_kind.fast, obj.array); |
- assertKind(elements_kind.fast_smi_only, obj.array[1]); |
- obj.array[1][0] = 3.5; |
- assertKind(elements_kind.fast_double, obj.array[1]); |
- obj = get_nested_object_literal(); |
- assertKind(elements_kind.fast_double, obj.array[1]); |
+ obj = get_nested_literal(); |
+ assertKind(elements_kind.fast, obj); |
+ obj[0][0] = 3.5; |
+ obj[2][0] = "hello"; |
+ obj = get_nested_literal(); |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast_smi_only, obj[1]); |
+ assertKind(elements_kind.fast, obj[2]); |
+ |
+ // A more complex nested literal case. |
+ function get_deep_nested_literal() { |
+ var literal = [[1], [[2], "hello"], 3, [4]]; |
+ return literal; |
+ } |
- %OptimizeFunctionOnNextCall(get_nested_object_literal); |
- get_nested_object_literal(); |
- obj = get_nested_object_literal(); |
- assertKind(elements_kind.fast_double, obj.array[1]); |
- |
- // Make sure we handle nested arrays |
- function get_nested_literal() { |
- var literal = [[1,2,3,4], [2], [3]]; |
- return literal; |
- } |
- |
- obj = get_nested_literal(); |
- assertKind(elements_kind.fast, obj); |
- obj[0][0] = 3.5; |
- obj[2][0] = "hello"; |
- obj = get_nested_literal(); |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast_smi_only, obj[1]); |
- assertKind(elements_kind.fast, obj[2]); |
- |
- // A more complex nested literal case. |
- function get_deep_nested_literal() { |
- var literal = [[1], [[2], "hello"], 3, [4]]; |
- return literal; |
- } |
- |
- obj = get_deep_nested_literal(); |
- assertKind(elements_kind.fast_smi_only, obj[1][0]); |
- obj[0][0] = 3.5; |
- obj[1][0][0] = "goodbye"; |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast, obj[1][0]); |
- |
- obj = get_deep_nested_literal(); |
- assertKind(elements_kind.fast_double, obj[0]); |
- assertKind(elements_kind.fast, obj[1][0]); |
- })(); |
-} |
+ obj = get_deep_nested_literal(); |
+ assertKind(elements_kind.fast_smi_only, obj[1][0]); |
+ obj[0][0] = 3.5; |
+ obj[1][0][0] = "goodbye"; |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast, obj[1][0]); |
+ |
+ obj = get_deep_nested_literal(); |
+ assertKind(elements_kind.fast_double, obj[0]); |
+ assertKind(elements_kind.fast, obj[1][0]); |
+})(); |