Commit 604f5be5 authored by cbruni's avatar cbruni Committed by Commit bot

[elements] add fast-path for slice with FastSloppyArguments

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35300}
parent a6882e82
......@@ -207,9 +207,14 @@ inline bool ClampedToInteger(Object* object, int* out) {
inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object,
int* out) {
Map* arguments_map = isolate->native_context()->sloppy_arguments_map();
if (object->map() != arguments_map) return false;
DCHECK(object->HasFastElements());
Context* context = *isolate->native_context();
Map* map = object->map();
if (map != context->sloppy_arguments_map() &&
map != context->strict_arguments_map() &&
map != context->fast_aliased_arguments_map()) {
return false;
}
DCHECK(object->HasFastElements() || object->HasFastArgumentsElements());
Object* len_obj = object->InObjectPropertyAt(JSArgumentsObject::kLengthIndex);
if (!len_obj->IsSmi()) return false;
*out = Max(0, Smi::cast(len_obj)->value());
......@@ -670,10 +675,11 @@ BUILTIN(ArraySlice) {
} else if (receiver->IsJSObject() &&
GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver),
&len)) {
DCHECK_EQ(FAST_ELEMENTS, JSObject::cast(*receiver)->GetElementsKind());
// Array.prototype.slice(arguments, ...) is quite a common idiom
// Array.prototype.slice.call(arguments, ...) is quite a common idiom
// (notably more than 50% of invocations in Web apps).
// Treat it in C++ as well.
DCHECK(JSObject::cast(*receiver)->HasFastElements() ||
JSObject::cast(*receiver)->HasFastArgumentsElements());
} else {
AllowHeapAllocation allow_allocation;
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
......
......@@ -1453,7 +1453,8 @@ class FastElementsAccessor
}
if (entry == 0) {
FixedArray* empty = heap->empty_fixed_array();
if (obj->HasFastArgumentsElements()) {
if (FastElementsAccessorSubclass::kind() ==
FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
FixedArray::cast(obj->elements())->set(1, empty);
} else {
obj->set_elements(empty);
......@@ -2568,16 +2569,45 @@ class FastSloppyArgumentsElementsAccessor
FastHoleyObjectElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
static Handle<FixedArray> GetArguments(Isolate* isolate,
FixedArrayBase* backing_store) {
FixedArray* parameter_map = FixedArray::cast(backing_store);
return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate);
}
static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start,
uint32_t end) {
Isolate* isolate = receiver->GetIsolate();
uint32_t result_len = end < start ? 0u : end - start;
Handle<JSArray> result_array = isolate->factory()->NewJSArray(
FAST_HOLEY_ELEMENTS, result_len, result_len);
DisallowHeapAllocation no_gc;
FixedArray* elements = FixedArray::cast(result_array->elements());
FixedArray* parameters = FixedArray::cast(receiver->elements());
uint32_t insertion_index = 0;
for (uint32_t i = start; i < end; i++) {
uint32_t entry =
GetEntryForIndexImpl(*receiver, parameters, i, ALL_PROPERTIES);
if (entry != kMaxUInt32 && HasEntryImpl(parameters, entry)) {
elements->set(insertion_index, *GetImpl(parameters, entry));
} else {
elements->set_the_hole(insertion_index);
}
insertion_index++;
}
return result_array;
}
static Handle<SeededNumberDictionary> NormalizeImpl(
Handle<JSObject> object, Handle<FixedArrayBase> elements) {
FixedArray* parameter_map = FixedArray::cast(*elements);
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
Handle<FixedArray> arguments =
GetArguments(elements->GetIsolate(), *elements);
return FastHoleyObjectElementsAccessor::NormalizeImpl(object, arguments);
}
static void DeleteFromArguments(Handle<JSObject> obj, uint32_t entry) {
FixedArray* parameter_map = FixedArray::cast(obj->elements());
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
Handle<FixedArray> arguments =
GetArguments(obj->GetIsolate(), obj->elements());
FastHoleyObjectElementsAccessor::DeleteCommon(obj, entry, arguments);
}
......
......@@ -228,6 +228,7 @@
func([]);
func(['a'], 'a');
func(['a', 1], 'a', 1);
func(['a', 1, 2, 3, 4, 5], 'a', 1, 2, 3, 4, 5);
func(['a', 1, undefined], 'a', 1, undefined);
func(['a', 1, undefined, void(0)], 'a', 1, undefined, void(0));
})();
......
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