| Index: src/builtins.cc
|
| diff --git a/src/builtins.cc b/src/builtins.cc
|
| index e98fb47a74c4224a54cab9018997f58b74de43da..92f66d2c91bea4be62f78c288d5a669a19f46faa 100644
|
| --- a/src/builtins.cc
|
| +++ b/src/builtins.cc
|
| @@ -266,6 +266,7 @@ inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
|
| Arguments* args,
|
| int first_added_arg) {
|
| if (!receiver->IsJSArray()) return false;
|
| +
|
| Handle<JSArray> array = Handle<JSArray>::cast(receiver);
|
| ElementsKind origin_kind = array->GetElementsKind();
|
| if (IsDictionaryElementsKind(origin_kind)) return false;
|
| @@ -1317,14 +1318,6 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
|
| return true;
|
| }
|
|
|
| -
|
| -bool HasConcatSpreadableModifier(Isolate* isolate, Handle<JSArray> obj) {
|
| - Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
|
| - Maybe<bool> maybe = JSReceiver::HasProperty(obj, key);
|
| - return maybe.FromMaybe(false);
|
| -}
|
| -
|
| -
|
| static Maybe<bool> IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
|
| HandleScope handle_scope(isolate);
|
| if (!obj->IsJSReceiver()) return Just(false);
|
| @@ -1519,8 +1512,25 @@ Object* Slow_ArrayConcat(Arguments* args, Handle<Object> species,
|
| }
|
| }
|
|
|
| +bool IsSimpleArray(Isolate* isolate, Handle<JSArray> obj) {
|
| + {
|
| + DisallowHeapAllocation no_gc;
|
| + Map* map = obj->map();
|
| + if (map->prototype() ==
|
| + isolate->native_context()->initial_array_prototype()) {
|
| + // If there is only the 'length' property we are fine.
|
| + if (map->NumberOfOwnDescriptors() == 1) return false;
|
| + }
|
| + }
|
| + // TODO(cbruni): slower lookup for array subclasses and support slow
|
| + // @@IsConcatSpreadable lookup.
|
| + return true;
|
| +}
|
|
|
| MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
|
| + if (!isolate->IsArrayIsConcatSpreadableLookupChainIntact()) {
|
| + return MaybeHandle<JSArray>();
|
| + }
|
| int n_arguments = args->length();
|
| int result_len = 0;
|
| {
|
| @@ -1538,7 +1548,7 @@ MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
|
| return MaybeHandle<JSArray>();
|
| }
|
| Handle<JSArray> array(JSArray::cast(arg), isolate);
|
| - if (HasConcatSpreadableModifier(isolate, array)) {
|
| + if (IsSimpleArray(isolate, array)) {
|
| return MaybeHandle<JSArray>();
|
| }
|
| int len = Smi::cast(array->length())->value();
|
| @@ -1548,7 +1558,7 @@ MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
|
| STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
|
| USE(kHalfOfMaxInt);
|
| result_len += len;
|
| - DCHECK(result_len >= 0);
|
| + DCHECK_LE(0, result_len);
|
| // Throw an Error if we overflow the FixedArray limits
|
| if (FixedArray::kMaxLength < result_len) {
|
| THROW_NEW_ERROR(isolate,
|
| @@ -1557,7 +1567,7 @@ MaybeHandle<JSArray> Fast_ArrayConcat(Isolate* isolate, Arguments* args) {
|
| }
|
| }
|
| }
|
| - return ElementsAccessor::Concat(isolate, args, n_arguments);
|
| + return ElementsAccessor::Concat(isolate, args, n_arguments, result_len);
|
| }
|
|
|
| } // namespace
|
|
|