| Index: src/runtime/runtime-array.cc | 
| diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc | 
| index 6664c814006798046ef7a6ffa279788e04146a49..f6c6e9d6f27486eceabfb89ce0ddb30a775b0166 100644 | 
| --- a/src/runtime/runtime-array.cc | 
| +++ b/src/runtime/runtime-array.cc | 
| @@ -32,18 +32,24 @@ RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) { | 
| } | 
|  | 
| static void InstallCode(Isolate* isolate, Handle<JSObject> holder, | 
| -                        const char* name, Handle<Code> code) { | 
| +                        const char* name, Handle<Code> code, int argc = -1) { | 
| Handle<String> key = isolate->factory()->InternalizeUtf8String(name); | 
| Handle<JSFunction> optimized = | 
| isolate->factory()->NewFunctionWithoutPrototype(key, code); | 
| -  optimized->shared()->DontAdaptArguments(); | 
| +  if (argc < 0) { | 
| +    optimized->shared()->DontAdaptArguments(); | 
| +  } else { | 
| +    optimized->shared()->set_internal_formal_parameter_count(argc); | 
| +  } | 
| JSObject::AddProperty(holder, key, optimized, NONE); | 
| } | 
|  | 
| static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder, | 
| -                           const char* name, Builtins::Name builtin_name) { | 
| +                           const char* name, Builtins::Name builtin_name, | 
| +                           int argc = -1) { | 
| InstallCode(isolate, holder, name, | 
| -              handle(isolate->builtins()->builtin(builtin_name), isolate)); | 
| +              handle(isolate->builtins()->builtin(builtin_name), isolate), | 
| +              argc); | 
| } | 
|  | 
| RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { | 
| @@ -59,6 +65,7 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { | 
| InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); | 
| InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); | 
| InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); | 
| +  InstallBuiltin(isolate, holder, "includes", Builtins::kArrayIncludes, 2); | 
|  | 
| return *holder; | 
| } | 
| @@ -439,5 +446,100 @@ RUNTIME_FUNCTION(Runtime_ArraySpeciesConstructor) { | 
| isolate, Object::ArraySpeciesConstructor(isolate, original_array)); | 
| } | 
|  | 
| +static inline Object* FastArrayIncludes(Isolate* isolate, | 
| +                                        Handle<JSObject> object, | 
| +                                        Handle<Object> value, uint32_t k, | 
| +                                        uint32_t len) { | 
| +  ElementsAccessor* elements = object->GetElementsAccessor(); | 
| +  Maybe<bool> result = elements->IncludesValue(isolate, object, value, k, len); | 
| +  MAYBE_RETURN(result, isolate->heap()->exception()); | 
| +  return *isolate->factory()->ToBoolean(result.FromJust()); | 
| +} | 
| + | 
| +// ES7 22.1.3.11 Array.prototype.includes | 
| +RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { | 
| +  HandleScope shs(isolate); | 
| +  DCHECK(args.length() == 3); | 
| +  CONVERT_ARG_HANDLE_CHECKED(Object, search_element, 1); | 
| +  CONVERT_ARG_HANDLE_CHECKED(Object, start_from_, 2); | 
| + | 
| +  // 1. Let O be ? ToObject(this value). | 
| +  Handle<JSReceiver> object; | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +      isolate, object, Object::ToObject(isolate, handle(args[0], isolate))); | 
| + | 
| +  // 2. Let len be ? ToLength(? Get(O, "length")). | 
| +  Handle<Object> len_; | 
| +  int64_t len; | 
| +  if (object->map()->instance_type() == JS_ARRAY_TYPE) { | 
| +    len_ = handle(JSArray::cast(*object)->length(), isolate); | 
| +  } else { | 
| +    ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 
| +        isolate, len_, | 
| +        Object::GetProperty(object, isolate->factory()->length_string())); | 
| +  } | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, len_, | 
| +                                     Object::ToLength(isolate, len_)); | 
| +  len = static_cast<int64_t>(len_->Number()); | 
| +  DCHECK_EQ(len, len_->Number()); | 
| + | 
| +  // 3. If len is 0, return false. | 
| +  if (len == 0) return isolate->heap()->false_value(); | 
| + | 
| +  // 4. Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, | 
| +  //    this step produces the value 0.) | 
| +  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, start_from_, | 
| +                                     Object::ToInteger(isolate, start_from_)); | 
| +  if (std::isinf(start_from_->Number()) && start_from_->Number() > 0.0) { | 
| +    return isolate->heap()->false_value(); | 
| +  } | 
| +  int64_t start_from = static_cast<int64_t>(start_from_->Number()); | 
| + | 
| +  int64_t index; | 
| +  if (start_from >= 0) { | 
| +    index = start_from; | 
| +  } else { | 
| +    index = len + start_from; | 
| +    if (index < 0) { | 
| +      index = 0; | 
| +    } | 
| +  } | 
| + | 
| +  // In the slow path, we can still take a fast path similar to the TurboFan | 
| +  // implementation if there are no elements in the prototype, and if the length | 
| +  // is within elements boundaries. | 
| +  // | 
| +  // This would apply to Array-like Objects with no elements in the prototype, | 
| +  // for example. | 
| +  if (object->map()->instance_type() > LAST_SPECIAL_RECEIVER_TYPE && | 
| +      len < std::numeric_limits<uint32_t>::max() && | 
| +      JSObject::PrototypeHasNoElements(isolate, JSObject::cast(*object))) { | 
| +    return FastArrayIncludes(isolate, Handle<JSObject>::cast(object), | 
| +                             search_element, static_cast<uint32_t>(index), | 
| +                             static_cast<uint32_t>(len)); | 
| +  } | 
| + | 
| +  // Otherwise, perform slow lookups for JSProxies and API objects, or for | 
| +  // objects with long `length` values. | 
| +  for (; index < len; ++index) { | 
| +    Handle<Object> element_k; | 
| + | 
| +    Handle<Object> index_object = isolate->factory()->NewNumberFromInt64(index); | 
| + | 
| +    bool success; | 
| +    LookupIterator it = LookupIterator::PropertyOrElement( | 
| +        isolate, object, index_object, &success); | 
| +    DCHECK(success); | 
| + | 
| +    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_k, | 
| +                                       Object::GetProperty(&it)); | 
| + | 
| +    if (search_element->SameValueZero(*element_k)) { | 
| +      return isolate->heap()->true_value(); | 
| +    } | 
| +  } | 
| +  return isolate->heap()->false_value(); | 
| +} | 
| + | 
| }  // namespace internal | 
| }  // namespace v8 | 
|  |