From a9a80fb4227a61c508fc456cd6f8aacddc4db4fe Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Thu, 6 Jun 2013 09:26:30 +0000 Subject: [PATCH] Allocation type info advice consumed in bailout path leads to assert failure. If the runtime is taken for a constructor like "new Array(100000)", where allocation site info already led to an elements kind of DOUBLE, then the runtime would fail to transition the array to dictionary mode. Better to recognize this case and avoid wasting time by following the advice. Furthermore, it offers a way to recognize that the array should be in dictionary mode (though a future checkin will capitalize on that). BUG= R=danno@chromium.org Review URL: https://codereview.chromium.org/15993012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14966 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/builtins.cc | 21 +++++++++++++++++---- test/mjsunit/allocation-site-info.js | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/builtins.cc b/src/builtins.cc index b42fd5a..addda08 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -200,16 +200,29 @@ static MaybeObject* ArrayConstructorStubFailureCommon( Handle type_info, Arguments* caller_args) { bool holey = false; - if (caller_args->length() == 1 && (*caller_args)[0]->IsSmi()) { - int value = Smi::cast((*caller_args)[0])->value(); - holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray); + bool can_use_type_feedback = true; + if (caller_args->length() == 1) { + Object* argument_one = (*caller_args)[0]; + if (argument_one->IsSmi()) { + int value = Smi::cast(argument_one)->value(); + if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) { + // the array is a dictionary in this case. + can_use_type_feedback = false; + } else if (value != 0) { + holey = true; + } + } else { + // Non-smi length argument produces a dictionary + can_use_type_feedback = false; + } } JSArray* array; MaybeObject* maybe_array; if (!type_info.is_null() && *type_info != isolate->heap()->undefined_value() && - JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) { + JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() && + can_use_type_feedback) { JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info); Smi* smi = Smi::cast(cell->value()); ElementsKind to_kind = static_cast(smi->value()); diff --git a/test/mjsunit/allocation-site-info.js b/test/mjsunit/allocation-site-info.js index 4560531..f533d61 100644 --- a/test/mjsunit/allocation-site-info.js +++ b/test/mjsunit/allocation-site-info.js @@ -281,6 +281,23 @@ if (support_smi_only_arrays) { obj = newarraycase_list_smiobj(2); assertKind(elements_kind.fast, obj); + function newarraycase_onearg(len, value) { + var a = new Array(len); + a[0] = value; + return a; + } + + 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(); -- 2.7.4