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:
parent
887f876058
commit
053d7f49e5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user