Commit 053d7f49 authored by cbruni's avatar cbruni Committed by Commit bot

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}
parent 887f8760
...@@ -526,8 +526,8 @@ BUILTIN(ArraySlice) { ...@@ -526,8 +526,8 @@ BUILTIN(ArraySlice) {
(relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len); (relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
if (actual_end <= actual_start) { if (actual_end <= actual_start) {
Handle<JSArray> result_array = Handle<JSArray> result_array = isolate->factory()->NewJSArray(
isolate->factory()->NewJSArray(object->GetElementsKind(), 0, 0); GetPackedElementsKind(object->GetElementsKind()), 0, 0);
return *result_array; return *result_array;
} }
......
...@@ -542,6 +542,24 @@ class ElementsAccessorBase : public ElementsAccessor { ...@@ -542,6 +542,24 @@ class ElementsAccessorBase : public ElementsAccessor {
return true; 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, virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
Handle<FixedArrayBase> backing_store) final { Handle<FixedArrayBase> backing_store) final {
return ElementsAccessorSubclass::HasElementImpl(holder, index, return ElementsAccessorSubclass::HasElementImpl(holder, index,
...@@ -1453,6 +1471,8 @@ class FastElementsAccessor ...@@ -1453,6 +1471,8 @@ class FastElementsAccessor
FastElementsAccessorSubclass::CopyElementsImpl( FastElementsAccessorSubclass::CopyElementsImpl(
*backing_store, start, result_array->elements(), KindTraits::Kind, 0, *backing_store, start, result_array->elements(), KindTraits::Kind, 0,
kPackedSizeNotKnown, result_len); kPackedSizeNotKnown, result_len);
FastElementsAccessorSubclass::TryTransitionResultArrayToPacked(
result_array);
return result_array; return result_array;
} }
...@@ -1507,6 +1527,8 @@ class FastElementsAccessor ...@@ -1507,6 +1527,8 @@ class FastElementsAccessor
receiver->set_elements(*backing_store); receiver->set_elements(*backing_store);
} }
receiver->set_length(Smi::FromInt(new_length)); receiver->set_length(Smi::FromInt(new_length));
FastElementsAccessorSubclass::TryTransitionResultArrayToPacked(
deleted_elements);
return deleted_elements; return deleted_elements;
} }
......
...@@ -4046,6 +4046,7 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map, ...@@ -4046,6 +4046,7 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
Object* maybe_array_maps = map->is_strong() Object* maybe_array_maps = map->is_strong()
? native_context->js_array_strong_maps() ? native_context->js_array_strong_maps()
: native_context->js_array_maps(); : native_context->js_array_maps();
// Reuse map transitions for JSArrays.
if (maybe_array_maps->IsFixedArray()) { if (maybe_array_maps->IsFixedArray()) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
FixedArray* array_maps = FixedArray::cast(maybe_array_maps); FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
...@@ -4059,6 +4060,14 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map, ...@@ -4059,6 +4060,14 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
} }
DCHECK(!map->IsUndefined()); 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); bool allow_store_transition = IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality. // Only store fast element maps in ascending generality.
if (IsFastElementsKind(to_kind)) { if (IsFastElementsKind(to_kind)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment