builtins.cc return PackedElementsKind where applicable

Returning a result array with holey elements kind in where we actually have a packed kind causes performance regressions.

LOG=N
BUG=chromium:531357

Review URL: https://codereview.chromium.org/1340033002

Cr-Commit-Position: refs/heads/master@{#30736}
This commit is contained in:
cbruni 2015-09-15 02:08:28 -07:00 committed by Commit bot
parent 887f876058
commit 053d7f49e5
3 changed files with 33 additions and 2 deletions

View File

@ -526,8 +526,8 @@ BUILTIN(ArraySlice) {
(relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
if (actual_end <= actual_start) {
Handle<JSArray> result_array =
isolate->factory()->NewJSArray(object->GetElementsKind(), 0, 0);
Handle<JSArray> result_array = isolate->factory()->NewJSArray(
GetPackedElementsKind(object->GetElementsKind()), 0, 0);
return *result_array;
}

View File

@ -542,6 +542,24 @@ class ElementsAccessorBase : public ElementsAccessor {
return true;
}
static void TryTransitionResultArrayToPacked(Handle<JSArray> array) {
if (!IsHoleyElementsKind(kind())) return;
int length = Smi::cast(array->length())->value();
Handle<FixedArrayBase> backing_store(array->elements());
if (!ElementsAccessorSubclass::IsPackedImpl(array, backing_store, 0,
length)) {
return;
}
ElementsKind packed_kind = GetPackedElementsKind(kind());
Handle<Map> new_map =
JSObject::GetElementsTransitionMap(array, packed_kind);
JSObject::MigrateToMap(array, new_map);
if (FLAG_trace_elements_transitions) {
JSObject::PrintElementsTransition(stdout, array, kind(), backing_store,
packed_kind, backing_store);
}
}
virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
Handle<FixedArrayBase> backing_store) final {
return ElementsAccessorSubclass::HasElementImpl(holder, index,
@ -1453,6 +1471,8 @@ class FastElementsAccessor
FastElementsAccessorSubclass::CopyElementsImpl(
*backing_store, start, result_array->elements(), KindTraits::Kind, 0,
kPackedSizeNotKnown, result_len);
FastElementsAccessorSubclass::TryTransitionResultArrayToPacked(
result_array);
return result_array;
}
@ -1507,6 +1527,8 @@ class FastElementsAccessor
receiver->set_elements(*backing_store);
}
receiver->set_length(Smi::FromInt(new_length));
FastElementsAccessorSubclass::TryTransitionResultArrayToPacked(
deleted_elements);
return deleted_elements;
}

View File

@ -4046,6 +4046,7 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
Object* maybe_array_maps = map->is_strong()
? native_context->js_array_strong_maps()
: native_context->js_array_maps();
// Reuse map transitions for JSArrays.
if (maybe_array_maps->IsFixedArray()) {
DisallowHeapAllocation no_gc;
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
@ -4059,6 +4060,14 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
}
DCHECK(!map->IsUndefined());
// Check if we can go back in the elements kind transition chain.
if (IsHoleyElementsKind(from_kind) &&
to_kind == GetPackedElementsKind(from_kind) &&
map->GetBackPointer()->IsMap() &&
Map::cast(map->GetBackPointer())->elements_kind() == to_kind) {
return handle(Map::cast(map->GetBackPointer()));
}
bool allow_store_transition = IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality.
if (IsFastElementsKind(to_kind)) {