Reviewers: danno,
Message:
Hi Danno, here is the bugfix I referred to earlier today. I also added a
test.
Without the fix, the test fails with an assert under
JSObject::GetElementsCapacityAndUsage() in the bailout.
Description:
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=
Please review this at https://codereview.chromium.org/15993012/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/builtins.cc
M test/mjsunit/allocation-site-info.js
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index
37ba1e5301a9e17a9e5f4f026e0ad902bb03fd9d..8a4ae71ff0a229daa97dfed558eb1da94716328f
100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -209,15 +209,25 @@ RUNTIME_FUNCTION(MaybeObject*,
ArrayConstructor_StubFailure) {
Handle<Object> type_info = args.at<Object>(parameters_start + 1);
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 ignore_advice = false;
+ if (caller_args->length() == 1) {
+ Object* argument_one = (*caller_args)[0];
+ if (argument_one->IsSmi()) {
+ int value = Smi::cast(argument_one)->value();
+ holey = (value > 0 && value < JSObject::kInitialMaxFastElementArray);
+ }
+
+ // If we have a single argument, and we failed to set holey above,
+ // then we'll be forced down the dictionary path. In this case it's
+ // useless to consume allocation site info advice, even if we have it.
+ ignore_advice = !holey;
}
JSArray* array;
MaybeObject* maybe_array;
if (*type_info != isolate->heap()->undefined_value() &&
- JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi()) {
+ JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() &&
+ !ignore_advice) {
JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info);
Smi* smi = Smi::cast(cell->value());
ElementsKind to_kind = static_cast<ElementsKind>(smi->value());
Index: test/mjsunit/allocation-site-info.js
diff --git a/test/mjsunit/allocation-site-info.js
b/test/mjsunit/allocation-site-info.js
index
45605317fea69bfd116897c75e9a1a08fc5a9bdb..5af4598494398b30bf5370a6a08047c7a0c4ae7c
100644
--- a/test/mjsunit/allocation-site-info.js
+++ b/test/mjsunit/allocation-site-info.js
@@ -281,6 +281,21 @@ 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);
+ // 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();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.