[elements] add fast-path for slice with FastSloppyArguments
BUG= Review URL: https://codereview.chromium.org/1834613003 Cr-Commit-Position: refs/heads/master@{#35300}
This commit is contained in:
parent
a6882e8262
commit
604f5be5f7
@ -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));
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user