LCOV - code coverage report
Current view: top level - src/objects - js-objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1925 2124 90.6 %
Date: 2019-02-19 Functions: 183 190 96.3 %

          Line data    Source code
       1             : // Copyright 2019 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/objects/js-objects.h"
       6             : 
       7             : #include "src/api-arguments-inl.h"
       8             : #include "src/arguments.h"
       9             : #include "src/bootstrapper.h"
      10             : #include "src/compiler.h"
      11             : #include "src/counters.h"
      12             : #include "src/date.h"
      13             : #include "src/elements.h"
      14             : #include "src/field-type.h"
      15             : #include "src/handles-inl.h"
      16             : #include "src/heap/heap-inl.h"
      17             : #include "src/ic/ic.h"
      18             : #include "src/isolate.h"
      19             : #include "src/layout-descriptor.h"
      20             : #include "src/log.h"
      21             : #include "src/lookup.h"
      22             : #include "src/maybe-handles.h"
      23             : #include "src/objects-inl.h"
      24             : #include "src/objects/allocation-site-inl.h"
      25             : #include "src/objects/api-callbacks.h"
      26             : #include "src/objects/arguments-inl.h"
      27             : #include "src/objects/dictionary.h"
      28             : #include "src/objects/fixed-array.h"
      29             : #include "src/objects/heap-number.h"
      30             : #include "src/objects/js-array-buffer.h"
      31             : #include "src/objects/js-array-inl.h"
      32             : #ifdef V8_INTL_SUPPORT
      33             : #include "src/objects/js-break-iterator.h"
      34             : #include "src/objects/js-collator.h"
      35             : #endif  // V8_INTL_SUPPORT
      36             : #include "src/objects/js-collection.h"
      37             : #ifdef V8_INTL_SUPPORT
      38             : #include "src/objects/js-date-time-format.h"
      39             : #endif  // V8_INTL_SUPPORT
      40             : #include "src/objects/js-generator-inl.h"
      41             : #ifdef V8_INTL_SUPPORT
      42             : #include "src/objects/js-list-format.h"
      43             : #include "src/objects/js-locale.h"
      44             : #include "src/objects/js-number-format.h"
      45             : #include "src/objects/js-plural-rules.h"
      46             : #endif  // V8_INTL_SUPPORT
      47             : #include "src/objects/js-promise.h"
      48             : #include "src/objects/js-regexp-inl.h"
      49             : #include "src/objects/js-regexp-string-iterator.h"
      50             : #ifdef V8_INTL_SUPPORT
      51             : #include "src/objects/js-relative-time-format.h"
      52             : #include "src/objects/js-segment-iterator.h"
      53             : #include "src/objects/js-segmenter.h"
      54             : #endif  // V8_INTL_SUPPORT
      55             : #include "src/objects/js-weak-refs.h"
      56             : #include "src/objects/map-inl.h"
      57             : #include "src/objects/module.h"
      58             : #include "src/objects/oddball.h"
      59             : #include "src/objects/property-cell.h"
      60             : #include "src/objects/prototype-info.h"
      61             : #include "src/objects/shared-function-info.h"
      62             : #include "src/ostreams.h"
      63             : #include "src/property-descriptor.h"
      64             : #include "src/property.h"
      65             : #include "src/prototype.h"
      66             : #include "src/string-builder-inl.h"
      67             : #include "src/string-stream.h"
      68             : #include "src/transitions.h"
      69             : #include "src/wasm/wasm-objects.h"
      70             : 
      71             : namespace v8 {
      72             : namespace internal {
      73             : 
      74             : // static
      75    10330506 : Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
      76    10312494 :   for (; it->IsFound(); it->Next()) {
      77     1607373 :     switch (it->state()) {
      78             :       case LookupIterator::NOT_FOUND:
      79             :       case LookupIterator::TRANSITION:
      80           0 :         UNREACHABLE();
      81             :       case LookupIterator::JSPROXY:
      82             :         return JSProxy::HasProperty(it->isolate(), it->GetHolder<JSProxy>(),
      83       94176 :                                     it->GetName());
      84             :       case LookupIterator::INTERCEPTOR: {
      85             :         Maybe<PropertyAttributes> result =
      86         226 :             JSObject::GetPropertyAttributesWithInterceptor(it);
      87         300 :         if (result.IsNothing()) return Nothing<bool>();
      88         220 :         if (result.FromJust() != ABSENT) return Just(true);
      89         152 :         break;
      90             :       }
      91             :       case LookupIterator::ACCESS_CHECK: {
      92       28964 :         if (it->HasAccess()) break;
      93             :         Maybe<PropertyAttributes> result =
      94          40 :             JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
      95          80 :         if (result.IsNothing()) return Nothing<bool>();
      96           0 :         return Just(result.FromJust() != ABSENT);
      97             :       }
      98             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
      99             :         // TypedArray out-of-bounds access.
     100             :         return Just(false);
     101             :       case LookupIterator::ACCESSOR:
     102             :       case LookupIterator::DATA:
     103             :         return Just(true);
     104             :     }
     105             :   }
     106             :   return Just(false);
     107             : }
     108             : 
     109             : // static
     110      423655 : Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object,
     111             :                                        Handle<Name> name) {
     112      847310 :   if (object->IsJSModuleNamespace()) {
     113             :     PropertyDescriptor desc;
     114             :     return JSReceiver::GetOwnPropertyDescriptor(object->GetIsolate(), object,
     115         171 :                                                 name, &desc);
     116             :   }
     117             : 
     118      846968 :   if (object->IsJSObject()) {  // Shortcut.
     119             :     LookupIterator it = LookupIterator::PropertyOrElement(
     120      422095 :         object->GetIsolate(), object, name, object, LookupIterator::OWN);
     121      422095 :     return HasProperty(&it);
     122             :   }
     123             : 
     124             :   Maybe<PropertyAttributes> attributes =
     125        1389 :       JSReceiver::GetOwnPropertyAttributes(object, name);
     126        1389 :   MAYBE_RETURN(attributes, Nothing<bool>());
     127        1299 :   return Just(attributes.FromJust() != ABSENT);
     128             : }
     129             : 
     130     9999454 : Handle<Object> JSReceiver::GetDataProperty(LookupIterator* it) {
     131     9413286 :   for (; it->IsFound(); it->Next()) {
     132     4654248 :     switch (it->state()) {
     133             :       case LookupIterator::INTERCEPTOR:
     134             :       case LookupIterator::NOT_FOUND:
     135             :       case LookupIterator::TRANSITION:
     136           0 :         UNREACHABLE();
     137             :       case LookupIterator::ACCESS_CHECK:
     138             :         // Support calling this method without an active context, but refuse
     139             :         // access to access-checked objects in that case.
     140      595567 :         if (!it->isolate()->context().is_null() && it->HasAccess()) continue;
     141             :         V8_FALLTHROUGH;
     142             :       case LookupIterator::JSPROXY:
     143             :         it->NotFound();
     144        3008 :         return it->isolate()->factory()->undefined_value();
     145             :       case LookupIterator::ACCESSOR:
     146             :         // TODO(verwaest): For now this doesn't call into AccessorInfo, since
     147             :         // clients don't need it. Update once relevant.
     148             :         it->NotFound();
     149      529943 :         return it->isolate()->factory()->undefined_value();
     150             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     151           0 :         return it->isolate()->factory()->undefined_value();
     152             :       case LookupIterator::DATA:
     153     3526552 :         return it->GetDataValue();
     154             :     }
     155             :   }
     156       52395 :   return it->isolate()->factory()->undefined_value();
     157             : }
     158             : 
     159             : // static
     160        1286 : Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
     161             :                                             Handle<JSReceiver> object,
     162             :                                             Handle<Object> proto) {
     163        1286 :   PrototypeIterator iter(isolate, object, kStartAtReceiver);
     164             :   while (true) {
     165     3688852 :     if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
     166     3688744 :     if (iter.IsAtEnd()) return Just(false);
     167     3687952 :     if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
     168             :       return Just(true);
     169             :     }
     170             :   }
     171             : }
     172             : 
     173             : namespace {
     174             : 
     175         519 : bool HasExcludedProperty(
     176             :     const ScopedVector<Handle<Object>>* excluded_properties,
     177             :     Handle<Object> search_element) {
     178             :   // TODO(gsathya): Change this to be a hashtable.
     179        1590 :   for (int i = 0; i < excluded_properties->length(); i++) {
     180        1689 :     if (search_element->SameValue(*excluded_properties->at(i))) {
     181             :       return true;
     182             :     }
     183             :   }
     184             : 
     185             :   return false;
     186             : }
     187             : 
     188         761 : V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
     189             :     Handle<JSReceiver> target, Handle<Object> source,
     190             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
     191             :   // Non-empty strings are the only non-JSReceivers that need to be handled
     192             :   // explicitly by Object.assign.
     193        1522 :   if (!source->IsJSReceiver()) {
     194          36 :     return Just(!source->IsString() || String::cast(*source)->length() == 0);
     195             :   }
     196             : 
     197             :   // If the target is deprecated, the object will be updated on first store. If
     198             :   // the source for that store equals the target, this will invalidate the
     199             :   // cached representation of the source. Preventively upgrade the target.
     200             :   // Do this on each iteration since any property load could cause deprecation.
     201         752 :   if (target->map()->is_deprecated()) {
     202          18 :     JSObject::MigrateInstance(Handle<JSObject>::cast(target));
     203             :   }
     204             : 
     205             :   Isolate* isolate = target->GetIsolate();
     206             :   Handle<Map> map(JSReceiver::cast(*source)->map(), isolate);
     207             : 
     208         752 :   if (!map->IsJSObjectMap()) return Just(false);
     209         635 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
     210             : 
     211         446 :   Handle<JSObject> from = Handle<JSObject>::cast(source);
     212         892 :   if (from->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
     213             :     return Just(false);
     214             :   }
     215             : 
     216         694 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
     217             :   int length = map->NumberOfOwnDescriptors();
     218             : 
     219             :   bool stable = true;
     220             : 
     221         866 :   for (int i = 0; i < length; i++) {
     222        1038 :     Handle<Name> next_key(descriptors->GetKey(i), isolate);
     223             :     Handle<Object> prop_value;
     224             :     // Directly decode from the descriptor array if |from| did not change shape.
     225         519 :     if (stable) {
     226         519 :       PropertyDetails details = descriptors->GetDetails(i);
     227         519 :       if (!details.IsEnumerable()) continue;
     228         492 :       if (details.kind() == kData) {
     229         492 :         if (details.location() == kDescriptor) {
     230           0 :           prop_value = handle(descriptors->GetStrongValue(i), isolate);
     231             :         } else {
     232         492 :           Representation representation = details.representation();
     233         492 :           FieldIndex index = FieldIndex::ForDescriptor(*map, i);
     234         492 :           prop_value = JSObject::FastPropertyAt(from, representation, index);
     235             :         }
     236             :       } else {
     237           0 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     238             :             isolate, prop_value,
     239             :             JSReceiver::GetProperty(isolate, from, next_key), Nothing<bool>());
     240             :         stable = from->map() == *map;
     241             :       }
     242             :     } else {
     243             :       // If the map did change, do a slower lookup. We are still guaranteed that
     244             :       // the object has a simple shape, and that the key is a name.
     245             :       LookupIterator it(from, next_key, from,
     246           0 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
     247           0 :       if (!it.IsFound()) continue;
     248             :       DCHECK(it.state() == LookupIterator::DATA ||
     249             :              it.state() == LookupIterator::ACCESSOR);
     250           0 :       if (!it.IsEnumerable()) continue;
     251           0 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     252             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
     253             :     }
     254             : 
     255         492 :     if (use_set) {
     256          36 :       LookupIterator it(target, next_key, target);
     257             :       Maybe<bool> result =
     258             :           Object::SetProperty(&it, prop_value, StoreOrigin::kNamed,
     259          36 :                               Just(ShouldThrow::kThrowOnError));
     260          36 :       if (result.IsNothing()) return result;
     261          36 :       if (stable) stable = from->map() == *map;
     262             :     } else {
     263        1368 :       if (excluded_properties != nullptr &&
     264        1080 :           HasExcludedProperty(excluded_properties, next_key)) {
     265          99 :         continue;
     266             :       }
     267             : 
     268             :       // 4a ii 2. Perform ? CreateDataProperty(target, nextKey, propValue).
     269             :       bool success;
     270             :       LookupIterator it = LookupIterator::PropertyOrElement(
     271         357 :           isolate, target, next_key, &success, LookupIterator::OWN);
     272         357 :       CHECK(success);
     273         714 :       CHECK(JSObject::CreateDataProperty(&it, prop_value, Just(kThrowOnError))
     274             :                 .FromJust());
     275             :     }
     276             :   }
     277             : 
     278             :   return Just(true);
     279             : }
     280             : }  // namespace
     281             : 
     282             : // static
     283         761 : Maybe<bool> JSReceiver::SetOrCopyDataProperties(
     284             :     Isolate* isolate, Handle<JSReceiver> target, Handle<Object> source,
     285             :     const ScopedVector<Handle<Object>>* excluded_properties, bool use_set) {
     286             :   Maybe<bool> fast_assign =
     287         761 :       FastAssign(target, source, excluded_properties, use_set);
     288         761 :   if (fast_assign.IsNothing()) return Nothing<bool>();
     289         761 :   if (fast_assign.FromJust()) return Just(true);
     290             : 
     291         828 :   Handle<JSReceiver> from = Object::ToObject(isolate, source).ToHandleChecked();
     292             :   // 3b. Let keys be ? from.[[OwnPropertyKeys]]().
     293             :   Handle<FixedArray> keys;
     294         828 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     295             :       isolate, keys,
     296             :       KeyAccumulator::GetKeys(from, KeyCollectionMode::kOwnOnly, ALL_PROPERTIES,
     297             :                               GetKeysConversion::kKeepNumbers),
     298             :       Nothing<bool>());
     299             : 
     300             :   // 4. Repeat for each element nextKey of keys in List order,
     301        3868 :   for (int j = 0; j < keys->length(); ++j) {
     302             :     Handle<Object> next_key(keys->get(j), isolate);
     303             :     // 4a i. Let desc be ? from.[[GetOwnProperty]](nextKey).
     304             :     PropertyDescriptor desc;
     305             :     Maybe<bool> found =
     306        1817 :         JSReceiver::GetOwnPropertyDescriptor(isolate, from, next_key, &desc);
     307        1880 :     if (found.IsNothing()) return Nothing<bool>();
     308             :     // 4a ii. If desc is not undefined and desc.[[Enumerable]] is true, then
     309        3562 :     if (found.FromJust() && desc.enumerable()) {
     310             :       // 4a ii 1. Let propValue be ? Get(from, nextKey).
     311             :       Handle<Object> prop_value;
     312        2295 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     313             :           isolate, prop_value,
     314             :           Runtime::GetObjectProperty(isolate, from, next_key), Nothing<bool>());
     315             : 
     316        1107 :       if (use_set) {
     317             :         // 4c ii 2. Let status be ? Set(to, nextKey, propValue, true).
     318             :         Handle<Object> status;
     319        1440 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
     320             :             isolate, status,
     321             :             Runtime::SetObjectProperty(isolate, target, next_key, prop_value,
     322             :                                        StoreOrigin::kMaybeKeyed,
     323             :                                        Just(ShouldThrow::kThrowOnError)),
     324             :             Nothing<bool>());
     325             :       } else {
     326         594 :         if (excluded_properties != nullptr &&
     327         207 :             HasExcludedProperty(excluded_properties, next_key)) {
     328          72 :           continue;
     329             :         }
     330             : 
     331             :         // 4a ii 2. Perform ! CreateDataProperty(target, nextKey, propValue).
     332             :         bool success;
     333             :         LookupIterator it = LookupIterator::PropertyOrElement(
     334         315 :             isolate, target, next_key, &success, LookupIterator::OWN);
     335         315 :         CHECK(success);
     336         630 :         CHECK(JSObject::CreateDataProperty(&it, prop_value, Just(kThrowOnError))
     337             :                   .FromJust());
     338             :       }
     339             :     }
     340             :   }
     341             : 
     342             :   return Just(true);
     343             : }
     344             : 
     345      875184 : String JSReceiver::class_name() {
     346      875184 :   ReadOnlyRoots roots = GetReadOnlyRoots();
     347      875184 :   if (IsFunction()) return roots.Function_string();
     348      875179 :   if (IsJSArgumentsObject()) return roots.Arguments_string();
     349      875179 :   if (IsJSArray()) return roots.Array_string();
     350      871313 :   if (IsJSArrayBuffer()) {
     351           0 :     if (JSArrayBuffer::cast(*this)->is_shared()) {
     352             :       return roots.SharedArrayBuffer_string();
     353             :     }
     354             :     return roots.ArrayBuffer_string();
     355             :   }
     356      871313 :   if (IsJSArrayIterator()) return roots.ArrayIterator_string();
     357      871313 :   if (IsJSDate()) return roots.Date_string();
     358      871304 :   if (IsJSError()) return roots.Error_string();
     359      871304 :   if (IsJSGeneratorObject()) return roots.Generator_string();
     360      871304 :   if (IsJSMap()) return roots.Map_string();
     361      871304 :   if (IsJSMapIterator()) return roots.MapIterator_string();
     362      871304 :   if (IsJSProxy()) {
     363             :     return map()->is_callable() ? roots.Function_string()
     364        1111 :                                 : roots.Object_string();
     365             :   }
     366      870193 :   if (IsJSRegExp()) return roots.RegExp_string();
     367      869779 :   if (IsJSSet()) return roots.Set_string();
     368      869779 :   if (IsJSSetIterator()) return roots.SetIterator_string();
     369      869779 :   if (IsJSTypedArray()) {
     370             : #define SWITCH_KIND(Type, type, TYPE, ctype)       \
     371             :   if (map()->elements_kind() == TYPE##_ELEMENTS) { \
     372             :     return roots.Type##Array_string();             \
     373             :   }
     374        4266 :     TYPED_ARRAYS(SWITCH_KIND)
     375             : #undef SWITCH_KIND
     376             :   }
     377      869068 :   if (IsJSValue()) {
     378        2639 :     Object value = JSValue::cast(*this)->value();
     379        2639 :     if (value->IsBoolean()) return roots.Boolean_string();
     380        1808 :     if (value->IsString()) return roots.String_string();
     381         869 :     if (value->IsNumber()) return roots.Number_string();
     382          10 :     if (value->IsBigInt()) return roots.BigInt_string();
     383          10 :     if (value->IsSymbol()) return roots.Symbol_string();
     384           0 :     if (value->IsScript()) return roots.Script_string();
     385           0 :     UNREACHABLE();
     386             :   }
     387      866429 :   if (IsJSWeakMap()) return roots.WeakMap_string();
     388      866429 :   if (IsJSWeakSet()) return roots.WeakSet_string();
     389      866429 :   if (IsJSGlobalProxy()) return roots.global_string();
     390             : 
     391      813239 :   Object maybe_constructor = map()->GetConstructor();
     392      813239 :   if (maybe_constructor->IsJSFunction()) {
     393      813107 :     JSFunction constructor = JSFunction::cast(maybe_constructor);
     394      813107 :     if (constructor->shared()->IsApiFunction()) {
     395        3355 :       maybe_constructor = constructor->shared()->get_api_func_data();
     396             :     }
     397             :   }
     398             : 
     399      813239 :   if (maybe_constructor->IsFunctionTemplateInfo()) {
     400             :     FunctionTemplateInfo info = FunctionTemplateInfo::cast(maybe_constructor);
     401        6712 :     if (info->class_name()->IsString()) return String::cast(info->class_name());
     402             :   }
     403             : 
     404             :   return roots.Object_string();
     405             : }
     406             : 
     407             : namespace {
     408     3920308 : std::pair<MaybeHandle<JSFunction>, Handle<String>> GetConstructorHelper(
     409             :     Handle<JSReceiver> receiver) {
     410             :   Isolate* isolate = receiver->GetIsolate();
     411             : 
     412             :   // If the object was instantiated simply with base == new.target, the
     413             :   // constructor on the map provides the most accurate name.
     414             :   // Don't provide the info for prototypes, since their constructors are
     415             :   // reclaimed and replaced by Object in OptimizeAsPrototype.
     416    15680589 :   if (!receiver->IsJSProxy() && receiver->map()->new_target_is_base() &&
     417             :       !receiver->map()->is_prototype_map()) {
     418     3749853 :     Object maybe_constructor = receiver->map()->GetConstructor();
     419     3749853 :     if (maybe_constructor->IsJSFunction()) {
     420     3511203 :       JSFunction constructor = JSFunction::cast(maybe_constructor);
     421     3511203 :       String name = constructor->shared()->DebugName();
     422     6428092 :       if (name->length() != 0 &&
     423     2916889 :           !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
     424             :         return std::make_pair(handle(constructor, isolate),
     425     2036135 :                               handle(name, isolate));
     426             :       }
     427      238650 :     } else if (maybe_constructor->IsFunctionTemplateInfo()) {
     428             :       FunctionTemplateInfo info = FunctionTemplateInfo::cast(maybe_constructor);
     429           0 :       if (info->class_name()->IsString()) {
     430             :         return std::make_pair(
     431             :             MaybeHandle<JSFunction>(),
     432             :             handle(String::cast(info->class_name()), isolate));
     433             :       }
     434             :     }
     435             :   }
     436             : 
     437             :   Handle<Object> maybe_tag = JSReceiver::GetDataProperty(
     438     1884173 :       receiver, isolate->factory()->to_string_tag_symbol());
     439     3768346 :   if (maybe_tag->IsString())
     440             :     return std::make_pair(MaybeHandle<JSFunction>(),
     441     1427238 :                           Handle<String>::cast(maybe_tag));
     442             : 
     443     1170554 :   PrototypeIterator iter(isolate, receiver);
     444     1170554 :   if (iter.IsAtEnd()) {
     445             :     return std::make_pair(MaybeHandle<JSFunction>(),
     446      952972 :                           handle(receiver->class_name(), isolate));
     447             :   }
     448             : 
     449      694068 :   Handle<JSReceiver> start = PrototypeIterator::GetCurrent<JSReceiver>(iter);
     450             :   LookupIterator it(receiver, isolate->factory()->constructor_string(), start,
     451      694068 :                     LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
     452      694068 :   Handle<Object> maybe_constructor = JSReceiver::GetDataProperty(&it);
     453     1388136 :   if (maybe_constructor->IsJSFunction()) {
     454      694068 :     JSFunction constructor = JSFunction::cast(*maybe_constructor);
     455      694068 :     String name = constructor->shared()->DebugName();
     456             : 
     457     1335384 :     if (name->length() != 0 &&
     458      641316 :         !name->Equals(ReadOnlyRoots(isolate).Object_string())) {
     459             :       return std::make_pair(handle(constructor, isolate),
     460      307207 :                             handle(name, isolate));
     461             :     }
     462             :   }
     463             : 
     464             :   return std::make_pair(MaybeHandle<JSFunction>(),
     465      773722 :                         handle(receiver->class_name(), isolate));
     466             : }
     467             : }  // anonymous namespace
     468             : 
     469             : // static
     470      141454 : MaybeHandle<JSFunction> JSReceiver::GetConstructor(
     471             :     Handle<JSReceiver> receiver) {
     472      141454 :   return GetConstructorHelper(receiver).first;
     473             : }
     474             : 
     475             : // static
     476     3778854 : Handle<String> JSReceiver::GetConstructorName(Handle<JSReceiver> receiver) {
     477     3778854 :   return GetConstructorHelper(receiver).second;
     478             : }
     479             : 
     480      401190 : Handle<NativeContext> JSReceiver::GetCreationContext() {
     481      401190 :   JSReceiver receiver = *this;
     482             :   // Externals are JSObjects with null as a constructor.
     483             :   DCHECK(!receiver->IsExternal(GetIsolate()));
     484      401190 :   Object constructor = receiver->map()->GetConstructor();
     485      401190 :   JSFunction function;
     486      401190 :   if (constructor->IsJSFunction()) {
     487      195194 :     function = JSFunction::cast(constructor);
     488      205996 :   } else if (constructor->IsFunctionTemplateInfo()) {
     489             :     // Remote objects don't have a creation context.
     490           2 :     return Handle<NativeContext>::null();
     491      205994 :   } else if (receiver->IsJSGeneratorObject()) {
     492           0 :     function = JSGeneratorObject::cast(receiver)->function();
     493             :   } else {
     494             :     // Functions have null as a constructor,
     495             :     // but any JSFunction knows its context immediately.
     496      205994 :     CHECK(receiver->IsJSFunction());
     497      205994 :     function = JSFunction::cast(receiver);
     498             :   }
     499             : 
     500      401188 :   return function->has_context()
     501             :              ? Handle<NativeContext>(function->context()->native_context(),
     502             :                                      receiver->GetIsolate())
     503      802376 :              : Handle<NativeContext>::null();
     504             : }
     505             : 
     506             : // static
     507        3387 : MaybeHandle<NativeContext> JSReceiver::GetFunctionRealm(
     508             :     Handle<JSReceiver> receiver) {
     509        6774 :   if (receiver->IsJSProxy()) {
     510          36 :     return JSProxy::GetFunctionRealm(Handle<JSProxy>::cast(receiver));
     511             :   }
     512             : 
     513        6702 :   if (receiver->IsJSFunction()) {
     514        3342 :     return JSFunction::GetFunctionRealm(Handle<JSFunction>::cast(receiver));
     515             :   }
     516             : 
     517          18 :   if (receiver->IsJSBoundFunction()) {
     518             :     return JSBoundFunction::GetFunctionRealm(
     519           9 :         Handle<JSBoundFunction>::cast(receiver));
     520             :   }
     521             : 
     522           0 :   return JSObject::GetFunctionRealm(Handle<JSObject>::cast(receiver));
     523             : }
     524             : 
     525    16626688 : Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
     526    18926932 :     LookupIterator* it) {
     527    37853865 :   for (; it->IsFound(); it->Next()) {
     528    12173200 :     switch (it->state()) {
     529             :       case LookupIterator::NOT_FOUND:
     530             :       case LookupIterator::TRANSITION:
     531           0 :         UNREACHABLE();
     532             :       case LookupIterator::JSPROXY:
     533         909 :         return JSProxy::GetPropertyAttributes(it);
     534             :       case LookupIterator::INTERCEPTOR: {
     535             :         Maybe<PropertyAttributes> result =
     536         677 :             JSObject::GetPropertyAttributesWithInterceptor(it);
     537        1031 :         if (result.IsNothing()) return result;
     538         677 :         if (result.FromJust() != ABSENT) return result;
     539         323 :         break;
     540             :       }
     541             :       case LookupIterator::ACCESS_CHECK:
     542     2300003 :         if (it->HasAccess()) break;
     543          81 :         return JSObject::GetPropertyAttributesWithFailedAccessCheck(it);
     544             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     545             :         return Just(ABSENT);
     546             :       case LookupIterator::ACCESSOR:
     547      427502 :         if (it->GetHolder<Object>()->IsJSModuleNamespace()) {
     548         792 :           return JSModuleNamespace::GetPropertyAttributes(it);
     549             :         } else {
     550             :           return Just(it->property_attributes());
     551             :         }
     552             :       case LookupIterator::DATA:
     553             :         return Just(it->property_attributes());
     554             :     }
     555             :   }
     556             :   return Just(ABSENT);
     557             : }
     558             : 
     559             : namespace {
     560             : 
     561       39105 : Object SetHashAndUpdateProperties(HeapObject properties, int hash) {
     562             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
     563             :   DCHECK(PropertyArray::HashField::is_valid(hash));
     564             : 
     565       39105 :   ReadOnlyRoots roots = properties->GetReadOnlyRoots();
     566       44851 :   if (properties == roots.empty_fixed_array() ||
     567       44841 :       properties == roots.empty_property_array() ||
     568             :       properties == roots.empty_property_dictionary()) {
     569       33747 :     return Smi::FromInt(hash);
     570             :   }
     571             : 
     572        5358 :   if (properties->IsPropertyArray()) {
     573         156 :     PropertyArray::cast(properties)->SetHash(hash);
     574             :     DCHECK_LT(0, PropertyArray::cast(properties)->length());
     575         156 :     return properties;
     576             :   }
     577             : 
     578        5202 :   if (properties->IsGlobalDictionary()) {
     579             :     GlobalDictionary::cast(properties)->SetHash(hash);
     580           0 :     return properties;
     581             :   }
     582             : 
     583             :   DCHECK(properties->IsNameDictionary());
     584             :   NameDictionary::cast(properties)->SetHash(hash);
     585        5202 :   return properties;
     586             : }
     587             : 
     588    36095701 : int GetIdentityHashHelper(JSReceiver object) {
     589             :   DisallowHeapAllocation no_gc;
     590    36095701 :   Object properties = object->raw_properties_or_hash();
     591    36095703 :   if (properties->IsSmi()) {
     592       39269 :     return Smi::ToInt(properties);
     593             :   }
     594             : 
     595    36056435 :   if (properties->IsPropertyArray()) {
     596    15686770 :     return PropertyArray::cast(properties)->Hash();
     597             :   }
     598             : 
     599    20369665 :   if (properties->IsNameDictionary()) {
     600     2758130 :     return NameDictionary::cast(properties)->Hash();
     601             :   }
     602             : 
     603    17611534 :   if (properties->IsGlobalDictionary()) {
     604     8146912 :     return GlobalDictionary::cast(properties)->Hash();
     605             :   }
     606             : 
     607             : #ifdef DEBUG
     608             :   ReadOnlyRoots roots = object->GetReadOnlyRoots();
     609             :   DCHECK(properties == roots.empty_fixed_array() ||
     610             :          properties == roots.empty_property_dictionary());
     611             : #endif
     612             : 
     613             :   return PropertyArray::kNoHashSentinel;
     614             : }
     615             : }  // namespace
     616             : 
     617       33817 : void JSReceiver::SetIdentityHash(int hash) {
     618             :   DisallowHeapAllocation no_gc;
     619             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
     620             :   DCHECK(PropertyArray::HashField::is_valid(hash));
     621             : 
     622       33817 :   HeapObject existing_properties = HeapObject::cast(raw_properties_or_hash());
     623       33817 :   Object new_properties = SetHashAndUpdateProperties(existing_properties, hash);
     624       33817 :   set_raw_properties_or_hash(new_properties);
     625       33817 : }
     626             : 
     627    36033025 : void JSReceiver::SetProperties(HeapObject properties) {
     628             :   DCHECK_IMPLIES(properties->IsPropertyArray() &&
     629             :                      PropertyArray::cast(properties)->length() == 0,
     630             :                  properties == GetReadOnlyRoots().empty_property_array());
     631             :   DisallowHeapAllocation no_gc;
     632    36033025 :   int hash = GetIdentityHashHelper(*this);
     633    36033024 :   Object new_properties = properties;
     634             : 
     635             :   // TODO(cbruni): Make GetIdentityHashHelper return a bool so that we
     636             :   // don't have to manually compare against kNoHashSentinel.
     637    36033024 :   if (hash != PropertyArray::kNoHashSentinel) {
     638        5288 :     new_properties = SetHashAndUpdateProperties(properties, hash);
     639             :   }
     640             : 
     641    36033024 :   set_raw_properties_or_hash(new_properties);
     642    36033032 : }
     643             : 
     644       41122 : Object JSReceiver::GetIdentityHash() {
     645             :   DisallowHeapAllocation no_gc;
     646             : 
     647       41122 :   int hash = GetIdentityHashHelper(*this);
     648       41122 :   if (hash == PropertyArray::kNoHashSentinel) {
     649        4506 :     return GetReadOnlyRoots().undefined_value();
     650             :   }
     651             : 
     652       38869 :   return Smi::FromInt(hash);
     653             : }
     654             : 
     655             : // static
     656       33782 : Smi JSReceiver::CreateIdentityHash(Isolate* isolate, JSReceiver key) {
     657             :   DisallowHeapAllocation no_gc;
     658       33782 :   int hash = isolate->GenerateIdentityHash(PropertyArray::HashField::kMax);
     659             :   DCHECK_NE(PropertyArray::kNoHashSentinel, hash);
     660             : 
     661       33782 :   key->SetIdentityHash(hash);
     662       33782 :   return Smi::FromInt(hash);
     663             : }
     664             : 
     665       21554 : Smi JSReceiver::GetOrCreateIdentityHash(Isolate* isolate) {
     666             :   DisallowHeapAllocation no_gc;
     667             : 
     668       21554 :   int hash = GetIdentityHashHelper(*this);
     669       21554 :   if (hash != PropertyArray::kNoHashSentinel) {
     670             :     return Smi::FromInt(hash);
     671             :   }
     672             : 
     673       21044 :   return JSReceiver::CreateIdentityHash(isolate, *this);
     674             : }
     675             : 
     676       54257 : void JSReceiver::DeleteNormalizedProperty(Handle<JSReceiver> object,
     677             :                                           int entry) {
     678             :   DCHECK(!object->HasFastProperties());
     679             :   Isolate* isolate = object->GetIsolate();
     680             : 
     681      108514 :   if (object->IsJSGlobalObject()) {
     682             :     // If we have a global object, invalidate the cell and swap in a new one.
     683             :     Handle<GlobalDictionary> dictionary(
     684       22566 :         JSGlobalObject::cast(*object)->global_dictionary(), isolate);
     685             :     DCHECK_NE(GlobalDictionary::kNotFound, entry);
     686             : 
     687       11283 :     auto cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
     688       22566 :     cell->set_value(ReadOnlyRoots(isolate).the_hole_value());
     689             :     cell->set_property_details(
     690       22566 :         PropertyDetails::Empty(PropertyCellType::kUninitialized));
     691             :   } else {
     692       85948 :     Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
     693             :     DCHECK_NE(NameDictionary::kNotFound, entry);
     694             : 
     695       42974 :     dictionary = NameDictionary::DeleteEntry(isolate, dictionary, entry);
     696       85948 :     object->SetProperties(*dictionary);
     697             :   }
     698       54257 :   if (object->map()->is_prototype_map()) {
     699             :     // Invalidate prototype validity cell as this may invalidate transitioning
     700             :     // store IC handlers.
     701             :     JSObject::InvalidatePrototypeChains(object->map());
     702             :   }
     703       54257 : }
     704             : 
     705    19147077 : Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it,
     706             :                                        LanguageMode language_mode) {
     707     6387922 :   it->UpdateProtector();
     708             : 
     709             :   Isolate* isolate = it->isolate();
     710             : 
     711     6387922 :   if (it->state() == LookupIterator::JSPROXY) {
     712             :     return JSProxy::DeletePropertyOrElement(it->GetHolder<JSProxy>(),
     713       53184 :                                             it->GetName(), language_mode);
     714             :   }
     715             : 
     716    12722660 :   if (it->GetReceiver()->IsJSProxy()) {
     717          39 :     if (it->state() != LookupIterator::NOT_FOUND) {
     718             :       DCHECK_EQ(LookupIterator::DATA, it->state());
     719             :       DCHECK(it->name()->IsPrivate());
     720           6 :       it->Delete();
     721             :     }
     722             :     return Just(true);
     723             :   }
     724     6361291 :   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
     725             : 
     726    12742388 :   for (; it->IsFound(); it->Next()) {
     727      170036 :     switch (it->state()) {
     728             :       case LookupIterator::JSPROXY:
     729             :       case LookupIterator::NOT_FOUND:
     730             :       case LookupIterator::TRANSITION:
     731           0 :         UNREACHABLE();
     732             :       case LookupIterator::ACCESS_CHECK:
     733        9863 :         if (it->HasAccess()) break;
     734          36 :         isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
     735          36 :         RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
     736             :         return Just(false);
     737             :       case LookupIterator::INTERCEPTOR: {
     738             :         ShouldThrow should_throw =
     739         100 :             is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
     740             :         Maybe<bool> result =
     741         100 :             JSObject::DeletePropertyWithInterceptor(it, should_throw);
     742             :         // An exception was thrown in the interceptor. Propagate.
     743         124 :         if (isolate->has_pending_exception()) return Nothing<bool>();
     744             :         // Delete with interceptor succeeded. Return result.
     745             :         // TODO(neis): In strict mode, we should probably throw if the
     746             :         // interceptor returns false.
     747         100 :         if (result.IsJust()) return result;
     748          76 :         break;
     749             :       }
     750             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     751             :         return Just(true);
     752             :       case LookupIterator::DATA:
     753             :       case LookupIterator::ACCESSOR: {
     754      160028 :         if (!it->IsConfigurable()) {
     755             :           // Fail if the property is not configurable.
     756        2476 :           if (is_strict(language_mode)) {
     757             :             isolate->Throw(*isolate->factory()->NewTypeError(
     758             :                 MessageTemplate::kStrictDeleteProperty, it->GetName(),
     759        2019 :                 receiver));
     760             :             return Nothing<bool>();
     761             :           }
     762             :           return Just(false);
     763             :         }
     764             : 
     765      157552 :         it->Delete();
     766             : 
     767             :         return Just(true);
     768             :       }
     769             :     }
     770             :   }
     771             : 
     772             :   return Just(true);
     773             : }
     774             : 
     775        1027 : Maybe<bool> JSReceiver::DeleteElement(Handle<JSReceiver> object, uint32_t index,
     776             :                                       LanguageMode language_mode) {
     777             :   LookupIterator it(object->GetIsolate(), object, index, object,
     778             :                     LookupIterator::OWN);
     779        1027 :   return DeleteProperty(&it, language_mode);
     780             : }
     781             : 
     782         891 : Maybe<bool> JSReceiver::DeleteProperty(Handle<JSReceiver> object,
     783             :                                        Handle<Name> name,
     784             :                                        LanguageMode language_mode) {
     785         891 :   LookupIterator it(object, name, object, LookupIterator::OWN);
     786         891 :   return DeleteProperty(&it, language_mode);
     787             : }
     788             : 
     789      621982 : Maybe<bool> JSReceiver::DeletePropertyOrElement(Handle<JSReceiver> object,
     790             :                                                 Handle<Name> name,
     791             :                                                 LanguageMode language_mode) {
     792             :   LookupIterator it = LookupIterator::PropertyOrElement(
     793      621982 :       object->GetIsolate(), object, name, object, LookupIterator::OWN);
     794      621982 :   return DeleteProperty(&it, language_mode);
     795             : }
     796             : 
     797             : // ES6 19.1.2.4
     798             : // static
     799      114533 : Object JSReceiver::DefineProperty(Isolate* isolate, Handle<Object> object,
     800             :                                   Handle<Object> key,
     801             :                                   Handle<Object> attributes) {
     802             :   // 1. If Type(O) is not Object, throw a TypeError exception.
     803      229066 :   if (!object->IsJSReceiver()) {
     804             :     Handle<String> fun_name =
     805          63 :         isolate->factory()->InternalizeUtf8String("Object.defineProperty");
     806         126 :     THROW_NEW_ERROR_RETURN_FAILURE(
     807             :         isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name));
     808             :   }
     809             :   // 2. Let key be ToPropertyKey(P).
     810             :   // 3. ReturnIfAbrupt(key).
     811      228940 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, key,
     812             :                                      Object::ToPropertyKey(isolate, key));
     813             :   // 4. Let desc be ToPropertyDescriptor(Attributes).
     814             :   // 5. ReturnIfAbrupt(desc).
     815             :   PropertyDescriptor desc;
     816      114470 :   if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) {
     817         135 :     return ReadOnlyRoots(isolate).exception();
     818             :   }
     819             :   // 6. Let success be DefinePropertyOrThrow(O,key, desc).
     820             :   Maybe<bool> success =
     821             :       DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object), key, &desc,
     822      114335 :                         Just(kThrowOnError));
     823             :   // 7. ReturnIfAbrupt(success).
     824      115371 :   MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception());
     825      113299 :   CHECK(success.FromJust());
     826             :   // 8. Return O.
     827             :   return *object;
     828             : }
     829             : 
     830             : // ES6 19.1.2.3.1
     831             : // static
     832        1829 : MaybeHandle<Object> JSReceiver::DefineProperties(Isolate* isolate,
     833             :                                                  Handle<Object> object,
     834             :                                                  Handle<Object> properties) {
     835             :   // 1. If Type(O) is not Object, throw a TypeError exception.
     836        3658 :   if (!object->IsJSReceiver()) {
     837             :     Handle<String> fun_name =
     838          27 :         isolate->factory()->InternalizeUtf8String("Object.defineProperties");
     839          27 :     THROW_NEW_ERROR(isolate,
     840             :                     NewTypeError(MessageTemplate::kCalledOnNonObject, fun_name),
     841             :                     Object);
     842             :   }
     843             :   // 2. Let props be ToObject(Properties).
     844             :   // 3. ReturnIfAbrupt(props).
     845             :   Handle<JSReceiver> props;
     846        3604 :   ASSIGN_RETURN_ON_EXCEPTION(isolate, props,
     847             :                              Object::ToObject(isolate, properties), Object);
     848             : 
     849             :   // 4. Let keys be props.[[OwnPropertyKeys]]().
     850             :   // 5. ReturnIfAbrupt(keys).
     851             :   Handle<FixedArray> keys;
     852        3586 :   ASSIGN_RETURN_ON_EXCEPTION(
     853             :       isolate, keys,
     854             :       KeyAccumulator::GetKeys(props, KeyCollectionMode::kOwnOnly,
     855             :                               ALL_PROPERTIES),
     856             :       Object);
     857             :   // 6. Let descriptors be an empty List.
     858             :   int capacity = keys->length();
     859        1793 :   std::vector<PropertyDescriptor> descriptors(capacity);
     860             :   size_t descriptors_index = 0;
     861             :   // 7. Repeat for each element nextKey of keys in List order,
     862       13584 :   for (int i = 0; i < keys->length(); ++i) {
     863             :     Handle<Object> next_key(keys->get(i), isolate);
     864             :     // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
     865             :     // 7b. ReturnIfAbrupt(propDesc).
     866        5224 :     bool success = false;
     867             :     LookupIterator it = LookupIterator::PropertyOrElement(
     868        5224 :         isolate, props, next_key, &success, LookupIterator::OWN);
     869             :     DCHECK(success);
     870        5224 :     Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
     871        5224 :     if (maybe.IsNothing()) return MaybeHandle<Object>();
     872             :     PropertyAttributes attrs = maybe.FromJust();
     873             :     // 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
     874        6348 :     if (attrs == ABSENT) continue;
     875        5224 :     if (attrs & DONT_ENUM) continue;
     876             :     // 7c i. Let descObj be Get(props, nextKey).
     877             :     // 7c ii. ReturnIfAbrupt(descObj).
     878             :     Handle<Object> desc_obj;
     879        8200 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, desc_obj, Object::GetProperty(&it),
     880             :                                Object);
     881             :     // 7c iii. Let desc be ToPropertyDescriptor(descObj).
     882             :     success = PropertyDescriptor::ToPropertyDescriptor(
     883        8200 :         isolate, desc_obj, &descriptors[descriptors_index]);
     884             :     // 7c iv. ReturnIfAbrupt(desc).
     885        4100 :     if (!success) return MaybeHandle<Object>();
     886             :     // 7c v. Append the pair (a two element List) consisting of nextKey and
     887             :     //       desc to the end of descriptors.
     888        3875 :     descriptors[descriptors_index].set_name(next_key);
     889        3875 :     descriptors_index++;
     890             :   }
     891             :   // 8. For each pair from descriptors in list order,
     892        3488 :   for (size_t i = 0; i < descriptors_index; ++i) {
     893        3488 :     PropertyDescriptor* desc = &descriptors[i];
     894             :     // 8a. Let P be the first element of pair.
     895             :     // 8b. Let desc be the second element of pair.
     896             :     // 8c. Let status be DefinePropertyOrThrow(O, P, desc).
     897             :     Maybe<bool> status =
     898             :         DefineOwnProperty(isolate, Handle<JSReceiver>::cast(object),
     899        3488 :                           desc->name(), desc, Just(kThrowOnError));
     900             :     // 8d. ReturnIfAbrupt(status).
     901        3488 :     if (status.IsNothing()) return MaybeHandle<Object>();
     902        3488 :     CHECK(status.FromJust());
     903             :   }
     904             :   // 9. Return o.
     905        1568 :   return object;
     906             : }
     907             : 
     908             : // static
     909      571718 : Maybe<bool> JSReceiver::DefineOwnProperty(Isolate* isolate,
     910             :                                           Handle<JSReceiver> object,
     911             :                                           Handle<Object> key,
     912             :                                           PropertyDescriptor* desc,
     913             :                                           Maybe<ShouldThrow> should_throw) {
     914     1143438 :   if (object->IsJSArray()) {
     915             :     return JSArray::DefineOwnProperty(isolate, Handle<JSArray>::cast(object),
     916       30314 :                                       key, desc, should_throw);
     917             :   }
     918     1082810 :   if (object->IsJSProxy()) {
     919             :     return JSProxy::DefineOwnProperty(isolate, Handle<JSProxy>::cast(object),
     920       41050 :                                       key, desc, should_throw);
     921             :   }
     922     1000710 :   if (object->IsJSTypedArray()) {
     923             :     return JSTypedArray::DefineOwnProperty(
     924        3610 :         isolate, Handle<JSTypedArray>::cast(object), key, desc, should_throw);
     925             :   }
     926             : 
     927             :   // OrdinaryDefineOwnProperty, by virtue of calling
     928             :   // DefineOwnPropertyIgnoreAttributes, can handle arguments
     929             :   // (ES#sec-arguments-exotic-objects-defineownproperty-p-desc).
     930             :   return OrdinaryDefineOwnProperty(isolate, Handle<JSObject>::cast(object), key,
     931      496745 :                                    desc, should_throw);
     932             : }
     933             : 
     934             : // static
     935      536316 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(
     936             :     Isolate* isolate, Handle<JSObject> object, Handle<Object> key,
     937             :     PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw) {
     938      536316 :   bool success = false;
     939             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
     940             :   LookupIterator it = LookupIterator::PropertyOrElement(
     941      536316 :       isolate, object, key, &success, LookupIterator::OWN);
     942             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
     943             : 
     944             :   // Deal with access checks first.
     945      536317 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
     946        2450 :     if (!it.HasAccess()) {
     947          30 :       isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>());
     948          30 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
     949             :       return Just(true);
     950             :     }
     951        2420 :     it.Next();
     952             :   }
     953             : 
     954      536287 :   return OrdinaryDefineOwnProperty(&it, desc, should_throw);
     955             : }
     956             : 
     957             : namespace {
     958             : 
     959      114273 : MaybeHandle<Object> GetPropertyWithInterceptorInternal(
     960      228426 :     LookupIterator* it, Handle<InterceptorInfo> interceptor, bool* done) {
     961      114273 :   *done = false;
     962             :   Isolate* isolate = it->isolate();
     963             :   // Make sure that the top context does not change when doing callbacks or
     964             :   // interceptor calls.
     965             :   AssertNoContextChange ncc(isolate);
     966             : 
     967      228546 :   if (interceptor->getter()->IsUndefined(isolate)) {
     968         120 :     return isolate->factory()->undefined_value();
     969             :   }
     970             : 
     971             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
     972             :   Handle<Object> result;
     973             :   Handle<Object> receiver = it->GetReceiver();
     974      228306 :   if (!receiver->IsJSReceiver()) {
     975          32 :     ASSIGN_RETURN_ON_EXCEPTION(
     976             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver), Object);
     977             :   }
     978             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
     979      114153 :                                  *holder, Just(kDontThrow));
     980             : 
     981      114153 :   if (it->IsElement()) {
     982        2350 :     result = args.CallIndexedGetter(interceptor, it->index());
     983             :   } else {
     984      111803 :     result = args.CallNamedGetter(interceptor, it->name());
     985             :   }
     986             : 
     987      114153 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
     988      224991 :   if (result.is_null()) return isolate->factory()->undefined_value();
     989        3259 :   *done = true;
     990             :   // Rebox handle before return
     991        3259 :   return handle(*result, isolate);
     992             : }
     993             : 
     994      250405 : Maybe<PropertyAttributes> GetPropertyAttributesWithInterceptorInternal(
     995      500690 :     LookupIterator* it, Handle<InterceptorInfo> interceptor) {
     996             :   Isolate* isolate = it->isolate();
     997             :   // Make sure that the top context does not change when doing
     998             :   // callbacks or interceptor calls.
     999             :   AssertNoContextChange ncc(isolate);
    1000             :   HandleScope scope(isolate);
    1001             : 
    1002             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1003             :   DCHECK_IMPLIES(!it->IsElement() && it->name()->IsSymbol(),
    1004             :                  interceptor->can_intercept_symbols());
    1005             :   Handle<Object> receiver = it->GetReceiver();
    1006      500810 :   if (!receiver->IsJSReceiver()) {
    1007          24 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1008             :                                      Object::ConvertReceiver(isolate, receiver),
    1009             :                                      Nothing<PropertyAttributes>());
    1010             :   }
    1011             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1012      250405 :                                  *holder, Just(kDontThrow));
    1013      500810 :   if (!interceptor->query()->IsUndefined(isolate)) {
    1014             :     Handle<Object> result;
    1015         555 :     if (it->IsElement()) {
    1016         315 :       result = args.CallIndexedQuery(interceptor, it->index());
    1017             :     } else {
    1018         240 :       result = args.CallNamedQuery(interceptor, it->name());
    1019             :     }
    1020         555 :     if (!result.is_null()) {
    1021             :       int32_t value;
    1022         365 :       CHECK(result->ToInt32(&value));
    1023         365 :       return Just(static_cast<PropertyAttributes>(value));
    1024             :     }
    1025      499700 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    1026             :     // TODO(verwaest): Use GetPropertyWithInterceptor?
    1027             :     Handle<Object> result;
    1028      249730 :     if (it->IsElement()) {
    1029      240203 :       result = args.CallIndexedGetter(interceptor, it->index());
    1030             :     } else {
    1031        9527 :       result = args.CallNamedGetter(interceptor, it->name());
    1032             :     }
    1033      249730 :     if (!result.is_null()) return Just(DONT_ENUM);
    1034             :   }
    1035             : 
    1036      240625 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    1037             :   return Just(ABSENT);
    1038             : }
    1039             : 
    1040      193298 : Maybe<bool> SetPropertyWithInterceptorInternal(
    1041      566266 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1042             :     Maybe<ShouldThrow> should_throw, Handle<Object> value) {
    1043             :   Isolate* isolate = it->isolate();
    1044             :   // Make sure that the top context does not change when doing callbacks or
    1045             :   // interceptor calls.
    1046             :   AssertNoContextChange ncc(isolate);
    1047             : 
    1048      386596 :   if (interceptor->setter()->IsUndefined(isolate)) return Just(false);
    1049             : 
    1050             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1051             :   bool result;
    1052             :   Handle<Object> receiver = it->GetReceiver();
    1053      372968 :   if (!receiver->IsJSReceiver()) {
    1054           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1055             :                                      Object::ConvertReceiver(isolate, receiver),
    1056             :                                      Nothing<bool>());
    1057             :   }
    1058             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1059      186484 :                                  *holder, should_throw);
    1060             : 
    1061      186484 :   if (it->IsElement()) {
    1062             :     // TODO(neis): In the future, we may want to actually return the
    1063             :     // interceptor's result, which then should be a boolean.
    1064      131338 :     result = !args.CallIndexedSetter(interceptor, it->index(), value).is_null();
    1065             :   } else {
    1066      241630 :     result = !args.CallNamedSetter(interceptor, it->name(), value).is_null();
    1067             :   }
    1068             : 
    1069      186484 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1070             :   return Just(result);
    1071             : }
    1072             : 
    1073         183 : Maybe<bool> DefinePropertyWithInterceptorInternal(
    1074         357 :     LookupIterator* it, Handle<InterceptorInfo> interceptor,
    1075             :     Maybe<ShouldThrow> should_throw, PropertyDescriptor& desc) {
    1076             :   Isolate* isolate = it->isolate();
    1077             :   // Make sure that the top context does not change when doing callbacks or
    1078             :   // interceptor calls.
    1079             :   AssertNoContextChange ncc(isolate);
    1080             : 
    1081         366 :   if (interceptor->definer()->IsUndefined(isolate)) return Just(false);
    1082             : 
    1083             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1084             :   bool result;
    1085             :   Handle<Object> receiver = it->GetReceiver();
    1086         174 :   if (!receiver->IsJSReceiver()) {
    1087           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1088             :                                      Object::ConvertReceiver(isolate, receiver),
    1089             :                                      Nothing<bool>());
    1090             :   }
    1091             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1092          87 :                                  *holder, should_throw);
    1093             : 
    1094             :   std::unique_ptr<v8::PropertyDescriptor> descriptor(
    1095          87 :       new v8::PropertyDescriptor());
    1096          87 :   if (PropertyDescriptor::IsAccessorDescriptor(&desc)) {
    1097             :     descriptor.reset(new v8::PropertyDescriptor(
    1098          66 :         v8::Utils::ToLocal(desc.get()), v8::Utils::ToLocal(desc.set())));
    1099          54 :   } else if (PropertyDescriptor::IsDataDescriptor(&desc)) {
    1100          44 :     if (desc.has_writable()) {
    1101             :       descriptor.reset(new v8::PropertyDescriptor(
    1102          18 :           v8::Utils::ToLocal(desc.value()), desc.writable()));
    1103             :     } else {
    1104             :       descriptor.reset(
    1105          76 :           new v8::PropertyDescriptor(v8::Utils::ToLocal(desc.value())));
    1106             :     }
    1107             :   }
    1108          87 :   if (desc.has_enumerable()) {
    1109          12 :     descriptor->set_enumerable(desc.enumerable());
    1110             :   }
    1111          87 :   if (desc.has_configurable()) {
    1112          12 :     descriptor->set_configurable(desc.configurable());
    1113             :   }
    1114             : 
    1115          87 :   if (it->IsElement()) {
    1116             :     result = !args.CallIndexedDefiner(interceptor, it->index(), *descriptor)
    1117          48 :                   .is_null();
    1118             :   } else {
    1119             :     result =
    1120         126 :         !args.CallNamedDefiner(interceptor, it->name(), *descriptor).is_null();
    1121             :   }
    1122             : 
    1123          87 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    1124             :   return Just(result);
    1125             : }
    1126             : 
    1127             : }  // namespace
    1128             : 
    1129             : // ES6 9.1.6.1
    1130             : // static
    1131      536285 : Maybe<bool> JSReceiver::OrdinaryDefineOwnProperty(
    1132     1259893 :     LookupIterator* it, PropertyDescriptor* desc,
    1133             :     Maybe<ShouldThrow> should_throw) {
    1134             :   Isolate* isolate = it->isolate();
    1135             :   // 1. Let current be O.[[GetOwnProperty]](P).
    1136             :   // 2. ReturnIfAbrupt(current).
    1137             :   PropertyDescriptor current;
    1138      536285 :   MAYBE_RETURN(GetOwnPropertyDescriptor(it, &current), Nothing<bool>());
    1139             : 
    1140      536269 :   it->Restart();
    1141             :   // Handle interceptor
    1142     1447219 :   for (; it->IsFound(); it->Next()) {
    1143      187395 :     if (it->state() == LookupIterator::INTERCEPTOR) {
    1144         183 :       if (it->HolderIsReceiverOrHiddenPrototype()) {
    1145             :         Maybe<bool> result = DefinePropertyWithInterceptorInternal(
    1146         183 :             it, it->GetInterceptor(), should_throw, *desc);
    1147         366 :         if (result.IsNothing() || result.FromJust()) {
    1148          54 :           return result;
    1149             :         }
    1150             :       }
    1151             :     }
    1152             :   }
    1153             : 
    1154             :   // TODO(jkummerow/verwaest): It would be nice if we didn't have to reset
    1155             :   // the iterator every time. Currently, the reasons why we need it are:
    1156             :   // - handle interceptors correctly
    1157             :   // - handle accessors correctly (which might change the holder's map)
    1158      536213 :   it->Restart();
    1159             :   // 3. Let extensible be the value of the [[Extensible]] internal slot of O.
    1160      536214 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    1161      536215 :   bool extensible = JSObject::IsExtensible(object);
    1162             : 
    1163             :   return ValidateAndApplyPropertyDescriptor(
    1164      536216 :       isolate, it, extensible, desc, &current, should_throw, Handle<Name>());
    1165             : }
    1166             : 
    1167             : // ES6 9.1.6.2
    1168             : // static
    1169        4608 : Maybe<bool> JSReceiver::IsCompatiblePropertyDescriptor(
    1170             :     Isolate* isolate, bool extensible, PropertyDescriptor* desc,
    1171             :     PropertyDescriptor* current, Handle<Name> property_name,
    1172             :     Maybe<ShouldThrow> should_throw) {
    1173             :   // 1. Return ValidateAndApplyPropertyDescriptor(undefined, undefined,
    1174             :   //    Extensible, Desc, Current).
    1175             :   return ValidateAndApplyPropertyDescriptor(
    1176        4608 :       isolate, nullptr, extensible, desc, current, should_throw, property_name);
    1177             : }
    1178             : 
    1179             : // ES6 9.1.6.3
    1180             : // static
    1181      540824 : Maybe<bool> JSReceiver::ValidateAndApplyPropertyDescriptor(
    1182             :     Isolate* isolate, LookupIterator* it, bool extensible,
    1183             :     PropertyDescriptor* desc, PropertyDescriptor* current,
    1184             :     Maybe<ShouldThrow> should_throw, Handle<Name> property_name) {
    1185             :   // We either need a LookupIterator, or a property name.
    1186             :   DCHECK((it == nullptr) != property_name.is_null());
    1187             :   Handle<JSObject> object;
    1188      540824 :   if (it != nullptr) object = Handle<JSObject>::cast(it->GetReceiver());
    1189             :   bool desc_is_data_descriptor = PropertyDescriptor::IsDataDescriptor(desc);
    1190             :   bool desc_is_accessor_descriptor =
    1191             :       PropertyDescriptor::IsAccessorDescriptor(desc);
    1192             :   bool desc_is_generic_descriptor =
    1193             :       PropertyDescriptor::IsGenericDescriptor(desc);
    1194             :   // 1. (Assert)
    1195             :   // 2. If current is undefined, then
    1196      540823 :   if (current->is_empty()) {
    1197             :     // 2a. If extensible is false, return false.
    1198      354119 :     if (!extensible) {
    1199         258 :       RETURN_FAILURE(
    1200             :           isolate, GetShouldThrow(isolate, should_throw),
    1201             :           NewTypeError(MessageTemplate::kDefineDisallowed,
    1202             :                        it != nullptr ? it->GetName() : property_name));
    1203             :     }
    1204             :     // 2c. If IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true, then:
    1205             :     // (This is equivalent to !IsAccessorDescriptor(desc).)
    1206             :     DCHECK((desc_is_generic_descriptor || desc_is_data_descriptor) ==
    1207             :            !desc_is_accessor_descriptor);
    1208      354020 :     if (!desc_is_accessor_descriptor) {
    1209             :       // 2c i. If O is not undefined, create an own data property named P of
    1210             :       // object O whose [[Value]], [[Writable]], [[Enumerable]] and
    1211             :       // [[Configurable]] attribute values are described by Desc. If the value
    1212             :       // of an attribute field of Desc is absent, the attribute of the newly
    1213             :       // created property is set to its default value.
    1214      285986 :       if (it != nullptr) {
    1215      283431 :         if (!desc->has_writable()) desc->set_writable(false);
    1216      283431 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    1217      283431 :         if (!desc->has_configurable()) desc->set_configurable(false);
    1218             :         Handle<Object> value(
    1219             :             desc->has_value()
    1220             :                 ? desc->value()
    1221      292942 :                 : Handle<Object>::cast(isolate->factory()->undefined_value()));
    1222             :         MaybeHandle<Object> result =
    1223             :             JSObject::DefineOwnPropertyIgnoreAttributes(it, value,
    1224      283431 :                                                         desc->ToAttributes());
    1225      283431 :         if (result.is_null()) return Nothing<bool>();
    1226             :       }
    1227             :     } else {
    1228             :       // 2d. Else Desc must be an accessor Property Descriptor,
    1229             :       DCHECK(desc_is_accessor_descriptor);
    1230             :       // 2d i. If O is not undefined, create an own accessor property named P
    1231             :       // of object O whose [[Get]], [[Set]], [[Enumerable]] and
    1232             :       // [[Configurable]] attribute values are described by Desc. If the value
    1233             :       // of an attribute field of Desc is absent, the attribute of the newly
    1234             :       // created property is set to its default value.
    1235       68034 :       if (it != nullptr) {
    1236       67890 :         if (!desc->has_enumerable()) desc->set_enumerable(false);
    1237       67890 :         if (!desc->has_configurable()) desc->set_configurable(false);
    1238             :         Handle<Object> getter(
    1239             :             desc->has_get()
    1240             :                 ? desc->get()
    1241       80624 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    1242             :         Handle<Object> setter(
    1243             :             desc->has_set()
    1244             :                 ? desc->set()
    1245      109760 :                 : Handle<Object>::cast(isolate->factory()->null_value()));
    1246             :         MaybeHandle<Object> result =
    1247       67890 :             JSObject::DefineAccessor(it, getter, setter, desc->ToAttributes());
    1248       67890 :         if (result.is_null()) return Nothing<bool>();
    1249             :       }
    1250             :     }
    1251             :     // 2e. Return true.
    1252             :     return Just(true);
    1253             :   }
    1254             :   // 3. Return true, if every field in Desc is absent.
    1255             :   // 4. Return true, if every field in Desc also occurs in current and the
    1256             :   // value of every field in Desc is the same value as the corresponding field
    1257             :   // in current when compared using the SameValue algorithm.
    1258      331345 :   if ((!desc->has_enumerable() ||
    1259       70546 :        desc->enumerable() == current->enumerable()) &&
    1260       47359 :       (!desc->has_configurable() ||
    1261       68170 :        desc->configurable() == current->configurable()) &&
    1262       50559 :       (!desc->has_value() ||
    1263      280879 :        (current->has_value() && current->value()->SameValue(*desc->value()))) &&
    1264       27233 :       (!desc->has_writable() ||
    1265       70186 :        (current->has_writable() && current->writable() == desc->writable())) &&
    1266        5794 :       (!desc->has_get() ||
    1267      414767 :        (current->has_get() && current->get()->SameValue(*desc->get()))) &&
    1268        7197 :       (!desc->has_set() ||
    1269        7008 :        (current->has_set() && current->set()->SameValue(*desc->set())))) {
    1270             :     return Just(true);
    1271             :   }
    1272             :   // 5. If the [[Configurable]] field of current is false, then
    1273      156403 :   if (!current->configurable()) {
    1274             :     // 5a. Return false, if the [[Configurable]] field of Desc is true.
    1275        7806 :     if (desc->has_configurable() && desc->configurable()) {
    1276         543 :       RETURN_FAILURE(
    1277             :           isolate, GetShouldThrow(isolate, should_throw),
    1278             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    1279             :                        it != nullptr ? it->GetName() : property_name));
    1280             :     }
    1281             :     // 5b. Return false, if the [[Enumerable]] field of Desc is present and the
    1282             :     // [[Enumerable]] fields of current and Desc are the Boolean negation of
    1283             :     // each other.
    1284        7142 :     if (desc->has_enumerable() && desc->enumerable() != current->enumerable()) {
    1285         284 :       RETURN_FAILURE(
    1286             :           isolate, GetShouldThrow(isolate, should_throw),
    1287             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    1288             :                        it != nullptr ? it->GetName() : property_name));
    1289             :     }
    1290             :   }
    1291             : 
    1292             :   bool current_is_data_descriptor =
    1293             :       PropertyDescriptor::IsDataDescriptor(current);
    1294             :   // 6. If IsGenericDescriptor(Desc) is true, no further validation is required.
    1295      156104 :   if (desc_is_generic_descriptor) {
    1296             :     // Nothing to see here.
    1297             : 
    1298             :     // 7. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) have
    1299             :     // different results, then:
    1300      155196 :   } else if (current_is_data_descriptor != desc_is_data_descriptor) {
    1301             :     // 7a. Return false, if the [[Configurable]] field of current is false.
    1302      118083 :     if (!current->configurable()) {
    1303         431 :       RETURN_FAILURE(
    1304             :           isolate, GetShouldThrow(isolate, should_throw),
    1305             :           NewTypeError(MessageTemplate::kRedefineDisallowed,
    1306             :                        it != nullptr ? it->GetName() : property_name));
    1307             :     }
    1308             :     // 7b. If IsDataDescriptor(current) is true, then:
    1309             :     if (current_is_data_descriptor) {
    1310             :       // 7b i. If O is not undefined, convert the property named P of object O
    1311             :       // from a data property to an accessor property. Preserve the existing
    1312             :       // values of the converted property's [[Configurable]] and [[Enumerable]]
    1313             :       // attributes and set the rest of the property's attributes to their
    1314             :       // default values.
    1315             :       // --> Folded into step 10.
    1316             :     } else {
    1317             :       // 7c i. If O is not undefined, convert the property named P of object O
    1318             :       // from an accessor property to a data property. Preserve the existing
    1319             :       // values of the converted property’s [[Configurable]] and [[Enumerable]]
    1320             :       // attributes and set the rest of the property’s attributes to their
    1321             :       // default values.
    1322             :       // --> Folded into step 10.
    1323             :     }
    1324             : 
    1325             :     // 8. Else if IsDataDescriptor(current) and IsDataDescriptor(Desc) are both
    1326             :     // true, then:
    1327       37113 :   } else if (current_is_data_descriptor && desc_is_data_descriptor) {
    1328             :     // 8a. If the [[Configurable]] field of current is false, then:
    1329       26118 :     if (!current->configurable()) {
    1330             :       // 8a i. Return false, if the [[Writable]] field of current is false and
    1331             :       // the [[Writable]] field of Desc is true.
    1332        4234 :       if (!current->writable() && desc->has_writable() && desc->writable()) {
    1333         189 :         RETURN_FAILURE(
    1334             :             isolate, GetShouldThrow(isolate, should_throw),
    1335             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    1336             :                          it != nullptr ? it->GetName() : property_name));
    1337             :       }
    1338             :       // 8a ii. If the [[Writable]] field of current is false, then:
    1339        3801 :       if (!current->writable()) {
    1340             :         // 8a ii 1. Return false, if the [[Value]] field of Desc is present and
    1341             :         // SameValue(Desc.[[Value]], current.[[Value]]) is false.
    1342         470 :         if (desc->has_value() && !desc->value()->SameValue(*current->value())) {
    1343         775 :           RETURN_FAILURE(
    1344             :               isolate, GetShouldThrow(isolate, should_throw),
    1345             :               NewTypeError(MessageTemplate::kRedefineDisallowed,
    1346             :                            it != nullptr ? it->GetName() : property_name));
    1347             :         }
    1348             :       }
    1349             :     }
    1350             :   } else {
    1351             :     // 9. Else IsAccessorDescriptor(current) and IsAccessorDescriptor(Desc)
    1352             :     // are both true,
    1353             :     DCHECK(PropertyDescriptor::IsAccessorDescriptor(current) &&
    1354             :            desc_is_accessor_descriptor);
    1355             :     // 9a. If the [[Configurable]] field of current is false, then:
    1356       10995 :     if (!current->configurable()) {
    1357             :       // 9a i. Return false, if the [[Set]] field of Desc is present and
    1358             :       // SameValue(Desc.[[Set]], current.[[Set]]) is false.
    1359         143 :       if (desc->has_set() && !desc->set()->SameValue(*current->set())) {
    1360         117 :         RETURN_FAILURE(
    1361             :             isolate, GetShouldThrow(isolate, should_throw),
    1362             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    1363             :                          it != nullptr ? it->GetName() : property_name));
    1364             :       }
    1365             :       // 9a ii. Return false, if the [[Get]] field of Desc is present and
    1366             :       // SameValue(Desc.[[Get]], current.[[Get]]) is false.
    1367         106 :       if (desc->has_get() && !desc->get()->SameValue(*current->get())) {
    1368         170 :         RETURN_FAILURE(
    1369             :             isolate, GetShouldThrow(isolate, should_throw),
    1370             :             NewTypeError(MessageTemplate::kRedefineDisallowed,
    1371             :                          it != nullptr ? it->GetName() : property_name));
    1372             :       }
    1373             :     }
    1374             :   }
    1375             : 
    1376             :   // 10. If O is not undefined, then:
    1377      155598 :   if (it != nullptr) {
    1378             :     // 10a. For each field of Desc that is present, set the corresponding
    1379             :     // attribute of the property named P of object O to the value of the field.
    1380             :     PropertyAttributes attrs = NONE;
    1381             : 
    1382      155337 :     if (desc->has_enumerable()) {
    1383             :       attrs = static_cast<PropertyAttributes>(
    1384      121156 :           attrs | (desc->enumerable() ? NONE : DONT_ENUM));
    1385             :     } else {
    1386             :       attrs = static_cast<PropertyAttributes>(
    1387       34181 :           attrs | (current->enumerable() ? NONE : DONT_ENUM));
    1388             :     }
    1389      155337 :     if (desc->has_configurable()) {
    1390             :       attrs = static_cast<PropertyAttributes>(
    1391      133264 :           attrs | (desc->configurable() ? NONE : DONT_DELETE));
    1392             :     } else {
    1393             :       attrs = static_cast<PropertyAttributes>(
    1394       22073 :           attrs | (current->configurable() ? NONE : DONT_DELETE));
    1395             :     }
    1396      284540 :     if (desc_is_data_descriptor ||
    1397      129203 :         (desc_is_generic_descriptor && current_is_data_descriptor)) {
    1398       26943 :       if (desc->has_writable()) {
    1399             :         attrs = static_cast<PropertyAttributes>(
    1400       24067 :             attrs | (desc->writable() ? NONE : READ_ONLY));
    1401             :       } else {
    1402             :         attrs = static_cast<PropertyAttributes>(
    1403        2876 :             attrs | (current->writable() ? NONE : READ_ONLY));
    1404             :       }
    1405             :       Handle<Object> value(
    1406             :           desc->has_value() ? desc->value()
    1407             :                             : current->has_value()
    1408             :                                   ? current->value()
    1409             :                                   : Handle<Object>::cast(
    1410       29755 :                                         isolate->factory()->undefined_value()));
    1411             :       return JSObject::DefineOwnPropertyIgnoreAttributes(it, value, attrs,
    1412       26943 :                                                          should_throw);
    1413             :     } else {
    1414             :       DCHECK(desc_is_accessor_descriptor ||
    1415             :              (desc_is_generic_descriptor &&
    1416             :               PropertyDescriptor::IsAccessorDescriptor(current)));
    1417             :       Handle<Object> getter(
    1418             :           desc->has_get()
    1419             :               ? desc->get()
    1420             :               : current->has_get()
    1421             :                     ? current->get()
    1422      135879 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    1423             :       Handle<Object> setter(
    1424             :           desc->has_set()
    1425             :               ? desc->set()
    1426             :               : current->has_set()
    1427             :                     ? current->set()
    1428      365745 :                     : Handle<Object>::cast(isolate->factory()->null_value()));
    1429             :       MaybeHandle<Object> result =
    1430      128394 :           JSObject::DefineAccessor(it, getter, setter, attrs);
    1431      128394 :       if (result.is_null()) return Nothing<bool>();
    1432             :     }
    1433             :   }
    1434             : 
    1435             :   // 11. Return true.
    1436             :   return Just(true);
    1437             : }
    1438             : 
    1439             : // static
    1440      104205 : Maybe<bool> JSReceiver::CreateDataProperty(Isolate* isolate,
    1441             :                                            Handle<JSReceiver> object,
    1442             :                                            Handle<Name> key,
    1443             :                                            Handle<Object> value,
    1444             :                                            Maybe<ShouldThrow> should_throw) {
    1445             :   LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, key,
    1446      104205 :                                                         LookupIterator::OWN);
    1447      104205 :   return CreateDataProperty(&it, value, should_throw);
    1448             : }
    1449             : 
    1450             : // static
    1451     2312142 : Maybe<bool> JSReceiver::CreateDataProperty(LookupIterator* it,
    1452             :                                            Handle<Object> value,
    1453             :                                            Maybe<ShouldThrow> should_throw) {
    1454             :   DCHECK(!it->check_prototype_chain());
    1455     2312142 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    1456             :   Isolate* isolate = receiver->GetIsolate();
    1457             : 
    1458     4624284 :   if (receiver->IsJSObject()) {
    1459     2311110 :     return JSObject::CreateDataProperty(it, value, should_throw);  // Shortcut.
    1460             :   }
    1461             : 
    1462             :   PropertyDescriptor new_desc;
    1463             :   new_desc.set_value(value);
    1464             :   new_desc.set_writable(true);
    1465             :   new_desc.set_enumerable(true);
    1466             :   new_desc.set_configurable(true);
    1467             : 
    1468             :   return JSReceiver::DefineOwnProperty(isolate, receiver, it->GetName(),
    1469        2064 :                                        &new_desc, should_throw);
    1470             : }
    1471             : 
    1472             : // static
    1473     3181663 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(Isolate* isolate,
    1474             :                                                  Handle<JSReceiver> object,
    1475             :                                                  Handle<Object> key,
    1476             :                                                  PropertyDescriptor* desc) {
    1477     3181663 :   bool success = false;
    1478             :   DCHECK(key->IsName() || key->IsNumber());  // |key| is a PropertyKey...
    1479             :   LookupIterator it = LookupIterator::PropertyOrElement(
    1480     3181663 :       isolate, object, key, &success, LookupIterator::OWN);
    1481             :   DCHECK(success);  // ...so creating a LookupIterator can't fail.
    1482     3181665 :   return GetOwnPropertyDescriptor(&it, desc);
    1483             : }
    1484             : 
    1485             : namespace {
    1486             : 
    1487     7387993 : Maybe<bool> GetPropertyDescriptorWithInterceptor(LookupIterator* it,
    1488             :                                                  PropertyDescriptor* desc) {
    1489     3693713 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    1490     2310449 :     if (it->HasAccess()) {
    1491     2310399 :       it->Next();
    1492          55 :     } else if (!JSObject::AllCanRead(it) ||
    1493             :                it->state() != LookupIterator::INTERCEPTOR) {
    1494          50 :       it->Restart();
    1495             :       return Just(false);
    1496             :     }
    1497             :   }
    1498             : 
    1499     3693663 :   if (it->state() != LookupIterator::INTERCEPTOR) return Just(false);
    1500             : 
    1501             :   Isolate* isolate = it->isolate();
    1502         555 :   Handle<InterceptorInfo> interceptor = it->GetInterceptor();
    1503        1110 :   if (interceptor->descriptor()->IsUndefined(isolate)) return Just(false);
    1504             : 
    1505             :   Handle<Object> result;
    1506             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    1507             : 
    1508             :   Handle<Object> receiver = it->GetReceiver();
    1509          90 :   if (!receiver->IsJSReceiver()) {
    1510           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    1511             :                                      Object::ConvertReceiver(isolate, receiver),
    1512             :                                      Nothing<bool>());
    1513             :   }
    1514             : 
    1515             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    1516          45 :                                  *holder, Just(kDontThrow));
    1517          45 :   if (it->IsElement()) {
    1518          12 :     result = args.CallIndexedDescriptor(interceptor, it->index());
    1519             :   } else {
    1520          33 :     result = args.CallNamedDescriptor(interceptor, it->name());
    1521             :   }
    1522          45 :   if (!result.is_null()) {
    1523             :     // Request successfully intercepted, try to set the property
    1524             :     // descriptor.
    1525             :     Utils::ApiCheck(
    1526          12 :         PropertyDescriptor::ToPropertyDescriptor(isolate, result, desc),
    1527             :         it->IsElement() ? "v8::IndexedPropertyDescriptorCallback"
    1528             :                         : "v8::NamedPropertyDescriptorCallback",
    1529          12 :         "Invalid property descriptor.");
    1530             : 
    1531             :     return Just(true);
    1532             :   }
    1533             : 
    1534          33 :   it->Next();
    1535             :   return Just(false);
    1536             : }
    1537             : }  // namespace
    1538             : 
    1539             : // ES6 9.1.5.1
    1540             : // Returns true on success, false if the property didn't exist, nothing if
    1541             : // an exception was thrown.
    1542             : // static
    1543     7031463 : Maybe<bool> JSReceiver::GetOwnPropertyDescriptor(LookupIterator* it,
    1544             :                                                  PropertyDescriptor* desc) {
    1545             :   Isolate* isolate = it->isolate();
    1546             :   // "Virtual" dispatch.
    1547    10396834 :   if (it->IsFound() && it->GetHolder<JSReceiver>()->IsJSProxy()) {
    1548             :     return JSProxy::GetOwnPropertyDescriptor(isolate, it->GetHolder<JSProxy>(),
    1549       53186 :                                              it->GetName(), desc);
    1550             :   }
    1551             : 
    1552     3693713 :   Maybe<bool> intercepted = GetPropertyDescriptorWithInterceptor(it, desc);
    1553     3693715 :   MAYBE_RETURN(intercepted, Nothing<bool>());
    1554     3693714 :   if (intercepted.FromJust()) {
    1555             :     return Just(true);
    1556             :   }
    1557             : 
    1558             :   // Request was not intercepted, continue as normal.
    1559             :   // 1. (Assert)
    1560             :   // 2. If O does not have an own property with key P, return undefined.
    1561     3693702 :   Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(it);
    1562     3693701 :   MAYBE_RETURN(maybe, Nothing<bool>());
    1563             :   PropertyAttributes attrs = maybe.FromJust();
    1564     3693514 :   if (attrs == ABSENT) return Just(false);
    1565             :   DCHECK(!isolate->has_pending_exception());
    1566             : 
    1567             :   // 3. Let D be a newly created Property Descriptor with no fields.
    1568             :   DCHECK(desc->is_empty());
    1569             :   // 4. Let X be O's own property whose key is P.
    1570             :   // 5. If X is a data property, then
    1571     3482442 :   bool is_accessor_pair = it->state() == LookupIterator::ACCESSOR &&
    1572     3653726 :                           it->GetAccessors()->IsAccessorPair();
    1573     3311158 :   if (!is_accessor_pair) {
    1574             :     // 5a. Set D.[[Value]] to the value of X's [[Value]] attribute.
    1575             :     Handle<Object> value;
    1576     6532418 :     if (!Object::GetProperty(it).ToHandle(&value)) {
    1577             :       DCHECK(isolate->has_pending_exception());
    1578             :       return Nothing<bool>();
    1579             :     }
    1580             :     desc->set_value(value);
    1581             :     // 5b. Set D.[[Writable]] to the value of X's [[Writable]] attribute
    1582     3266103 :     desc->set_writable((attrs & READ_ONLY) == 0);
    1583             :   } else {
    1584             :     // 6. Else X is an accessor property, so
    1585             :     Handle<AccessorPair> accessors =
    1586       44948 :         Handle<AccessorPair>::cast(it->GetAccessors());
    1587             :     // 6a. Set D.[[Get]] to the value of X's [[Get]] attribute.
    1588             :     desc->set_get(
    1589       44948 :         AccessorPair::GetComponent(isolate, accessors, ACCESSOR_GETTER));
    1590             :     // 6b. Set D.[[Set]] to the value of X's [[Set]] attribute.
    1591             :     desc->set_set(
    1592       44948 :         AccessorPair::GetComponent(isolate, accessors, ACCESSOR_SETTER));
    1593             :   }
    1594             : 
    1595             :   // 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
    1596     3311051 :   desc->set_enumerable((attrs & DONT_ENUM) == 0);
    1597             :   // 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
    1598     3311051 :   desc->set_configurable((attrs & DONT_DELETE) == 0);
    1599             :   // 9. Return D.
    1600             :   DCHECK(PropertyDescriptor::IsAccessorDescriptor(desc) !=
    1601             :          PropertyDescriptor::IsDataDescriptor(desc));
    1602             :   return Just(true);
    1603             : }
    1604      248886 : Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
    1605             :                                           IntegrityLevel level,
    1606             :                                           ShouldThrow should_throw) {
    1607             :   DCHECK(level == SEALED || level == FROZEN);
    1608             : 
    1609      497773 :   if (receiver->IsJSObject()) {
    1610      248472 :     Handle<JSObject> object = Handle<JSObject>::cast(receiver);
    1611             : 
    1612      993856 :     if (!object->HasSloppyArgumentsElements() &&
    1613      496906 :         !object->IsJSModuleNamespace()) {  // Fast path.
    1614             :       // Prevent memory leaks by not adding unnecessary transitions.
    1615      248359 :       Maybe<bool> test = JSObject::TestIntegrityLevel(object, level);
    1616      248359 :       MAYBE_RETURN(test, Nothing<bool>());
    1617      248359 :       if (test.FromJust()) return test;
    1618             : 
    1619      231123 :       if (level == SEALED) {
    1620             :         return JSObject::PreventExtensionsWithTransition<SEALED>(object,
    1621         674 :                                                                  should_throw);
    1622             :       } else {
    1623             :         return JSObject::PreventExtensionsWithTransition<FROZEN>(object,
    1624      230449 :                                                                  should_throw);
    1625             :       }
    1626             :     }
    1627             :   }
    1628             : 
    1629             :   Isolate* isolate = receiver->GetIsolate();
    1630             : 
    1631         530 :   MAYBE_RETURN(JSReceiver::PreventExtensions(receiver, should_throw),
    1632             :                Nothing<bool>());
    1633             : 
    1634             :   Handle<FixedArray> keys;
    1635         530 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1636             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    1637             : 
    1638             :   PropertyDescriptor no_conf;
    1639             :   no_conf.set_configurable(false);
    1640             : 
    1641             :   PropertyDescriptor no_conf_no_write;
    1642             :   no_conf_no_write.set_configurable(false);
    1643             :   no_conf_no_write.set_writable(false);
    1644             : 
    1645         530 :   if (level == SEALED) {
    1646         430 :     for (int i = 0; i < keys->length(); ++i) {
    1647             :       Handle<Object> key(keys->get(i), isolate);
    1648         166 :       MAYBE_RETURN(DefineOwnProperty(isolate, receiver, key, &no_conf,
    1649             :                                      Just(kThrowOnError)),
    1650             :                    Nothing<bool>());
    1651             :     }
    1652             :     return Just(true);
    1653             :   }
    1654             : 
    1655        2916 :   for (int i = 0; i < keys->length(); ++i) {
    1656             :     Handle<Object> key(keys->get(i), isolate);
    1657             :     PropertyDescriptor current_desc;
    1658             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    1659        1296 :         isolate, receiver, key, &current_desc);
    1660        1332 :     MAYBE_RETURN(owned, Nothing<bool>());
    1661        1287 :     if (owned.FromJust()) {
    1662             :       PropertyDescriptor desc =
    1663             :           PropertyDescriptor::IsAccessorDescriptor(&current_desc)
    1664             :               ? no_conf
    1665        1287 :               : no_conf_no_write;
    1666        1287 :       MAYBE_RETURN(
    1667             :           DefineOwnProperty(isolate, receiver, key, &desc, Just(kThrowOnError)),
    1668             :           Nothing<bool>());
    1669             :     }
    1670             :   }
    1671             :   return Just(true);
    1672             : }
    1673             : 
    1674             : namespace {
    1675         280 : Maybe<bool> GenericTestIntegrityLevel(Handle<JSReceiver> receiver,
    1676             :                                       PropertyAttributes level) {
    1677             :   DCHECK(level == SEALED || level == FROZEN);
    1678             : 
    1679         280 :   Maybe<bool> extensible = JSReceiver::IsExtensible(receiver);
    1680         280 :   MAYBE_RETURN(extensible, Nothing<bool>());
    1681         280 :   if (extensible.FromJust()) return Just(false);
    1682             : 
    1683             :   Isolate* isolate = receiver->GetIsolate();
    1684             : 
    1685             :   Handle<FixedArray> keys;
    1686         161 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1687             :       isolate, keys, JSReceiver::OwnPropertyKeys(receiver), Nothing<bool>());
    1688             : 
    1689        4791 :   for (int i = 0; i < keys->length(); ++i) {
    1690             :     Handle<Object> key(keys->get(i), isolate);
    1691             :     PropertyDescriptor current_desc;
    1692             :     Maybe<bool> owned = JSReceiver::GetOwnPropertyDescriptor(
    1693        2396 :         isolate, receiver, key, &current_desc);
    1694        2477 :     MAYBE_RETURN(owned, Nothing<bool>());
    1695        2369 :     if (owned.FromJust()) {
    1696        2369 :       if (current_desc.configurable()) return Just(false);
    1697        3538 :       if (level == FROZEN &&
    1698        3529 :           PropertyDescriptor::IsDataDescriptor(&current_desc) &&
    1699             :           current_desc.writable()) {
    1700             :         return Just(false);
    1701             :       }
    1702             :     }
    1703             :   }
    1704             :   return Just(true);
    1705             : }
    1706             : 
    1707             : }  // namespace
    1708             : 
    1709        1114 : Maybe<bool> JSReceiver::TestIntegrityLevel(Handle<JSReceiver> receiver,
    1710             :                                            IntegrityLevel level) {
    1711        1114 :   if (!receiver->map()->IsCustomElementsReceiverMap()) {
    1712             :     return JSObject::TestIntegrityLevel(Handle<JSObject>::cast(receiver),
    1713         961 :                                         level);
    1714             :   }
    1715         153 :   return GenericTestIntegrityLevel(receiver, level);
    1716             : }
    1717             : 
    1718       77352 : Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object,
    1719             :                                           ShouldThrow should_throw) {
    1720      154704 :   if (object->IsJSProxy()) {
    1721             :     return JSProxy::PreventExtensions(Handle<JSProxy>::cast(object),
    1722       73220 :                                       should_throw);
    1723             :   }
    1724             :   DCHECK(object->IsJSObject());
    1725             :   return JSObject::PreventExtensions(Handle<JSObject>::cast(object),
    1726        4132 :                                      should_throw);
    1727             : }
    1728             : 
    1729     1012727 : Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) {
    1730     2025454 :   if (object->IsJSProxy()) {
    1731       81231 :     return JSProxy::IsExtensible(Handle<JSProxy>::cast(object));
    1732             :   }
    1733      931496 :   return Just(JSObject::IsExtensible(Handle<JSObject>::cast(object)));
    1734             : }
    1735             : 
    1736             : // static
    1737     5531071 : MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
    1738             :                                             ToPrimitiveHint hint) {
    1739             :   Isolate* const isolate = receiver->GetIsolate();
    1740             :   Handle<Object> exotic_to_prim;
    1741    11062142 :   ASSIGN_RETURN_ON_EXCEPTION(
    1742             :       isolate, exotic_to_prim,
    1743             :       Object::GetMethod(receiver, isolate->factory()->to_primitive_symbol()),
    1744             :       Object);
    1745    11062132 :   if (!exotic_to_prim->IsUndefined(isolate)) {
    1746             :     Handle<Object> hint_string =
    1747        6822 :         isolate->factory()->ToPrimitiveHintString(hint);
    1748             :     Handle<Object> result;
    1749       13644 :     ASSIGN_RETURN_ON_EXCEPTION(
    1750             :         isolate, result,
    1751             :         Execution::Call(isolate, exotic_to_prim, receiver, 1, &hint_string),
    1752             :         Object);
    1753       13338 :     if (result->IsPrimitive()) return result;
    1754           0 :     THROW_NEW_ERROR(isolate,
    1755             :                     NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    1756             :                     Object);
    1757             :   }
    1758             :   return OrdinaryToPrimitive(receiver, (hint == ToPrimitiveHint::kString)
    1759             :                                            ? OrdinaryToPrimitiveHint::kString
    1760     5524244 :                                            : OrdinaryToPrimitiveHint::kNumber);
    1761             : }
    1762             : 
    1763             : // static
    1764     5524244 : MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(
    1765             :     Handle<JSReceiver> receiver, OrdinaryToPrimitiveHint hint) {
    1766             :   Isolate* const isolate = receiver->GetIsolate();
    1767    16572732 :   Handle<String> method_names[2];
    1768     5524244 :   switch (hint) {
    1769             :     case OrdinaryToPrimitiveHint::kNumber:
    1770        6118 :       method_names[0] = isolate->factory()->valueOf_string();
    1771        6118 :       method_names[1] = isolate->factory()->toString_string();
    1772        6118 :       break;
    1773             :     case OrdinaryToPrimitiveHint::kString:
    1774     5518126 :       method_names[0] = isolate->factory()->toString_string();
    1775     5518126 :       method_names[1] = isolate->factory()->valueOf_string();
    1776     5518126 :       break;
    1777             :   }
    1778     5528117 :   for (Handle<String> name : method_names) {
    1779             :     Handle<Object> method;
    1780    11052226 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
    1781             :                                JSReceiver::GetProperty(isolate, receiver, name),
    1782             :                                Object);
    1783    11052190 :     if (method->IsCallable()) {
    1784             :       Handle<Object> result;
    1785    11051290 :       ASSIGN_RETURN_ON_EXCEPTION(
    1786             :           isolate, result,
    1787             :           Execution::Call(isolate, method, receiver, 0, nullptr), Object);
    1788    11033648 :       if (result->IsPrimitive()) return result;
    1789             :     }
    1790             :   }
    1791         135 :   THROW_NEW_ERROR(isolate,
    1792             :                   NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
    1793             :                   Object);
    1794             : }
    1795             : 
    1796        1398 : V8_WARN_UNUSED_RESULT Maybe<bool> FastGetOwnValuesOrEntries(
    1797             :     Isolate* isolate, Handle<JSReceiver> receiver, bool get_entries,
    1798             :     Handle<FixedArray>* result) {
    1799             :   Handle<Map> map(JSReceiver::cast(*receiver)->map(), isolate);
    1800             : 
    1801        1398 :   if (!map->IsJSObjectMap()) return Just(false);
    1802        1398 :   if (!map->OnlyHasSimpleProperties()) return Just(false);
    1803             : 
    1804             :   Handle<JSObject> object(JSObject::cast(*receiver), isolate);
    1805             : 
    1806        2796 :   Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    1807             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    1808             :   int number_of_own_elements =
    1809        5592 :       object->GetElementsAccessor()->GetCapacity(*object, object->elements());
    1810             :   Handle<FixedArray> values_or_entries = isolate->factory()->NewFixedArray(
    1811        1398 :       number_of_own_descriptors + number_of_own_elements);
    1812        1398 :   int count = 0;
    1813             : 
    1814        2796 :   if (object->elements() != ReadOnlyRoots(isolate).empty_fixed_array()) {
    1815        2016 :     MAYBE_RETURN(object->GetElementsAccessor()->CollectValuesOrEntries(
    1816             :                      isolate, object, values_or_entries, get_entries, &count,
    1817             :                      ENUMERABLE_STRINGS),
    1818             :                  Nothing<bool>());
    1819             :   }
    1820             : 
    1821             :   bool stable = object->map() == *map;
    1822             : 
    1823        3375 :   for (int index = 0; index < number_of_own_descriptors; index++) {
    1824        3954 :     Handle<Name> next_key(descriptors->GetKey(index), isolate);
    1825        3954 :     if (!next_key->IsString()) continue;
    1826             :     Handle<Object> prop_value;
    1827             : 
    1828             :     // Directly decode from the descriptor array if |from| did not change shape.
    1829        1797 :     if (stable) {
    1830        1707 :       PropertyDetails details = descriptors->GetDetails(index);
    1831        1707 :       if (!details.IsEnumerable()) continue;
    1832        1212 :       if (details.kind() == kData) {
    1833        1176 :         if (details.location() == kDescriptor) {
    1834           0 :           prop_value = handle(descriptors->GetStrongValue(index), isolate);
    1835             :         } else {
    1836        1176 :           Representation representation = details.representation();
    1837        1176 :           FieldIndex field_index = FieldIndex::ForDescriptor(*map, index);
    1838             :           prop_value =
    1839        1176 :               JSObject::FastPropertyAt(object, representation, field_index);
    1840             :         }
    1841             :       } else {
    1842          72 :         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1843             :             isolate, prop_value,
    1844             :             JSReceiver::GetProperty(isolate, object, next_key),
    1845             :             Nothing<bool>());
    1846             :         stable = object->map() == *map;
    1847             :       }
    1848             :     } else {
    1849             :       // If the map did change, do a slower lookup. We are still guaranteed that
    1850             :       // the object has a simple shape, and that the key is a name.
    1851             :       LookupIterator it(isolate, object, next_key,
    1852          90 :                         LookupIterator::OWN_SKIP_INTERCEPTOR);
    1853         162 :       if (!it.IsFound()) continue;
    1854             :       DCHECK(it.state() == LookupIterator::DATA ||
    1855             :              it.state() == LookupIterator::ACCESSOR);
    1856          54 :       if (!it.IsEnumerable()) continue;
    1857          36 :       ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1858             :           isolate, prop_value, Object::GetProperty(&it), Nothing<bool>());
    1859             :     }
    1860             : 
    1861        1230 :     if (get_entries) {
    1862         816 :       prop_value = MakeEntryPair(isolate, next_key, prop_value);
    1863             :     }
    1864             : 
    1865        2460 :     values_or_entries->set(count, *prop_value);
    1866        1230 :     count++;
    1867             :   }
    1868             : 
    1869             :   DCHECK_LE(count, values_or_entries->length());
    1870        1398 :   *result = FixedArray::ShrinkOrEmpty(isolate, values_or_entries, count);
    1871             :   return Just(true);
    1872             : }
    1873             : 
    1874        2145 : MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate,
    1875             :                                               Handle<JSReceiver> object,
    1876             :                                               PropertyFilter filter,
    1877             :                                               bool try_fast_path,
    1878             :                                               bool get_entries) {
    1879             :   Handle<FixedArray> values_or_entries;
    1880        2145 :   if (try_fast_path && filter == ENUMERABLE_STRINGS) {
    1881             :     Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries(
    1882        1398 :         isolate, object, get_entries, &values_or_entries);
    1883        1398 :     if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>();
    1884        1398 :     if (fast_values_or_entries.FromJust()) return values_or_entries;
    1885             :   }
    1886             : 
    1887             :   PropertyFilter key_filter =
    1888         747 :       static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE);
    1889             : 
    1890             :   Handle<FixedArray> keys;
    1891        1494 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1892             :       isolate, keys,
    1893             :       KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, key_filter,
    1894             :                               GetKeysConversion::kConvertToString),
    1895             :       MaybeHandle<FixedArray>());
    1896             : 
    1897         720 :   values_or_entries = isolate->factory()->NewFixedArray(keys->length());
    1898             :   int length = 0;
    1899             : 
    1900        5910 :   for (int i = 0; i < keys->length(); ++i) {
    1901        2271 :     Handle<Name> key = Handle<Name>::cast(handle(keys->get(i), isolate));
    1902             : 
    1903        2271 :     if (filter & ONLY_ENUMERABLE) {
    1904             :       PropertyDescriptor descriptor;
    1905             :       Maybe<bool> did_get_descriptor = JSReceiver::GetOwnPropertyDescriptor(
    1906        2271 :           isolate, object, key, &descriptor);
    1907        2271 :       MAYBE_RETURN(did_get_descriptor, MaybeHandle<FixedArray>());
    1908        4413 :       if (!did_get_descriptor.FromJust() || !descriptor.enumerable()) continue;
    1909             :     }
    1910             : 
    1911             :     Handle<Object> value;
    1912        2952 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
    1913             :         isolate, value, Object::GetPropertyOrElement(isolate, object, key),
    1914             :         MaybeHandle<FixedArray>());
    1915             : 
    1916        1476 :     if (get_entries) {
    1917             :       Handle<FixedArray> entry_storage =
    1918         981 :           isolate->factory()->NewUninitializedFixedArray(2);
    1919        1962 :       entry_storage->set(0, *key);
    1920         981 :       entry_storage->set(1, *value);
    1921             :       value = isolate->factory()->NewJSArrayWithElements(entry_storage,
    1922         981 :                                                          PACKED_ELEMENTS, 2);
    1923             :     }
    1924             : 
    1925        1476 :     values_or_entries->set(length, *value);
    1926        1476 :     length++;
    1927             :   }
    1928             :   DCHECK_LE(length, values_or_entries->length());
    1929         684 :   return FixedArray::ShrinkOrEmpty(isolate, values_or_entries, length);
    1930             : }
    1931             : 
    1932         909 : MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object,
    1933             :                                                  PropertyFilter filter,
    1934             :                                                  bool try_fast_path) {
    1935             :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
    1936        1818 :                                try_fast_path, false);
    1937             : }
    1938             : 
    1939        1236 : MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object,
    1940             :                                                   PropertyFilter filter,
    1941             :                                                   bool try_fast_path) {
    1942             :   return GetOwnValuesOrEntries(object->GetIsolate(), object, filter,
    1943        2472 :                                try_fast_path, true);
    1944             : }
    1945             : 
    1946        5314 : Handle<FixedArray> JSReceiver::GetOwnElementIndices(Isolate* isolate,
    1947             :                                                     Handle<JSReceiver> receiver,
    1948             :                                                     Handle<JSObject> object) {
    1949             :   KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly,
    1950             :                              ALL_PROPERTIES);
    1951        5314 :   accumulator.CollectOwnElementIndices(receiver, object);
    1952             :   Handle<FixedArray> keys =
    1953        5314 :       accumulator.GetKeys(GetKeysConversion::kKeepNumbers);
    1954             :   DCHECK(keys->ContainsSortedNumbers());
    1955        5314 :   return keys;
    1956             : }
    1957      280102 : Maybe<bool> JSReceiver::SetPrototype(Handle<JSReceiver> object,
    1958             :                                      Handle<Object> value, bool from_javascript,
    1959             :                                      ShouldThrow should_throw) {
    1960      560204 :   if (object->IsJSProxy()) {
    1961             :     return JSProxy::SetPrototype(Handle<JSProxy>::cast(object), value,
    1962       71920 :                                  from_javascript, should_throw);
    1963             :   }
    1964             :   return JSObject::SetPrototype(Handle<JSObject>::cast(object), value,
    1965      208182 :                                 from_javascript, should_throw);
    1966             : }
    1967             : 
    1968        4128 : bool JSReceiver::HasProxyInPrototype(Isolate* isolate) {
    1969       17052 :   for (PrototypeIterator iter(isolate, *this, kStartAtReceiver,
    1970             :                               PrototypeIterator::END_AT_NULL);
    1971       12924 :        !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) {
    1972       25902 :     if (iter.GetCurrent()->IsJSProxy()) return true;
    1973             :   }
    1974        4101 :   return false;
    1975             : }
    1976             : 
    1977           0 : bool JSReceiver::HasComplexElements() {
    1978           0 :   if (IsJSProxy()) return true;
    1979           0 :   JSObject this_object = JSObject::cast(*this);
    1980           0 :   if (this_object->HasIndexedInterceptor()) {
    1981             :     return true;
    1982             :   }
    1983           0 :   if (!this_object->HasDictionaryElements()) return false;
    1984           0 :   return this_object->element_dictionary()->HasComplexElements();
    1985             : }
    1986             : 
    1987             : // static
    1988     2678859 : MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
    1989             :                                     Handle<JSReceiver> new_target,
    1990             :                                     Handle<AllocationSite> site) {
    1991             :   // If called through new, new.target can be:
    1992             :   // - a subclass of constructor,
    1993             :   // - a proxy wrapper around constructor, or
    1994             :   // - the constructor itself.
    1995             :   // If called through Reflect.construct, it's guaranteed to be a constructor.
    1996             :   Isolate* const isolate = constructor->GetIsolate();
    1997             :   DCHECK(constructor->IsConstructor());
    1998             :   DCHECK(new_target->IsConstructor());
    1999             :   DCHECK(!constructor->has_initial_map() ||
    2000             :          constructor->initial_map()->instance_type() != JS_FUNCTION_TYPE);
    2001             : 
    2002             :   Handle<Map> initial_map;
    2003     5357729 :   ASSIGN_RETURN_ON_EXCEPTION(
    2004             :       isolate, initial_map,
    2005             :       JSFunction::GetDerivedMap(isolate, constructor, new_target), JSObject);
    2006             :   Handle<JSObject> result =
    2007     2678784 :       isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
    2008     2678782 :   if (initial_map->is_dictionary_map()) {
    2009             :     Handle<NameDictionary> dictionary =
    2010           0 :         NameDictionary::New(isolate, NameDictionary::kInitialCapacity);
    2011           0 :     result->SetProperties(*dictionary);
    2012             :   }
    2013     2678782 :   isolate->counters()->constructed_objects()->Increment();
    2014     2678782 :   isolate->counters()->constructed_objects_runtime()->Increment();
    2015     2678783 :   return result;
    2016             : }
    2017             : 
    2018             : // 9.1.12 ObjectCreate ( proto [ , internalSlotsList ] )
    2019             : // Notice: This is NOT 19.1.2.2 Object.create ( O, Properties )
    2020      120898 : MaybeHandle<JSObject> JSObject::ObjectCreate(Isolate* isolate,
    2021             :                                              Handle<Object> prototype) {
    2022             :   // Generate the map with the specified {prototype} based on the Object
    2023             :   // function's initial map from the current native context.
    2024             :   // TODO(bmeurer): Use a dedicated cache for Object.create; think about
    2025             :   // slack tracking for Object.create.
    2026             :   Handle<Map> map =
    2027      120898 :       Map::GetObjectCreateMap(isolate, Handle<HeapObject>::cast(prototype));
    2028             : 
    2029             :   // Actually allocate the object.
    2030             :   Handle<JSObject> object;
    2031      120898 :   if (map->is_dictionary_map()) {
    2032         365 :     object = isolate->factory()->NewSlowJSObjectFromMap(map);
    2033             :   } else {
    2034      120533 :     object = isolate->factory()->NewJSObjectFromMap(map);
    2035             :   }
    2036      120898 :   return object;
    2037             : }
    2038             : 
    2039     5487176 : void JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
    2040             :   DCHECK(object->HasSmiOrObjectElements() ||
    2041             :          object->HasFastStringWrapperElements());
    2042    10974355 :   FixedArray raw_elems = FixedArray::cast(object->elements());
    2043             :   Isolate* isolate = object->GetIsolate();
    2044    10960028 :   if (raw_elems->map() != ReadOnlyRoots(isolate).fixed_cow_array_map()) return;
    2045             :   Handle<FixedArray> elems(raw_elems, isolate);
    2046             :   Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap(
    2047       14326 :       elems, isolate->factory()->fixed_array_map());
    2048       28652 :   object->set_elements(*writable_elems);
    2049       14326 :   isolate->counters()->cow_arrays_converted()->Increment();
    2050             : }
    2051             : 
    2052     5543452 : int JSObject::GetHeaderSize(InstanceType type,
    2053             :                             bool function_has_prototype_slot) {
    2054     5543452 :   switch (type) {
    2055             :     case JS_OBJECT_TYPE:
    2056             :     case JS_API_OBJECT_TYPE:
    2057             :     case JS_SPECIAL_API_OBJECT_TYPE:
    2058             :       return JSObject::kHeaderSize;
    2059             :     case JS_GENERATOR_OBJECT_TYPE:
    2060        7296 :       return JSGeneratorObject::kSize;
    2061             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
    2062           0 :       return JSAsyncFunctionObject::kSize;
    2063             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    2064        1375 :       return JSAsyncGeneratorObject::kSize;
    2065             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    2066           0 :       return JSAsyncFromSyncIterator::kSize;
    2067             :     case JS_GLOBAL_PROXY_TYPE:
    2068       55340 :       return JSGlobalProxy::kSize;
    2069             :     case JS_GLOBAL_OBJECT_TYPE:
    2070       55956 :       return JSGlobalObject::kSize;
    2071             :     case JS_BOUND_FUNCTION_TYPE:
    2072         842 :       return JSBoundFunction::kSize;
    2073             :     case JS_FUNCTION_TYPE:
    2074      471729 :       return JSFunction::GetHeaderSize(function_has_prototype_slot);
    2075             :     case JS_VALUE_TYPE:
    2076        6003 :       return JSValue::kSize;
    2077             :     case JS_DATE_TYPE:
    2078        1642 :       return JSDate::kSize;
    2079             :     case JS_ARRAY_TYPE:
    2080       61281 :       return JSArray::kSize;
    2081             :     case JS_ARRAY_BUFFER_TYPE:
    2082      814098 :       return JSArrayBuffer::kHeaderSize;
    2083             :     case JS_ARRAY_ITERATOR_TYPE:
    2084         189 :       return JSArrayIterator::kSize;
    2085             :     case JS_TYPED_ARRAY_TYPE:
    2086       10295 :       return JSTypedArray::kHeaderSize;
    2087             :     case JS_DATA_VIEW_TYPE:
    2088        8239 :       return JSDataView::kHeaderSize;
    2089             :     case JS_SET_TYPE:
    2090        1561 :       return JSSet::kSize;
    2091             :     case JS_MAP_TYPE:
    2092         456 :       return JSMap::kSize;
    2093             :     case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    2094             :     case JS_SET_VALUE_ITERATOR_TYPE:
    2095          63 :       return JSSetIterator::kSize;
    2096             :     case JS_MAP_KEY_ITERATOR_TYPE:
    2097             :     case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    2098             :     case JS_MAP_VALUE_ITERATOR_TYPE:
    2099          45 :       return JSMapIterator::kSize;
    2100             :     case WEAK_CELL_TYPE:
    2101           0 :       return WeakCell::kSize;
    2102             :     case JS_WEAK_REF_TYPE:
    2103           0 :       return JSWeakRef::kSize;
    2104             :     case JS_FINALIZATION_GROUP_TYPE:
    2105           0 :       return JSFinalizationGroup::kSize;
    2106             :     case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
    2107           0 :       return JSFinalizationGroupCleanupIterator::kSize;
    2108             :     case JS_WEAK_MAP_TYPE:
    2109        1262 :       return JSWeakMap::kSize;
    2110             :     case JS_WEAK_SET_TYPE:
    2111        1231 :       return JSWeakSet::kSize;
    2112             :     case JS_PROMISE_TYPE:
    2113         461 :       return JSPromise::kSize;
    2114             :     case JS_REGEXP_TYPE:
    2115        1680 :       return JSRegExp::kSize;
    2116             :     case JS_REGEXP_STRING_ITERATOR_TYPE:
    2117           0 :       return JSRegExpStringIterator::kSize;
    2118             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    2119             :       return JSObject::kHeaderSize;
    2120             :     case JS_MESSAGE_OBJECT_TYPE:
    2121           0 :       return JSMessageObject::kSize;
    2122             :     case JS_ARGUMENTS_TYPE:
    2123             :       return JSObject::kHeaderSize;
    2124             :     case JS_ERROR_TYPE:
    2125             :       return JSObject::kHeaderSize;
    2126             :     case JS_STRING_ITERATOR_TYPE:
    2127           0 :       return JSStringIterator::kSize;
    2128             :     case JS_MODULE_NAMESPACE_TYPE:
    2129         118 :       return JSModuleNamespace::kHeaderSize;
    2130             : #ifdef V8_INTL_SUPPORT
    2131             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
    2132          18 :       return JSV8BreakIterator::kSize;
    2133             :     case JS_INTL_COLLATOR_TYPE:
    2134           0 :       return JSCollator::kSize;
    2135             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
    2136           0 :       return JSDateTimeFormat::kSize;
    2137             :     case JS_INTL_LIST_FORMAT_TYPE:
    2138          18 :       return JSListFormat::kSize;
    2139             :     case JS_INTL_LOCALE_TYPE:
    2140          18 :       return JSLocale::kSize;
    2141             :     case JS_INTL_NUMBER_FORMAT_TYPE:
    2142           0 :       return JSNumberFormat::kSize;
    2143             :     case JS_INTL_PLURAL_RULES_TYPE:
    2144           0 :       return JSPluralRules::kSize;
    2145             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
    2146          18 :       return JSRelativeTimeFormat::kSize;
    2147             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
    2148           0 :       return JSSegmentIterator::kSize;
    2149             :     case JS_INTL_SEGMENTER_TYPE:
    2150          18 :       return JSSegmenter::kSize;
    2151             : #endif  // V8_INTL_SUPPORT
    2152             :     case WASM_GLOBAL_TYPE:
    2153           0 :       return WasmGlobalObject::kSize;
    2154             :     case WASM_INSTANCE_TYPE:
    2155           0 :       return WasmInstanceObject::kSize;
    2156             :     case WASM_MEMORY_TYPE:
    2157           0 :       return WasmMemoryObject::kSize;
    2158             :     case WASM_MODULE_TYPE:
    2159           0 :       return WasmModuleObject::kSize;
    2160             :     case WASM_TABLE_TYPE:
    2161           0 :       return WasmTableObject::kSize;
    2162             :     case WASM_EXCEPTION_TYPE:
    2163           0 :       return WasmExceptionObject::kSize;
    2164             :     default:
    2165           0 :       UNREACHABLE();
    2166             :   }
    2167             : }
    2168             : 
    2169             : // static
    2170        3651 : bool JSObject::AllCanRead(LookupIterator* it) {
    2171             :   // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
    2172             :   // which have already been checked.
    2173             :   DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
    2174             :          it->state() == LookupIterator::INTERCEPTOR);
    2175        4822 :   for (it->Next(); it->IsFound(); it->Next()) {
    2176        1241 :     if (it->state() == LookupIterator::ACCESSOR) {
    2177         122 :       auto accessors = it->GetAccessors();
    2178         244 :       if (accessors->IsAccessorInfo()) {
    2179          77 :         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
    2180             :       }
    2181        1119 :     } else if (it->state() == LookupIterator::INTERCEPTOR) {
    2182        1260 :       if (it->GetInterceptor()->all_can_read()) return true;
    2183         489 :     } else if (it->state() == LookupIterator::JSPROXY) {
    2184             :       // Stop lookupiterating. And no, AllCanNotRead.
    2185             :       return false;
    2186             :     }
    2187             :   }
    2188             :   return false;
    2189             : }
    2190             : 
    2191        1174 : MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
    2192        1272 :     LookupIterator* it) {
    2193             :   Isolate* isolate = it->isolate();
    2194        1174 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2195             :   Handle<InterceptorInfo> interceptor =
    2196        1174 :       it->GetInterceptorForFailedAccessCheck();
    2197        1174 :   if (interceptor.is_null()) {
    2198        1069 :     while (AllCanRead(it)) {
    2199          46 :       if (it->state() == LookupIterator::ACCESSOR) {
    2200          52 :         return Object::GetPropertyWithAccessor(it);
    2201             :       }
    2202             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2203             :       bool done;
    2204             :       Handle<Object> result;
    2205          60 :       ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
    2206             :                                  GetPropertyWithInterceptor(it, &done), Object);
    2207          30 :       if (done) return result;
    2208             :     }
    2209             : 
    2210             :   } else {
    2211             :     Handle<Object> result;
    2212             :     bool done;
    2213         230 :     ASSIGN_RETURN_ON_EXCEPTION(
    2214             :         isolate, result,
    2215             :         GetPropertyWithInterceptorInternal(it, interceptor, &done), Object);
    2216         105 :     if (done) return result;
    2217             :   }
    2218             : 
    2219             :   // Cross-Origin [[Get]] of Well-Known Symbols does not throw, and returns
    2220             :   // undefined.
    2221        1083 :   Handle<Name> name = it->GetName();
    2222        2223 :   if (name->IsSymbol() && Symbol::cast(*name)->is_well_known_symbol()) {
    2223          52 :     return it->factory()->undefined_value();
    2224             :   }
    2225             : 
    2226        1031 :   isolate->ReportFailedAccessCheck(checked);
    2227        1031 :   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    2228           0 :   return it->factory()->undefined_value();
    2229             : }
    2230             : 
    2231         121 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
    2232         131 :     LookupIterator* it) {
    2233             :   Isolate* isolate = it->isolate();
    2234         121 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2235             :   Handle<InterceptorInfo> interceptor =
    2236         121 :       it->GetInterceptorForFailedAccessCheck();
    2237         121 :   if (interceptor.is_null()) {
    2238         121 :     while (AllCanRead(it)) {
    2239          10 :       if (it->state() == LookupIterator::ACCESSOR) {
    2240             :         return Just(it->property_attributes());
    2241             :       }
    2242             :       DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2243           0 :       auto result = GetPropertyAttributesWithInterceptor(it);
    2244           0 :       if (isolate->has_scheduled_exception()) break;
    2245           0 :       if (result.IsJust() && result.FromJust() != ABSENT) return result;
    2246             :     }
    2247             :   } else {
    2248             :     Maybe<PropertyAttributes> result =
    2249           0 :         GetPropertyAttributesWithInterceptorInternal(it, interceptor);
    2250           0 :     if (isolate->has_pending_exception()) return Nothing<PropertyAttributes>();
    2251           0 :     if (result.FromMaybe(ABSENT) != ABSENT) return result;
    2252             :   }
    2253         111 :   isolate->ReportFailedAccessCheck(checked);
    2254         111 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<PropertyAttributes>());
    2255             :   return Just(ABSENT);
    2256             : }
    2257             : 
    2258             : // static
    2259         269 : bool JSObject::AllCanWrite(LookupIterator* it) {
    2260         382 :   for (; it->IsFound() && it->state() != LookupIterator::JSPROXY; it->Next()) {
    2261         123 :     if (it->state() == LookupIterator::ACCESSOR) {
    2262          25 :       Handle<Object> accessors = it->GetAccessors();
    2263          50 :       if (accessors->IsAccessorInfo()) {
    2264          15 :         if (AccessorInfo::cast(*accessors)->all_can_write()) return true;
    2265             :       }
    2266             :     }
    2267             :   }
    2268             :   return false;
    2269             : }
    2270             : 
    2271         108 : Maybe<bool> JSObject::SetPropertyWithFailedAccessCheck(
    2272         108 :     LookupIterator* it, Handle<Object> value, Maybe<ShouldThrow> should_throw) {
    2273             :   Isolate* isolate = it->isolate();
    2274         108 :   Handle<JSObject> checked = it->GetHolder<JSObject>();
    2275             :   Handle<InterceptorInfo> interceptor =
    2276         108 :       it->GetInterceptorForFailedAccessCheck();
    2277         108 :   if (interceptor.is_null()) {
    2278          78 :     if (AllCanWrite(it)) {
    2279          10 :       return Object::SetPropertyWithAccessor(it, value, should_throw);
    2280             :     }
    2281             :   } else {
    2282             :     Maybe<bool> result = SetPropertyWithInterceptorInternal(
    2283          30 :         it, interceptor, should_throw, value);
    2284          60 :     if (isolate->has_pending_exception()) return Nothing<bool>();
    2285          20 :     if (result.IsJust()) return result;
    2286             :   }
    2287          68 :   isolate->ReportFailedAccessCheck(checked);
    2288          68 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    2289             :   return Just(true);
    2290             : }
    2291             : 
    2292      337587 : void JSObject::SetNormalizedProperty(Handle<JSObject> object, Handle<Name> name,
    2293             :                                      Handle<Object> value,
    2294             :                                      PropertyDetails details) {
    2295             :   DCHECK(!object->HasFastProperties());
    2296             :   DCHECK(name->IsUniqueName());
    2297             :   Isolate* isolate = object->GetIsolate();
    2298             : 
    2299      337587 :   uint32_t hash = name->Hash();
    2300             : 
    2301      675174 :   if (object->IsJSGlobalObject()) {
    2302        9627 :     Handle<JSGlobalObject> global_obj = Handle<JSGlobalObject>::cast(object);
    2303             :     Handle<GlobalDictionary> dictionary(global_obj->global_dictionary(),
    2304       19254 :                                         isolate);
    2305       19254 :     int entry = dictionary->FindEntry(ReadOnlyRoots(isolate), name, hash);
    2306             : 
    2307        9627 :     if (entry == GlobalDictionary::kNotFound) {
    2308             :       DCHECK_IMPLIES(global_obj->map()->is_prototype_map(),
    2309             :                      Map::IsPrototypeChainInvalidated(global_obj->map()));
    2310        1020 :       auto cell = isolate->factory()->NewPropertyCell(name);
    2311        1020 :       cell->set_value(*value);
    2312        2040 :       auto cell_type = value->IsUndefined(isolate)
    2313             :                            ? PropertyCellType::kUndefined
    2314        1020 :                            : PropertyCellType::kConstant;
    2315             :       details = details.set_cell_type(cell_type);
    2316             :       value = cell;
    2317             :       dictionary =
    2318        1020 :           GlobalDictionary::Add(isolate, dictionary, name, value, details);
    2319        2040 :       global_obj->set_global_dictionary(*dictionary);
    2320             :     } else {
    2321             :       Handle<PropertyCell> cell = PropertyCell::PrepareForValue(
    2322        8607 :           isolate, dictionary, entry, value, details);
    2323        8607 :       cell->set_value(*value);
    2324             :     }
    2325             :   } else {
    2326      655920 :     Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
    2327             : 
    2328      327960 :     int entry = dictionary->FindEntry(isolate, name);
    2329      327960 :     if (entry == NameDictionary::kNotFound) {
    2330             :       DCHECK_IMPLIES(object->map()->is_prototype_map(),
    2331             :                      Map::IsPrototypeChainInvalidated(object->map()));
    2332             :       dictionary =
    2333       97254 :           NameDictionary::Add(isolate, dictionary, name, value, details);
    2334      194508 :       object->SetProperties(*dictionary);
    2335             :     } else {
    2336      230706 :       PropertyDetails original_details = dictionary->DetailsAt(entry);
    2337             :       int enumeration_index = original_details.dictionary_index();
    2338             :       DCHECK_GT(enumeration_index, 0);
    2339             :       details = details.set_index(enumeration_index);
    2340      461412 :       dictionary->SetEntry(isolate, entry, *name, *value, details);
    2341             :     }
    2342             :   }
    2343      337587 : }
    2344             : 
    2345       32568 : void JSObject::JSObjectShortPrint(StringStream* accumulator) {
    2346       32568 :   switch (map()->instance_type()) {
    2347             :     case JS_ARRAY_TYPE: {
    2348        1982 :       double length = JSArray::cast(*this)->length()->IsUndefined()
    2349             :                           ? 0
    2350        1982 :                           : JSArray::cast(*this)->length()->Number();
    2351         991 :       accumulator->Add("<JSArray[%u]>", static_cast<uint32_t>(length));
    2352         991 :       break;
    2353             :     }
    2354             :     case JS_BOUND_FUNCTION_TYPE: {
    2355           0 :       JSBoundFunction bound_function = JSBoundFunction::cast(*this);
    2356           0 :       accumulator->Add("<JSBoundFunction");
    2357             :       accumulator->Add(" (BoundTargetFunction %p)>",
    2358             :                        reinterpret_cast<void*>(
    2359           0 :                            bound_function->bound_target_function().ptr()));
    2360             :       break;
    2361             :     }
    2362             :     case JS_WEAK_MAP_TYPE: {
    2363           0 :       accumulator->Add("<JSWeakMap>");
    2364           0 :       break;
    2365             :     }
    2366             :     case JS_WEAK_SET_TYPE: {
    2367           0 :       accumulator->Add("<JSWeakSet>");
    2368           0 :       break;
    2369             :     }
    2370             :     case JS_REGEXP_TYPE: {
    2371          18 :       accumulator->Add("<JSRegExp");
    2372             :       JSRegExp regexp = JSRegExp::cast(*this);
    2373          36 :       if (regexp->source()->IsString()) {
    2374          18 :         accumulator->Add(" ");
    2375          18 :         String::cast(regexp->source())->StringShortPrint(accumulator);
    2376             :       }
    2377          18 :       accumulator->Add(">");
    2378             : 
    2379             :       break;
    2380             :     }
    2381             :     case JS_FUNCTION_TYPE: {
    2382       20500 :       JSFunction function = JSFunction::cast(*this);
    2383       20500 :       Object fun_name = function->shared()->DebugName();
    2384             :       bool printed = false;
    2385       20500 :       if (fun_name->IsString()) {
    2386             :         String str = String::cast(fun_name);
    2387       20500 :         if (str->length() > 0) {
    2388       15832 :           accumulator->Add("<JSFunction ");
    2389       15832 :           accumulator->Put(str);
    2390             :           printed = true;
    2391             :         }
    2392             :       }
    2393       20500 :       if (!printed) {
    2394        4668 :         accumulator->Add("<JSFunction");
    2395             :       }
    2396       20500 :       if (FLAG_trace_file_names) {
    2397           0 :         Object source_name = Script::cast(function->shared()->script())->name();
    2398           0 :         if (source_name->IsString()) {
    2399             :           String str = String::cast(source_name);
    2400           0 :           if (str->length() > 0) {
    2401           0 :             accumulator->Add(" <");
    2402           0 :             accumulator->Put(str);
    2403           0 :             accumulator->Add(">");
    2404             :           }
    2405             :         }
    2406             :       }
    2407             :       accumulator->Add(" (sfi = %p)",
    2408       41000 :                        reinterpret_cast<void*>(function->shared().ptr()));
    2409       20500 :       accumulator->Put('>');
    2410             :       break;
    2411             :     }
    2412             :     case JS_GENERATOR_OBJECT_TYPE: {
    2413           0 :       accumulator->Add("<JSGenerator>");
    2414           0 :       break;
    2415             :     }
    2416             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE: {
    2417           0 :       accumulator->Add("<JSAsyncFunctionObject>");
    2418           0 :       break;
    2419             :     }
    2420             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE: {
    2421           0 :       accumulator->Add("<JS AsyncGenerator>");
    2422           0 :       break;
    2423             :     }
    2424             : 
    2425             :     // All other JSObjects are rather similar to each other (JSObject,
    2426             :     // JSGlobalProxy, JSGlobalObject, JSUndetectable, JSValue).
    2427             :     default: {
    2428       11059 :       Map map_of_this = map();
    2429             :       Heap* heap = GetHeap();
    2430       11059 :       Object constructor = map_of_this->GetConstructor();
    2431             :       bool printed = false;
    2432       22118 :       if (constructor->IsHeapObject() &&
    2433       11059 :           !heap->Contains(HeapObject::cast(constructor))) {
    2434           0 :         accumulator->Add("!!!INVALID CONSTRUCTOR!!!");
    2435             :       } else {
    2436       11059 :         bool global_object = IsJSGlobalProxy();
    2437       11059 :         if (constructor->IsJSFunction()) {
    2438       11059 :           if (!heap->Contains(JSFunction::cast(constructor)->shared())) {
    2439           0 :             accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!");
    2440             :           } else {
    2441             :             String constructor_name =
    2442       11059 :                 JSFunction::cast(constructor)->shared()->Name();
    2443       11059 :             if (constructor_name->length() > 0) {
    2444        9666 :               accumulator->Add(global_object ? "<GlobalObject " : "<");
    2445        9666 :               accumulator->Put(constructor_name);
    2446             :               accumulator->Add(
    2447             :                   " %smap = %p",
    2448        9666 :                   map_of_this->is_deprecated() ? "deprecated-" : "",
    2449        9666 :                   map_of_this);
    2450             :               printed = true;
    2451             :             }
    2452             :           }
    2453           0 :         } else if (constructor->IsFunctionTemplateInfo()) {
    2454           0 :           accumulator->Add(global_object ? "<RemoteObject>" : "<RemoteObject>");
    2455             :           printed = true;
    2456             :         }
    2457       11059 :         if (!printed) {
    2458        1393 :           accumulator->Add("<JS%sObject", global_object ? "Global " : "");
    2459             :         }
    2460             :       }
    2461       22118 :       if (IsJSValue()) {
    2462          84 :         accumulator->Add(" value = ");
    2463          84 :         JSValue::cast(*this)->value()->ShortPrint(accumulator);
    2464             :       }
    2465       11059 :       accumulator->Put('>');
    2466             :       break;
    2467             :     }
    2468             :   }
    2469       32568 : }
    2470             : 
    2471           0 : void JSObject::PrintElementsTransition(FILE* file, Handle<JSObject> object,
    2472             :                                        ElementsKind from_kind,
    2473             :                                        Handle<FixedArrayBase> from_elements,
    2474             :                                        ElementsKind to_kind,
    2475             :                                        Handle<FixedArrayBase> to_elements) {
    2476           0 :   if (from_kind != to_kind) {
    2477           0 :     OFStream os(file);
    2478           0 :     os << "elements transition [" << ElementsKindToString(from_kind) << " -> "
    2479           0 :        << ElementsKindToString(to_kind) << "] in ";
    2480           0 :     JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
    2481           0 :     PrintF(file, " for ");
    2482           0 :     object->ShortPrint(file);
    2483           0 :     PrintF(file, " from ");
    2484           0 :     from_elements->ShortPrint(file);
    2485           0 :     PrintF(file, " to ");
    2486           0 :     to_elements->ShortPrint(file);
    2487           0 :     PrintF(file, "\n");
    2488             :   }
    2489           0 : }
    2490             : 
    2491           0 : void JSObject::PrintInstanceMigration(FILE* file, Map original_map,
    2492             :                                       Map new_map) {
    2493           0 :   if (new_map->is_dictionary_map()) {
    2494           0 :     PrintF(file, "[migrating to slow]\n");
    2495           0 :     return;
    2496             :   }
    2497           0 :   PrintF(file, "[migrating]");
    2498           0 :   DescriptorArray o = original_map->instance_descriptors();
    2499           0 :   DescriptorArray n = new_map->instance_descriptors();
    2500           0 :   for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
    2501           0 :     Representation o_r = o->GetDetails(i).representation();
    2502           0 :     Representation n_r = n->GetDetails(i).representation();
    2503           0 :     if (!o_r.Equals(n_r)) {
    2504           0 :       String::cast(o->GetKey(i))->PrintOn(file);
    2505           0 :       PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
    2506           0 :     } else if (o->GetDetails(i).location() == kDescriptor &&
    2507           0 :                n->GetDetails(i).location() == kField) {
    2508           0 :       Name name = o->GetKey(i);
    2509           0 :       if (name->IsString()) {
    2510           0 :         String::cast(name)->PrintOn(file);
    2511             :       } else {
    2512           0 :         PrintF(file, "{symbol %p}", reinterpret_cast<void*>(name.ptr()));
    2513             :       }
    2514           0 :       PrintF(file, " ");
    2515             :     }
    2516             :   }
    2517           0 :   if (original_map->elements_kind() != new_map->elements_kind()) {
    2518             :     PrintF(file, "elements_kind[%i->%i]", original_map->elements_kind(),
    2519           0 :            new_map->elements_kind());
    2520             :   }
    2521           0 :   PrintF(file, "\n");
    2522             : }
    2523             : 
    2524      138325 : bool JSObject::IsUnmodifiedApiObject(FullObjectSlot o) {
    2525      138325 :   Object object = *o;
    2526      138325 :   if (object->IsSmi()) return false;
    2527             :   HeapObject heap_object = HeapObject::cast(object);
    2528      138325 :   if (!object->IsJSObject()) return false;
    2529       26695 :   JSObject js_object = JSObject::cast(object);
    2530       26695 :   if (!js_object->IsDroppableApiWrapper()) return false;
    2531          66 :   Object maybe_constructor = js_object->map()->GetConstructor();
    2532          66 :   if (!maybe_constructor->IsJSFunction()) return false;
    2533          66 :   JSFunction constructor = JSFunction::cast(maybe_constructor);
    2534         132 :   if (js_object->elements()->length() != 0) return false;
    2535             : 
    2536         122 :   return constructor->initial_map() == heap_object->map();
    2537             : }
    2538             : 
    2539             : // static
    2540     3090181 : void JSObject::UpdatePrototypeUserRegistration(Handle<Map> old_map,
    2541             :                                                Handle<Map> new_map,
    2542             :                                                Isolate* isolate) {
    2543             :   DCHECK(old_map->is_prototype_map());
    2544             :   DCHECK(new_map->is_prototype_map());
    2545     3090181 :   bool was_registered = JSObject::UnregisterPrototypeUser(old_map, isolate);
    2546     3090182 :   new_map->set_prototype_info(old_map->prototype_info());
    2547     3090182 :   old_map->set_prototype_info(Smi::kZero);
    2548     3090183 :   if (FLAG_trace_prototype_users) {
    2549             :     PrintF("Moving prototype_info %p from map %p to map %p.\n",
    2550             :            reinterpret_cast<void*>(new_map->prototype_info()->ptr()),
    2551             :            reinterpret_cast<void*>(old_map->ptr()),
    2552           0 :            reinterpret_cast<void*>(new_map->ptr()));
    2553             :   }
    2554     3090183 :   if (was_registered) {
    2555      383247 :     if (new_map->prototype_info()->IsPrototypeInfo()) {
    2556             :       // The new map isn't registered with its prototype yet; reflect this fact
    2557             :       // in the PrototypeInfo it just inherited from the old map.
    2558             :       PrototypeInfo::cast(new_map->prototype_info())
    2559             :           ->set_registry_slot(PrototypeInfo::UNREGISTERED);
    2560             :     }
    2561      191624 :     JSObject::LazyRegisterPrototypeUser(new_map, isolate);
    2562             :   }
    2563     3090183 : }
    2564             : 
    2565             : // static
    2566    28763079 : void JSObject::NotifyMapChange(Handle<Map> old_map, Handle<Map> new_map,
    2567             :                                Isolate* isolate) {
    2568    57526161 :   if (!old_map->is_prototype_map()) return;
    2569             : 
    2570             :   InvalidatePrototypeChains(*old_map);
    2571             : 
    2572             :   // If the map was registered with its prototype before, ensure that it
    2573             :   // registers with its new prototype now. This preserves the invariant that
    2574             :   // when a map on a prototype chain is registered with its prototype, then
    2575             :   // all prototypes further up the chain are also registered with their
    2576             :   // respective prototypes.
    2577     3090182 :   UpdatePrototypeUserRegistration(old_map, new_map, isolate);
    2578             : }
    2579             : 
    2580             : namespace {
    2581             : // To migrate a fast instance to a fast map:
    2582             : // - First check whether the instance needs to be rewritten. If not, simply
    2583             : //   change the map.
    2584             : // - Otherwise, allocate a fixed array large enough to hold all fields, in
    2585             : //   addition to unused space.
    2586             : // - Copy all existing properties in, in the following order: backing store
    2587             : //   properties, unused fields, inobject properties.
    2588             : // - If all allocation succeeded, commit the state atomically:
    2589             : //   * Copy inobject properties from the backing store back into the object.
    2590             : //   * Trim the difference in instance size of the object. This also cleanly
    2591             : //     frees inobject properties that moved to the backing store.
    2592             : //   * If there are properties left in the backing store, trim of the space used
    2593             : //     to temporarily store the inobject properties.
    2594             : //   * If there are properties left in the backing store, install the backing
    2595             : //     store.
    2596    27113316 : void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
    2597             :   Isolate* isolate = object->GetIsolate();
    2598             :   Handle<Map> old_map(object->map(), isolate);
    2599             :   // In case of a regular transition.
    2600    54226641 :   if (new_map->GetBackPointer() == *old_map) {
    2601             :     // If the map does not add named properties, simply set the map.
    2602    12814197 :     if (old_map->NumberOfOwnDescriptors() ==
    2603             :         new_map->NumberOfOwnDescriptors()) {
    2604      525271 :       object->synchronized_set_map(*new_map);
    2605      525269 :       return;
    2606             :     }
    2607             : 
    2608    12288924 :     PropertyDetails details = new_map->GetLastDescriptorDetails();
    2609    12288924 :     int target_index = details.field_index() - new_map->GetInObjectProperties();
    2610    24577848 :     int property_array_length = object->property_array()->length();
    2611    28060759 :     bool have_space = old_map->UnusedPropertyFields() > 0 ||
    2612     6944046 :                       (details.location() == kField && target_index >= 0 &&
    2613     3472023 :                        property_array_length > target_index);
    2614             :     // Either new_map adds an kDescriptor property, or a kField property for
    2615             :     // which there is still space, and which does not require a mutable double
    2616             :     // box (an out-of-object double).
    2617    24577852 :     if (details.location() == kDescriptor ||
    2618    13725578 :         (have_space && ((FLAG_unbox_double_fields && target_index < 0) ||
    2619             :                         !details.representation().IsDouble()))) {
    2620     8814143 :       object->synchronized_set_map(*new_map);
    2621     8814142 :       return;
    2622             :     }
    2623             : 
    2624             :     // If there is still space in the object, we need to allocate a mutable
    2625             :     // double box.
    2626     3474783 :     if (have_space) {
    2627             :       FieldIndex index =
    2628        6016 :           FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
    2629             :       DCHECK(details.representation().IsDouble());
    2630             :       DCHECK(!new_map->IsUnboxedDoubleField(index));
    2631             :       auto value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    2632        6016 :       object->RawFastPropertyAtPut(index, *value);
    2633        3008 :       object->synchronized_set_map(*new_map);
    2634             :       return;
    2635             :     }
    2636             : 
    2637             :     // This migration is a transition from a map that has run out of property
    2638             :     // space. Extend the backing store.
    2639     3471775 :     int grow_by = new_map->UnusedPropertyFields() + 1;
    2640     6943550 :     Handle<PropertyArray> old_storage(object->property_array(), isolate);
    2641             :     Handle<PropertyArray> new_storage =
    2642     3471775 :         isolate->factory()->CopyPropertyArrayAndGrow(old_storage, grow_by);
    2643             : 
    2644             :     // Properly initialize newly added property.
    2645             :     Handle<Object> value;
    2646     3471775 :     if (details.representation().IsDouble()) {
    2647             :       value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    2648             :     } else {
    2649             :       value = isolate->factory()->uninitialized_value();
    2650             :     }
    2651             :     DCHECK_EQ(kField, details.location());
    2652             :     DCHECK_EQ(kData, details.kind());
    2653             :     DCHECK_GE(target_index, 0);  // Must be a backing store index.
    2654     3471775 :     new_storage->set(target_index, *value);
    2655             : 
    2656             :     // From here on we cannot fail and we shouldn't GC anymore.
    2657             :     DisallowHeapAllocation no_allocation;
    2658             : 
    2659             :     // Set the new property value and do the map transition.
    2660     6943550 :     object->SetProperties(*new_storage);
    2661     3471775 :     object->synchronized_set_map(*new_map);
    2662     3471775 :     return;
    2663             :   }
    2664             : 
    2665             :   int old_number_of_fields;
    2666    14299124 :   int number_of_fields = new_map->NumberOfFields();
    2667    14299127 :   int inobject = new_map->GetInObjectProperties();
    2668    14299127 :   int unused = new_map->UnusedPropertyFields();
    2669             : 
    2670             :   // Nothing to do if no functions were converted to fields and no smis were
    2671             :   // converted to doubles.
    2672    14299132 :   if (!old_map->InstancesNeedRewriting(*new_map, number_of_fields, inobject,
    2673    14299128 :                                        unused, &old_number_of_fields)) {
    2674     5351956 :     object->synchronized_set_map(*new_map);
    2675     5351955 :     return;
    2676             :   }
    2677             : 
    2678     8947175 :   int total_size = number_of_fields + unused;
    2679     8947175 :   int external = total_size - inobject;
    2680     8947175 :   Handle<PropertyArray> array = isolate->factory()->NewPropertyArray(external);
    2681             : 
    2682             :   // We use this array to temporarily store the inobject properties.
    2683             :   Handle<FixedArray> inobject_props =
    2684     8947176 :       isolate->factory()->NewFixedArray(inobject);
    2685             : 
    2686             :   Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors(),
    2687    17894343 :                                           isolate);
    2688             :   Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors(),
    2689    17894347 :                                           isolate);
    2690             :   int old_nof = old_map->NumberOfOwnDescriptors();
    2691             :   int new_nof = new_map->NumberOfOwnDescriptors();
    2692             : 
    2693             :   // This method only supports generalizing instances to at least the same
    2694             :   // number of properties.
    2695             :   DCHECK(old_nof <= new_nof);
    2696             : 
    2697    87321708 :   for (int i = 0; i < old_nof; i++) {
    2698    78374531 :     PropertyDetails details = new_descriptors->GetDetails(i);
    2699    78374524 :     if (details.location() != kField) continue;
    2700             :     DCHECK_EQ(kData, details.kind());
    2701    74767309 :     PropertyDetails old_details = old_descriptors->GetDetails(i);
    2702             :     Representation old_representation = old_details.representation();
    2703             :     Representation representation = details.representation();
    2704             :     Handle<Object> value;
    2705    74767309 :     if (old_details.location() == kDescriptor) {
    2706       15978 :       if (old_details.kind() == kAccessor) {
    2707             :         // In case of kAccessor -> kData property reconfiguration, the property
    2708             :         // must already be prepared for data of certain type.
    2709             :         DCHECK(!details.representation().IsNone());
    2710       15978 :         if (details.representation().IsDouble()) {
    2711             :           value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    2712             :         } else {
    2713             :           value = isolate->factory()->uninitialized_value();
    2714             :         }
    2715             :       } else {
    2716             :         DCHECK_EQ(kData, old_details.kind());
    2717           0 :         value = handle(old_descriptors->GetStrongValue(i), isolate);
    2718             :         DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
    2719             :       }
    2720             :     } else {
    2721             :       DCHECK_EQ(kField, old_details.location());
    2722    74751330 :       FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
    2723    74751328 :       if (object->IsUnboxedDoubleField(index)) {
    2724             :         uint64_t old_bits = object->RawFastDoublePropertyAsBitsAt(index);
    2725        2943 :         if (representation.IsDouble()) {
    2726        2517 :           value = isolate->factory()->NewMutableHeapNumberFromBits(old_bits);
    2727             :         } else {
    2728         426 :           value = isolate->factory()->NewHeapNumberFromBits(old_bits);
    2729             :         }
    2730             :       } else {
    2731   149496767 :         value = handle(object->RawFastPropertyAt(index), isolate);
    2732    74748383 :         if (!old_representation.IsDouble() && representation.IsDouble()) {
    2733             :           DCHECK_IMPLIES(old_representation.IsNone(),
    2734             :                          value->IsUninitialized(isolate));
    2735        2008 :           value = Object::NewStorageFor(isolate, value, representation);
    2736    74746375 :         } else if (old_representation.IsDouble() &&
    2737             :                    !representation.IsDouble()) {
    2738         485 :           value = Object::WrapForRead(isolate, value, old_representation);
    2739             :         }
    2740             :       }
    2741             :     }
    2742             :     DCHECK(!(representation.IsDouble() && value->IsSmi()));
    2743   149534615 :     int target_index = new_descriptors->GetFieldIndex(i);
    2744    74767308 :     if (target_index < inobject) {
    2745     3914889 :       inobject_props->set(target_index, *value);
    2746             :     } else {
    2747   141704837 :       array->set(target_index - inobject, *value);
    2748             :     }
    2749             :   }
    2750             : 
    2751     8928729 :   for (int i = old_nof; i < new_nof; i++) {
    2752     8928729 :     PropertyDetails details = new_descriptors->GetDetails(i);
    2753     8928729 :     if (details.location() != kField) continue;
    2754             :     DCHECK_EQ(kData, details.kind());
    2755             :     Handle<Object> value;
    2756     8928729 :     if (details.representation().IsDouble()) {
    2757             :       value = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    2758             :     } else {
    2759             :       value = isolate->factory()->uninitialized_value();
    2760             :     }
    2761    17857458 :     int target_index = new_descriptors->GetFieldIndex(i);
    2762     8928729 :     if (target_index < inobject) {
    2763     5091087 :       inobject_props->set(target_index, *value);
    2764             :     } else {
    2765     7675284 :       array->set(target_index - inobject, *value);
    2766             :     }
    2767             :   }
    2768             : 
    2769             :   // From here on we cannot fail and we shouldn't GC anymore.
    2770             :   DisallowHeapAllocation no_allocation;
    2771             : 
    2772     8947176 :   Heap* heap = isolate->heap();
    2773             : 
    2774             :   int old_instance_size = old_map->instance_size();
    2775             : 
    2776     8947176 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    2777             : 
    2778             :   // Copy (real) inobject properties. If necessary, stop at number_of_fields to
    2779             :   // avoid overwriting |one_pointer_filler_map|.
    2780             :   int limit = Min(inobject, number_of_fields);
    2781    17953151 :   for (int i = 0; i < limit; i++) {
    2782     9005976 :     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    2783             :     Object value = inobject_props->get(i);
    2784             :     // Can't use JSObject::FastPropertyAtPut() because proper map was not set
    2785             :     // yet.
    2786     9005975 :     if (new_map->IsUnboxedDoubleField(index)) {
    2787             :       DCHECK(value->IsMutableHeapNumber());
    2788             :       // Ensure that all bits of the double value are preserved.
    2789             :       object->RawFastDoublePropertyAsBitsAtPut(
    2790             :           index, MutableHeapNumber::cast(value)->value_as_bits());
    2791        7889 :       if (i < old_number_of_fields && !old_map->IsUnboxedDoubleField(index)) {
    2792             :         // Transition from tagged to untagged slot.
    2793             :         heap->ClearRecordedSlot(*object,
    2794        1423 :                                 HeapObject::RawField(*object, index.offset()));
    2795             :       } else {
    2796             : #ifdef DEBUG
    2797             :         heap->VerifyClearedSlot(*object,
    2798             :                                 HeapObject::RawField(*object, index.offset()));
    2799             : #endif
    2800             :       }
    2801             :     } else {
    2802     9002026 :       object->RawFastPropertyAtPut(index, value);
    2803             :     }
    2804             :   }
    2805             : 
    2806    17894349 :   object->SetProperties(*array);
    2807             : 
    2808             :   // Create filler object past the new instance size.
    2809             :   int new_instance_size = new_map->instance_size();
    2810     8947175 :   int instance_size_delta = old_instance_size - new_instance_size;
    2811             :   DCHECK_GE(instance_size_delta, 0);
    2812             : 
    2813     8947175 :   if (instance_size_delta > 0) {
    2814             :     Address address = object->address();
    2815             :     heap->CreateFillerObjectAt(address + new_instance_size, instance_size_delta,
    2816          15 :                                ClearRecordedSlots::kYes);
    2817             :   }
    2818             : 
    2819             :   // We are storing the new map using release store after creating a filler for
    2820             :   // the left-over space to avoid races with the sweeper thread.
    2821     8947174 :   object->synchronized_set_map(*new_map);
    2822             : }
    2823             : 
    2824      673675 : void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
    2825             :                        int expected_additional_properties) {
    2826             :   // The global object is always normalized.
    2827             :   DCHECK(!object->IsJSGlobalObject());
    2828             :   // JSGlobalProxy must never be normalized
    2829             :   DCHECK(!object->IsJSGlobalProxy());
    2830             : 
    2831             :   DCHECK_IMPLIES(new_map->is_prototype_map(),
    2832             :                  Map::IsPrototypeChainInvalidated(*new_map));
    2833             : 
    2834             :   Isolate* isolate = object->GetIsolate();
    2835             :   HandleScope scope(isolate);
    2836             :   Handle<Map> map(object->map(), isolate);
    2837             : 
    2838             :   // Allocate new content.
    2839             :   int real_size = map->NumberOfOwnDescriptors();
    2840             :   int property_count = real_size;
    2841      673677 :   if (expected_additional_properties > 0) {
    2842         552 :     property_count += expected_additional_properties;
    2843             :   } else {
    2844             :     // Make space for two more properties.
    2845      673125 :     property_count += NameDictionary::kInitialCapacity;
    2846             :   }
    2847             :   Handle<NameDictionary> dictionary =
    2848      673677 :       NameDictionary::New(isolate, property_count);
    2849             : 
    2850     1347353 :   Handle<DescriptorArray> descs(map->instance_descriptors(), isolate);
    2851     2642135 :   for (int i = 0; i < real_size; i++) {
    2852     1968459 :     PropertyDetails details = descs->GetDetails(i);
    2853     3936914 :     Handle<Name> key(descs->GetKey(i), isolate);
    2854             :     Handle<Object> value;
    2855     1968455 :     if (details.location() == kField) {
    2856     1701945 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    2857     1701949 :       if (details.kind() == kData) {
    2858     1701948 :         if (object->IsUnboxedDoubleField(index)) {
    2859             :           double old_value = object->RawFastDoublePropertyAt(index);
    2860         864 :           value = isolate->factory()->NewHeapNumber(old_value);
    2861             :         } else {
    2862     3402170 :           value = handle(object->RawFastPropertyAt(index), isolate);
    2863     1701085 :           if (details.representation().IsDouble()) {
    2864             :             DCHECK(value->IsMutableHeapNumber());
    2865         598 :             double old_value = Handle<MutableHeapNumber>::cast(value)->value();
    2866         299 :             value = isolate->factory()->NewHeapNumber(old_value);
    2867             :           }
    2868             :         }
    2869             :       } else {
    2870             :         DCHECK_EQ(kAccessor, details.kind());
    2871           0 :         value = handle(object->RawFastPropertyAt(index), isolate);
    2872             :       }
    2873             : 
    2874             :     } else {
    2875             :       DCHECK_EQ(kDescriptor, details.location());
    2876      533020 :       value = handle(descs->GetStrongValue(i), isolate);
    2877             :     }
    2878             :     DCHECK(!value.is_null());
    2879             :     PropertyDetails d(details.kind(), details.attributes(),
    2880             :                       PropertyCellType::kNoCell);
    2881     1968459 :     dictionary = NameDictionary::Add(isolate, dictionary, key, value, d);
    2882             :   }
    2883             : 
    2884             :   // Copy the next enumeration index from instance descriptor.
    2885      673677 :   dictionary->SetNextEnumerationIndex(real_size + 1);
    2886             : 
    2887             :   // From here on we cannot fail and we shouldn't GC anymore.
    2888             :   DisallowHeapAllocation no_allocation;
    2889             : 
    2890      673677 :   Heap* heap = isolate->heap();
    2891             :   int old_instance_size = map->instance_size();
    2892      673677 :   heap->NotifyObjectLayoutChange(*object, old_instance_size, no_allocation);
    2893             : 
    2894             :   // Resize the object in the heap if necessary.
    2895             :   int new_instance_size = new_map->instance_size();
    2896      673677 :   int instance_size_delta = old_instance_size - new_instance_size;
    2897             :   DCHECK_GE(instance_size_delta, 0);
    2898             : 
    2899      673677 :   if (instance_size_delta > 0) {
    2900             :     heap->CreateFillerObjectAt(object->address() + new_instance_size,
    2901      299451 :                                instance_size_delta, ClearRecordedSlots::kYes);
    2902             :   }
    2903             : 
    2904             :   // We are storing the new map using release store after creating a filler for
    2905             :   // the left-over space to avoid races with the sweeper thread.
    2906      673677 :   object->synchronized_set_map(*new_map);
    2907             : 
    2908     1347354 :   object->SetProperties(*dictionary);
    2909             : 
    2910             :   // Ensure that in-object space of slow-mode object does not contain random
    2911             :   // garbage.
    2912      673677 :   int inobject_properties = new_map->GetInObjectProperties();
    2913      673677 :   if (inobject_properties) {
    2914             :     Heap* heap = isolate->heap();
    2915             :     heap->ClearRecordedSlotRange(
    2916             :         object->address() + map->GetInObjectPropertyOffset(0),
    2917      559754 :         object->address() + new_instance_size);
    2918             : 
    2919     1496352 :     for (int i = 0; i < inobject_properties; i++) {
    2920     1216475 :       FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
    2921     1216475 :       object->RawFastPropertyAtPut(index, Smi::kZero);
    2922             :     }
    2923             :   }
    2924             : 
    2925      673677 :   isolate->counters()->props_to_dictionary()->Increment();
    2926             : 
    2927             : #ifdef DEBUG
    2928             :   if (FLAG_trace_normalization) {
    2929             :     StdoutStream os;
    2930             :     os << "Object properties have been normalized:\n";
    2931             :     object->Print(os);
    2932             :   }
    2933             : #endif
    2934      673677 : }
    2935             : 
    2936             : }  // namespace
    2937             : 
    2938    31283674 : void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
    2939             :                             int expected_additional_properties) {
    2940    62567366 :   if (object->map() == *new_map) return;
    2941             :   Handle<Map> old_map(object->map(), object->GetIsolate());
    2942    28338592 :   NotifyMapChange(old_map, new_map, object->GetIsolate());
    2943             : 
    2944    28338589 :   if (old_map->is_dictionary_map()) {
    2945             :     // For slow-to-fast migrations JSObject::MigrateSlowToFast()
    2946             :     // must be used instead.
    2947      551597 :     CHECK(new_map->is_dictionary_map());
    2948             : 
    2949             :     // Slow-to-slow migration is trivial.
    2950      551597 :     object->synchronized_set_map(*new_map);
    2951    27786992 :   } else if (!new_map->is_dictionary_map()) {
    2952    27113314 :     MigrateFastToFast(object, new_map);
    2953    27113324 :     if (old_map->is_prototype_map()) {
    2954             :       DCHECK(!old_map->is_stable());
    2955             :       DCHECK(new_map->is_stable());
    2956             :       DCHECK(new_map->owns_descriptors());
    2957             :       DCHECK(old_map->owns_descriptors());
    2958             :       // Transfer ownership to the new map. Keep the descriptor pointer of the
    2959             :       // old map intact because the concurrent marker might be iterating the
    2960             :       // object with the old map.
    2961     2669133 :       old_map->set_owns_descriptors(false);
    2962             :       DCHECK(old_map->is_abandoned_prototype_map());
    2963             :       // Ensure that no transition was inserted for prototype migrations.
    2964             :       DCHECK_EQ(0, TransitionsAccessor(object->GetIsolate(), old_map)
    2965             :                        .NumberOfTransitions());
    2966             :       DCHECK(new_map->GetBackPointer()->IsUndefined());
    2967             :       DCHECK(object->map() != *old_map);
    2968             :     }
    2969             :   } else {
    2970      673677 :     MigrateFastToSlow(object, new_map, expected_additional_properties);
    2971             :   }
    2972             : 
    2973             :   // Careful: Don't allocate here!
    2974             :   // For some callers of this method, |object| might be in an inconsistent
    2975             :   // state now: the new map might have a new elements_kind, but the object's
    2976             :   // elements pointer hasn't been updated yet. Callers will fix this, but in
    2977             :   // the meantime, (indirectly) calling JSObjectVerify() must be avoided.
    2978             :   // When adding code here, add a DisallowHeapAllocation too.
    2979             : }
    2980             : 
    2981      292643 : void JSObject::ForceSetPrototype(Handle<JSObject> object,
    2982             :                                  Handle<Object> proto) {
    2983             :   // object.__proto__ = proto;
    2984             :   Handle<Map> old_map = Handle<Map>(object->map(), object->GetIsolate());
    2985             :   Handle<Map> new_map =
    2986      292643 :       Map::Copy(object->GetIsolate(), old_map, "ForceSetPrototype");
    2987      292643 :   Map::SetPrototype(object->GetIsolate(), new_map, proto);
    2988      292643 :   JSObject::MigrateToMap(object, new_map);
    2989      292643 : }
    2990             : 
    2991      193268 : Maybe<bool> JSObject::SetPropertyWithInterceptor(
    2992             :     LookupIterator* it, Maybe<ShouldThrow> should_throw, Handle<Object> value) {
    2993             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    2994             :   return SetPropertyWithInterceptorInternal(it, it->GetInterceptor(),
    2995      193268 :                                             should_throw, value);
    2996             : }
    2997             : 
    2998     1184126 : Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
    2999             :                                                ElementsKind to_kind) {
    3000             :   Handle<Map> map(object->map(), object->GetIsolate());
    3001     2368254 :   return Map::TransitionElementsTo(object->GetIsolate(), map, to_kind);
    3002             : }
    3003             : 
    3004             : // static
    3005           0 : MaybeHandle<NativeContext> JSObject::GetFunctionRealm(Handle<JSObject> object) {
    3006             :   DCHECK(object->map()->is_constructor());
    3007             :   DCHECK(!object->IsJSFunction());
    3008           0 :   return object->GetCreationContext();
    3009             : }
    3010             : 
    3011     7709205 : void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
    3012             :   DCHECK(object->map()->GetInObjectProperties() ==
    3013             :          map->GetInObjectProperties());
    3014             :   ElementsKind obj_kind = object->map()->elements_kind();
    3015             :   ElementsKind map_kind = map->elements_kind();
    3016     7709205 :   if (map_kind != obj_kind) {
    3017             :     ElementsKind to_kind = GetMoreGeneralElementsKind(map_kind, obj_kind);
    3018          27 :     if (IsDictionaryElementsKind(obj_kind)) {
    3019             :       to_kind = obj_kind;
    3020             :     }
    3021          27 :     if (IsDictionaryElementsKind(to_kind)) {
    3022          27 :       NormalizeElements(object);
    3023             :     } else {
    3024           0 :       TransitionElementsKind(object, to_kind);
    3025             :     }
    3026          54 :     map = Map::ReconfigureElementsKind(object->GetIsolate(), map, to_kind);
    3027             :   }
    3028     7709205 :   int number_of_fields = map->NumberOfFields();
    3029     7709205 :   int inobject = map->GetInObjectProperties();
    3030     7709205 :   int unused = map->UnusedPropertyFields();
    3031     7709205 :   int total_size = number_of_fields + unused;
    3032     7709205 :   int external = total_size - inobject;
    3033             :   // Allocate mutable double boxes if necessary. It is always necessary if we
    3034             :   // have external properties, but is also necessary if we only have inobject
    3035             :   // properties but don't unbox double fields.
    3036     7709205 :   if (!FLAG_unbox_double_fields || external > 0) {
    3037             :     Isolate* isolate = object->GetIsolate();
    3038             : 
    3039     5851080 :     Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
    3040             :     Handle<FixedArray> storage;
    3041             :     if (!FLAG_unbox_double_fields) {
    3042             :       storage = isolate->factory()->NewFixedArray(inobject);
    3043             :     }
    3044             : 
    3045             :     Handle<PropertyArray> array =
    3046     2925540 :         isolate->factory()->NewPropertyArray(external);
    3047             : 
    3048    41730092 :     for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    3049    17939506 :       PropertyDetails details = descriptors->GetDetails(i);
    3050             :       Representation representation = details.representation();
    3051    35878904 :       if (!representation.IsDouble()) continue;
    3052        6097 :       FieldIndex index = FieldIndex::ForDescriptor(*map, i);
    3053        6097 :       if (map->IsUnboxedDoubleField(index)) continue;
    3054             :       auto box = isolate->factory()->NewMutableHeapNumberWithHoleNaN();
    3055         108 :       if (index.is_inobject()) {
    3056           0 :         storage->set(index.property_index(), *box);
    3057             :       } else {
    3058         216 :         array->set(index.outobject_array_index(), *box);
    3059             :       }
    3060             :     }
    3061             : 
    3062     5851080 :     object->SetProperties(*array);
    3063             : 
    3064             :     if (!FLAG_unbox_double_fields) {
    3065             :       for (int i = 0; i < inobject; i++) {
    3066             :         FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
    3067             :         Object value = storage->get(i);
    3068             :         object->RawFastPropertyAtPut(index, value);
    3069             :       }
    3070             :     }
    3071             :   }
    3072     7709205 :   object->synchronized_set_map(*map);
    3073     7709205 : }
    3074             : 
    3075        2275 : void JSObject::MigrateInstance(Handle<JSObject> object) {
    3076             :   Handle<Map> original_map(object->map(), object->GetIsolate());
    3077        2275 :   Handle<Map> map = Map::Update(object->GetIsolate(), original_map);
    3078        2275 :   map->set_is_migration_target(true);
    3079        2275 :   MigrateToMap(object, map);
    3080        2275 :   if (FLAG_trace_migration) {
    3081           0 :     object->PrintInstanceMigration(stdout, *original_map, *map);
    3082             :   }
    3083             : #if VERIFY_HEAP
    3084             :   if (FLAG_verify_heap) {
    3085             :     object->JSObjectVerify(object->GetIsolate());
    3086             :   }
    3087             : #endif
    3088        2275 : }
    3089             : 
    3090             : // static
    3091        6622 : bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
    3092             :   Isolate* isolate = object->GetIsolate();
    3093             :   DisallowDeoptimization no_deoptimization(isolate);
    3094             :   Handle<Map> original_map(object->map(), isolate);
    3095             :   Handle<Map> new_map;
    3096       13244 :   if (!Map::TryUpdate(isolate, original_map).ToHandle(&new_map)) {
    3097             :     return false;
    3098             :   }
    3099        6606 :   JSObject::MigrateToMap(object, new_map);
    3100        6606 :   if (FLAG_trace_migration && *original_map != object->map()) {
    3101           0 :     object->PrintInstanceMigration(stdout, *original_map, object->map());
    3102             :   }
    3103             : #if VERIFY_HEAP
    3104             :   if (FLAG_verify_heap) {
    3105             :     object->JSObjectVerify(isolate);
    3106             :   }
    3107             : #endif
    3108             :   return true;
    3109             : }
    3110             : 
    3111    18115818 : void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
    3112             :                            Handle<Name> name, Handle<Object> value,
    3113             :                            PropertyAttributes attributes) {
    3114             :   LookupIterator it(isolate, object, name, object,
    3115    18115818 :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    3116    18115820 :   CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
    3117             : #ifdef DEBUG
    3118             :   uint32_t index;
    3119             :   DCHECK(!object->IsJSProxy());
    3120             :   DCHECK(!name->AsArrayIndex(&index));
    3121             :   Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it);
    3122             :   DCHECK(maybe.IsJust());
    3123             :   DCHECK(!it.IsFound());
    3124             :   DCHECK(object->map()->is_extensible() || name->IsPrivate());
    3125             : #endif
    3126    18115820 :   CHECK(Object::AddDataProperty(&it, value, attributes,
    3127             :                                 Just(ShouldThrow::kThrowOnError),
    3128             :                                 StoreOrigin::kNamed)
    3129             :             .IsJust());
    3130    18115815 : }
    3131             : 
    3132      181323 : void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
    3133             :                            const char* name, Handle<Object> value,
    3134             :                            PropertyAttributes attributes) {
    3135             :   JSObject::AddProperty(isolate, object,
    3136             :                         isolate->factory()->InternalizeUtf8String(name), value,
    3137      362646 :                         attributes);
    3138      181323 : }
    3139             : 
    3140             : // Reconfigures a property to a data property with attributes, even if it is not
    3141             : // reconfigurable.
    3142             : // Requires a LookupIterator that does not look at the prototype chain beyond
    3143             : // hidden prototypes.
    3144    11650161 : MaybeHandle<Object> JSObject::DefineOwnPropertyIgnoreAttributes(
    3145             :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    3146             :     AccessorInfoHandling handling) {
    3147    11650161 :   MAYBE_RETURN_NULL(DefineOwnPropertyIgnoreAttributes(
    3148             :       it, value, attributes, Just(ShouldThrow::kThrowOnError), handling));
    3149    11650145 :   return value;
    3150             : }
    3151             : 
    3152    11954321 : Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
    3153    11976309 :     LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
    3154             :     Maybe<ShouldThrow> should_throw, AccessorInfoHandling handling) {
    3155    11954321 :   it->UpdateProtector();
    3156    11954336 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    3157             : 
    3158    23909898 :   for (; it->IsFound(); it->Next()) {
    3159      529335 :     switch (it->state()) {
    3160             :       case LookupIterator::JSPROXY:
    3161             :       case LookupIterator::NOT_FOUND:
    3162             :       case LookupIterator::TRANSITION:
    3163           0 :         UNREACHABLE();
    3164             : 
    3165             :       case LookupIterator::ACCESS_CHECK:
    3166         412 :         if (!it->HasAccess()) {
    3167           0 :           it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    3168           0 :           RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(), Nothing<bool>());
    3169             :           return Just(true);
    3170             :         }
    3171             :         break;
    3172             : 
    3173             :       // If there's an interceptor, try to store the property with the
    3174             :       // interceptor.
    3175             :       // In case of success, the attributes will have been reset to the default
    3176             :       // attributes of the interceptor, rather than the incoming attributes.
    3177             :       //
    3178             :       // TODO(verwaest): JSProxy afterwards verify the attributes that the
    3179             :       // JSProxy claims it has, and verifies that they are compatible. If not,
    3180             :       // they throw. Here we should do the same.
    3181             :       case LookupIterator::INTERCEPTOR:
    3182         207 :         if (handling == DONT_FORCE_FIELD) {
    3183             :           Maybe<bool> result =
    3184         207 :               JSObject::SetPropertyWithInterceptor(it, should_throw, value);
    3185         414 :           if (result.IsNothing() || result.FromJust()) return result;
    3186             :         }
    3187             :         break;
    3188             : 
    3189             :       case LookupIterator::ACCESSOR: {
    3190        5295 :         Handle<Object> accessors = it->GetAccessors();
    3191             : 
    3192             :         // Special handling for AccessorInfo, which behaves like a data
    3193             :         // property.
    3194       10590 :         if (accessors->IsAccessorInfo() && handling == DONT_FORCE_FIELD) {
    3195             :           PropertyAttributes current_attributes = it->property_attributes();
    3196             :           // Ensure the context isn't changed after calling into accessors.
    3197             :           AssertNoContextChange ncc(it->isolate());
    3198             : 
    3199             :           // Update the attributes before calling the setter. The setter may
    3200             :           // later change the shape of the property.
    3201        4688 :           if (current_attributes != attributes) {
    3202        1160 :             it->TransitionToAccessorPair(accessors, attributes);
    3203             :           }
    3204             : 
    3205        4688 :           return Object::SetPropertyWithAccessor(it, value, should_throw);
    3206             :         }
    3207             : 
    3208         607 :         it->ReconfigureDataProperty(value, attributes);
    3209             :         return Just(true);
    3210             :       }
    3211             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    3212             :         return Object::RedefineIncompatibleProperty(
    3213          18 :             it->isolate(), it->GetName(), value, should_throw);
    3214             : 
    3215             :       case LookupIterator::DATA: {
    3216             :         // Regular property update if the attributes match.
    3217      523410 :         if (it->property_attributes() == attributes) {
    3218      502057 :           return Object::SetDataProperty(it, value);
    3219             :         }
    3220             : 
    3221             :         // Special case: properties of typed arrays cannot be reconfigured to
    3222             :         // non-writable nor to non-enumerable.
    3223       40704 :         if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    3224             :           return Object::RedefineIncompatibleProperty(
    3225           0 :               it->isolate(), it->GetName(), value, should_throw);
    3226             :         }
    3227             : 
    3228             :         // Reconfigure the data property if the attributes mismatch.
    3229       21353 :         it->ReconfigureDataProperty(value, attributes);
    3230             : 
    3231             :         return Just(true);
    3232             :       }
    3233             :     }
    3234             :   }
    3235             : 
    3236             :   return Object::AddDataProperty(it, value, attributes, should_throw,
    3237    11425612 :                                  StoreOrigin::kNamed);
    3238             : }
    3239             : 
    3240     3945965 : MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
    3241             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    3242             :     PropertyAttributes attributes) {
    3243             :   DCHECK(!value->IsTheHole());
    3244     3945965 :   LookupIterator it(object, name, object, LookupIterator::OWN);
    3245     3945967 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    3246             : }
    3247             : 
    3248     2472318 : MaybeHandle<Object> JSObject::SetOwnElementIgnoreAttributes(
    3249             :     Handle<JSObject> object, uint32_t index, Handle<Object> value,
    3250             :     PropertyAttributes attributes) {
    3251             :   Isolate* isolate = object->GetIsolate();
    3252             :   LookupIterator it(isolate, object, index, object, LookupIterator::OWN);
    3253     2472318 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    3254             : }
    3255             : 
    3256      432289 : MaybeHandle<Object> JSObject::DefinePropertyOrElementIgnoreAttributes(
    3257             :     Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
    3258             :     PropertyAttributes attributes) {
    3259             :   Isolate* isolate = object->GetIsolate();
    3260             :   LookupIterator it = LookupIterator::PropertyOrElement(
    3261      432289 :       isolate, object, name, object, LookupIterator::OWN);
    3262      432289 :   return DefineOwnPropertyIgnoreAttributes(&it, value, attributes);
    3263             : }
    3264             : 
    3265      250405 : Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithInterceptor(
    3266             :     LookupIterator* it) {
    3267      250405 :   return GetPropertyAttributesWithInterceptorInternal(it, it->GetInterceptor());
    3268             : }
    3269             : 
    3270      676739 : void JSObject::NormalizeProperties(Handle<JSObject> object,
    3271             :                                    PropertyNormalizationMode mode,
    3272             :                                    int expected_additional_properties,
    3273             :                                    const char* reason) {
    3274      930945 :   if (!object->HasFastProperties()) return;
    3275             : 
    3276             :   Handle<Map> map(object->map(), object->GetIsolate());
    3277      422534 :   Handle<Map> new_map = Map::Normalize(object->GetIsolate(), map, mode, reason);
    3278             : 
    3279      422534 :   MigrateToMap(object, new_map, expected_additional_properties);
    3280             : }
    3281             : 
    3282     1090379 : void JSObject::MigrateSlowToFast(Handle<JSObject> object,
    3283             :                                  int unused_property_fields,
    3284             :                                  const char* reason) {
    3285     1909791 :   if (object->HasFastProperties()) return;
    3286             :   DCHECK(!object->IsJSGlobalObject());
    3287         409 :   Isolate* isolate = object->GetIsolate();
    3288             :   Factory* factory = isolate->factory();
    3289      670585 :   Handle<NameDictionary> dictionary(object->property_dictionary(), isolate);
    3290             : 
    3291             :   // Make sure we preserve dictionary representation if there are too many
    3292             :   // descriptors.
    3293      335292 :   int number_of_elements = dictionary->NumberOfElements();
    3294      335292 :   if (number_of_elements > kMaxNumberOfDescriptors) return;
    3295             : 
    3296             :   Handle<FixedArray> iteration_order =
    3297      334697 :       NameDictionary::IterationIndices(isolate, dictionary);
    3298             : 
    3299             :   int instance_descriptor_length = iteration_order->length();
    3300             :   int number_of_fields = 0;
    3301             : 
    3302             :   // Compute the length of the instance descriptor.
    3303             :   ReadOnlyRoots roots(isolate);
    3304     2014580 :   for (int i = 0; i < instance_descriptor_length; i++) {
    3305     1679882 :     int index = Smi::ToInt(iteration_order->get(i));
    3306             :     DCHECK(dictionary->IsKey(roots, dictionary->KeyAt(index)));
    3307             : 
    3308     3359760 :     PropertyKind kind = dictionary->DetailsAt(index).kind();
    3309     1679884 :     if (kind == kData) {
    3310             :       if (FLAG_track_constant_fields) {
    3311     1270178 :         number_of_fields += 1;
    3312             :       } else {
    3313             :         Object value = dictionary->ValueAt(index);
    3314             :         if (!value->IsJSFunction()) {
    3315             :           number_of_fields += 1;
    3316             :         }
    3317             :       }
    3318             :     }
    3319             :   }
    3320             : 
    3321             :   Handle<Map> old_map(object->map(), isolate);
    3322             : 
    3323      334697 :   int inobject_props = old_map->GetInObjectProperties();
    3324             : 
    3325             :   // Allocate new map.
    3326      334696 :   Handle<Map> new_map = Map::CopyDropDescriptors(isolate, old_map);
    3327             :   // We should not only set this bit if we need to. We should not retain the
    3328             :   // old bit because turning a map into dictionary always sets this bit.
    3329      669249 :   new_map->set_may_have_interesting_symbols(new_map->has_named_interceptor() ||
    3330      669396 :                                             new_map->is_access_check_needed());
    3331      334698 :   new_map->set_is_dictionary_map(false);
    3332             : 
    3333      334698 :   NotifyMapChange(old_map, new_map, isolate);
    3334             : 
    3335      334698 :   if (instance_descriptor_length == 0) {
    3336             :     DisallowHeapAllocation no_gc;
    3337             :     DCHECK_LE(unused_property_fields, inobject_props);
    3338             :     // Transform the object.
    3339       63728 :     new_map->SetInObjectUnusedPropertyFields(inobject_props);
    3340       63728 :     object->synchronized_set_map(*new_map);
    3341      127456 :     object->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
    3342             :     // Check that it really works.
    3343             :     DCHECK(object->HasFastProperties());
    3344       63728 :     if (FLAG_trace_maps) {
    3345           0 :       LOG(isolate, MapEvent("SlowToFast", *old_map, *new_map, reason));
    3346             :     }
    3347             :     return;
    3348             :   }
    3349             : 
    3350             :   // Allocate the instance descriptor.
    3351             :   Handle<DescriptorArray> descriptors = DescriptorArray::Allocate(
    3352      270970 :       isolate, instance_descriptor_length, 0, TENURED);
    3353             : 
    3354             :   int number_of_allocated_fields =
    3355      270968 :       number_of_fields + unused_property_fields - inobject_props;
    3356      270968 :   if (number_of_allocated_fields < 0) {
    3357             :     // There is enough inobject space for all fields (including unused).
    3358             :     number_of_allocated_fields = 0;
    3359       42297 :     unused_property_fields = inobject_props - number_of_fields;
    3360             :   }
    3361             : 
    3362             :   // Allocate the property array for the fields.
    3363             :   Handle<PropertyArray> fields =
    3364      270968 :       factory->NewPropertyArray(number_of_allocated_fields);
    3365             : 
    3366             :   bool is_transitionable_elements_kind =
    3367             :       IsTransitionableFastElementsKind(old_map->elements_kind());
    3368             : 
    3369             :   // Fill in the instance descriptor and the fields.
    3370             :   int current_offset = 0;
    3371     1950851 :   for (int i = 0; i < instance_descriptor_length; i++) {
    3372     1679882 :     int index = Smi::ToInt(iteration_order->get(i));
    3373     1679883 :     Name k = dictionary->NameAt(index);
    3374             :     // Dictionary keys are internalized upon insertion.
    3375             :     // TODO(jkummerow): Turn this into a DCHECK if it's not hit in the wild.
    3376     1679882 :     CHECK(k->IsUniqueName());
    3377             :     Handle<Name> key(k, isolate);
    3378             : 
    3379             :     // Properly mark the {new_map} if the {key} is an "interesting symbol".
    3380     1679885 :     if (key->IsInterestingSymbol()) {
    3381        1819 :       new_map->set_may_have_interesting_symbols(true);
    3382             :     }
    3383             : 
    3384     1679884 :     Object value = dictionary->ValueAt(index);
    3385             : 
    3386     1679883 :     PropertyDetails details = dictionary->DetailsAt(index);
    3387             :     DCHECK_EQ(kField, details.location());
    3388             :     DCHECK_EQ(PropertyConstness::kMutable, details.constness());
    3389             : 
    3390     1679884 :     Descriptor d;
    3391     1679884 :     if (details.kind() == kData) {
    3392             :       if (!FLAG_track_constant_fields && value->IsJSFunction()) {
    3393             :         d = Descriptor::DataConstant(key, handle(value, isolate),
    3394             :                                      details.attributes());
    3395             :       } else {
    3396             :         // Ensure that we make constant field only when elements kind is not
    3397             :         // transitionable.
    3398             :         PropertyConstness constness =
    3399             :             FLAG_track_constant_fields && !is_transitionable_elements_kind
    3400             :                 ? PropertyConstness::kConst
    3401     1270178 :                 : PropertyConstness::kMutable;
    3402             :         d = Descriptor::DataField(
    3403             :             key, current_offset, details.attributes(), constness,
    3404             :             // TODO(verwaest): value->OptimalRepresentation();
    3405             :             Representation::Tagged(),
    3406     2540355 :             MaybeObjectHandle(FieldType::Any(isolate)));
    3407             :       }
    3408             :     } else {
    3409             :       DCHECK_EQ(kAccessor, details.kind());
    3410             :       d = Descriptor::AccessorConstant(key, handle(value, isolate),
    3411      409706 :                                        details.attributes());
    3412             :     }
    3413             :     details = d.GetDetails();
    3414     1679881 :     if (details.location() == kField) {
    3415     1270176 :       if (current_offset < inobject_props) {
    3416             :         object->InObjectPropertyAtPut(current_offset, value,
    3417       59111 :                                       UPDATE_WRITE_BARRIER);
    3418             :       } else {
    3419     1211065 :         int offset = current_offset - inobject_props;
    3420     1211065 :         fields->set(offset, value);
    3421             :       }
    3422     1270178 :       current_offset += details.field_width_in_words();
    3423             :     }
    3424     1679883 :     descriptors->Set(i, &d);
    3425             :   }
    3426             :   DCHECK(current_offset == number_of_fields);
    3427             : 
    3428      270970 :   descriptors->Sort();
    3429             : 
    3430             :   Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
    3431      270970 :       isolate, new_map, descriptors, descriptors->number_of_descriptors());
    3432             : 
    3433             :   DisallowHeapAllocation no_gc;
    3434      270970 :   new_map->InitializeDescriptors(isolate, *descriptors, *layout_descriptor);
    3435      270970 :   if (number_of_allocated_fields == 0) {
    3436       51714 :     new_map->SetInObjectUnusedPropertyFields(unused_property_fields);
    3437             :   } else {
    3438      219256 :     new_map->SetOutOfObjectUnusedPropertyFields(unused_property_fields);
    3439             :   }
    3440             : 
    3441      270969 :   if (FLAG_trace_maps) {
    3442         818 :     LOG(isolate, MapEvent("SlowToFast", *old_map, *new_map, reason));
    3443             :   }
    3444             :   // Transform the object.
    3445      270970 :   object->synchronized_set_map(*new_map);
    3446             : 
    3447      541940 :   object->SetProperties(*fields);
    3448             :   DCHECK(object->IsJSObject());
    3449             : 
    3450             :   // Check that it really works.
    3451             :   DCHECK(object->HasFastProperties());
    3452             : }
    3453             : 
    3454       74239 : void JSObject::RequireSlowElements(NumberDictionary dictionary) {
    3455      148478 :   if (dictionary->requires_slow_elements()) return;
    3456             :   dictionary->set_requires_slow_elements();
    3457       41944 :   if (map()->is_prototype_map()) {
    3458             :     // If this object is a prototype (the callee will check), invalidate any
    3459             :     // prototype chains involving it.
    3460             :     InvalidatePrototypeChains(map());
    3461             :   }
    3462             : }
    3463             : 
    3464      290801 : Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
    3465             :   DCHECK(!object->HasFixedTypedArrayElements());
    3466             :   Isolate* isolate = object->GetIsolate();
    3467      581602 :   bool is_sloppy_arguments = object->HasSloppyArgumentsElements();
    3468             :   {
    3469             :     DisallowHeapAllocation no_gc;
    3470      290801 :     FixedArrayBase elements = object->elements();
    3471             : 
    3472      290801 :     if (is_sloppy_arguments) {
    3473         775 :       elements = SloppyArgumentsElements::cast(elements)->arguments();
    3474             :     }
    3475             : 
    3476      290801 :     if (elements->IsNumberDictionary()) {
    3477        4280 :       return handle(NumberDictionary::cast(elements), isolate);
    3478             :     }
    3479             :   }
    3480             : 
    3481             :   DCHECK(object->HasSmiOrObjectElements() || object->HasDoubleElements() ||
    3482             :          object->HasFastArgumentsElements() ||
    3483             :          object->HasFastStringWrapperElements());
    3484             : 
    3485             :   Handle<NumberDictionary> dictionary =
    3486      573042 :       object->GetElementsAccessor()->Normalize(object);
    3487             : 
    3488             :   // Switch to using the dictionary as the backing storage for elements.
    3489             :   ElementsKind target_kind = is_sloppy_arguments
    3490             :                                  ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS
    3491      858085 :                                  : object->HasFastStringWrapperElements()
    3492             :                                        ? SLOW_STRING_WRAPPER_ELEMENTS
    3493      573042 :                                        : DICTIONARY_ELEMENTS;
    3494      286521 :   Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
    3495             :   // Set the new map first to satify the elements type assert in set_elements().
    3496      286521 :   JSObject::MigrateToMap(object, new_map);
    3497             : 
    3498      286521 :   if (is_sloppy_arguments) {
    3499        1478 :     SloppyArgumentsElements::cast(object->elements())
    3500        1478 :         ->set_arguments(*dictionary);
    3501             :   } else {
    3502      571564 :     object->set_elements(*dictionary);
    3503             :   }
    3504             : 
    3505      286521 :   isolate->counters()->elements_to_dictionary()->Increment();
    3506             : 
    3507             : #ifdef DEBUG
    3508             :   if (FLAG_trace_normalization) {
    3509             :     StdoutStream os;
    3510             :     os << "Object elements have been normalized:\n";
    3511             :     object->Print(os);
    3512             :   }
    3513             : #endif
    3514             : 
    3515             :   DCHECK(object->HasDictionaryElements() ||
    3516             :          object->HasSlowArgumentsElements() ||
    3517             :          object->HasSlowStringWrapperElements());
    3518      286521 :   return dictionary;
    3519             : }
    3520             : 
    3521         158 : Maybe<bool> JSObject::DeletePropertyWithInterceptor(LookupIterator* it,
    3522             :                                                     ShouldThrow should_throw) {
    3523             :   Isolate* isolate = it->isolate();
    3524             :   // Make sure that the top context does not change when doing callbacks or
    3525             :   // interceptor calls.
    3526             :   AssertNoContextChange ncc(isolate);
    3527             : 
    3528             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    3529         100 :   Handle<InterceptorInfo> interceptor(it->GetInterceptor());
    3530         200 :   if (interceptor->deleter()->IsUndefined(isolate)) return Nothing<bool>();
    3531             : 
    3532             :   Handle<JSObject> holder = it->GetHolder<JSObject>();
    3533             :   Handle<Object> receiver = it->GetReceiver();
    3534         116 :   if (!receiver->IsJSReceiver()) {
    3535           0 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, receiver,
    3536             :                                      Object::ConvertReceiver(isolate, receiver),
    3537             :                                      Nothing<bool>());
    3538             :   }
    3539             : 
    3540             :   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
    3541          58 :                                  *holder, Just(should_throw));
    3542             :   Handle<Object> result;
    3543          58 :   if (it->IsElement()) {
    3544          23 :     result = args.CallIndexedDeleter(interceptor, it->index());
    3545             :   } else {
    3546          35 :     result = args.CallNamedDeleter(interceptor, it->name());
    3547             :   }
    3548             : 
    3549          58 :   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    3550          58 :   if (result.is_null()) return Nothing<bool>();
    3551             : 
    3552             :   DCHECK(result->IsBoolean());
    3553             :   // Rebox CustomArguments::kReturnValueOffset before returning.
    3554          48 :   return Just(result->IsTrue(isolate));
    3555             : }
    3556             : 
    3557     4626817 : Maybe<bool> JSObject::CreateDataProperty(LookupIterator* it,
    3558             :                                          Handle<Object> value,
    3559             :                                          Maybe<ShouldThrow> should_throw) {
    3560             :   DCHECK(it->GetReceiver()->IsJSObject());
    3561     2313411 :   MAYBE_RETURN(JSReceiver::GetPropertyAttributes(it), Nothing<bool>());
    3562     2313406 :   Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver());
    3563             :   Isolate* isolate = receiver->GetIsolate();
    3564             : 
    3565     2313406 :   if (it->IsFound()) {
    3566         441 :     Maybe<PropertyAttributes> attributes = GetPropertyAttributes(it);
    3567         478 :     MAYBE_RETURN(attributes, Nothing<bool>());
    3568         441 :     if ((attributes.FromJust() & DONT_DELETE) != 0) {
    3569         118 :       RETURN_FAILURE(
    3570             :           isolate, GetShouldThrow(isolate, should_throw),
    3571             :           NewTypeError(MessageTemplate::kRedefineDisallowed, it->GetName()));
    3572             :     }
    3573             :   } else {
    3574     2312965 :     if (!JSObject::IsExtensible(Handle<JSObject>::cast(it->GetReceiver()))) {
    3575         329 :       RETURN_FAILURE(
    3576             :           isolate, GetShouldThrow(isolate, should_throw),
    3577             :           NewTypeError(MessageTemplate::kDefineDisallowed, it->GetName()));
    3578             :     }
    3579             :   }
    3580             : 
    3581     4626566 :   RETURN_ON_EXCEPTION_VALUE(it->isolate(),
    3582             :                             DefineOwnPropertyIgnoreAttributes(it, value, NONE),
    3583             :                             Nothing<bool>());
    3584             : 
    3585             :   return Just(true);
    3586             : }
    3587             : 
    3588             : namespace {
    3589             : 
    3590             : template <typename Dictionary>
    3591       18226 : bool TestDictionaryPropertiesIntegrityLevel(Dictionary dict,
    3592             :                                             ReadOnlyRoots roots,
    3593             :                                             PropertyAttributes level) {
    3594             :   DCHECK(level == SEALED || level == FROZEN);
    3595             : 
    3596       18226 :   uint32_t capacity = dict->Capacity();
    3597       41350 :   for (uint32_t i = 0; i < capacity; i++) {
    3598       23257 :     Object key;
    3599       43772 :     if (!dict->ToKey(roots, i, &key)) continue;
    3600        2760 :     if (key->FilterKey(ALL_PROPERTIES)) continue;
    3601        2742 :     PropertyDetails details = dict->DetailsAt(i);
    3602        2875 :     if (details.IsConfigurable()) return false;
    3603        6804 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    3604             :       return false;
    3605             :     }
    3606             :   }
    3607             :   return true;
    3608             : }
    3609             : 
    3610       17954 : bool TestFastPropertiesIntegrityLevel(Map map, PropertyAttributes level) {
    3611             :   DCHECK(level == SEALED || level == FROZEN);
    3612             :   DCHECK(!map->IsCustomElementsReceiverMap());
    3613             :   DCHECK(!map->is_dictionary_map());
    3614             : 
    3615       17954 :   DescriptorArray descriptors = map->instance_descriptors();
    3616             :   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
    3617       19740 :   for (int i = 0; i < number_of_own_descriptors; i++) {
    3618        1958 :     if (descriptors->GetKey(i)->IsPrivate()) continue;
    3619        1940 :     PropertyDetails details = descriptors->GetDetails(i);
    3620        1940 :     if (details.IsConfigurable()) return false;
    3621        4226 :     if (level == FROZEN && details.kind() == kData && !details.IsReadOnly()) {
    3622             :       return false;
    3623             :     }
    3624             :   }
    3625             :   return true;
    3626             : }
    3627             : 
    3628       18043 : bool TestPropertiesIntegrityLevel(JSObject object, PropertyAttributes level) {
    3629             :   DCHECK(!object->map()->IsCustomElementsReceiverMap());
    3630             : 
    3631       18043 :   if (object->HasFastProperties()) {
    3632       17954 :     return TestFastPropertiesIntegrityLevel(object->map(), level);
    3633             :   }
    3634             : 
    3635             :   return TestDictionaryPropertiesIntegrityLevel(
    3636          89 :       object->property_dictionary(), object->GetReadOnlyRoots(), level);
    3637             : }
    3638             : 
    3639       18141 : bool TestElementsIntegrityLevel(JSObject object, PropertyAttributes level) {
    3640             :   DCHECK(!object->HasSloppyArgumentsElements());
    3641             : 
    3642       18141 :   ElementsKind kind = object->GetElementsKind();
    3643             : 
    3644       18141 :   if (IsDictionaryElementsKind(kind)) {
    3645             :     return TestDictionaryPropertiesIntegrityLevel(
    3646             :         NumberDictionary::cast(object->elements()), object->GetReadOnlyRoots(),
    3647       36274 :         level);
    3648             :   }
    3649           4 :   if (IsFixedTypedArrayElementsKind(kind)) {
    3650           4 :     return TestPropertiesIntegrityLevel(object, level);
    3651             :   }
    3652             : 
    3653             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
    3654             :   // Only DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS have
    3655             :   // PropertyAttributes so just test if empty
    3656           0 :   return accessor->NumberOfElements(object) == 0;
    3657             : }
    3658             : 
    3659      249192 : bool FastTestIntegrityLevel(JSObject object, PropertyAttributes level) {
    3660             :   DCHECK(!object->map()->IsCustomElementsReceiverMap());
    3661             : 
    3662       18141 :   return !object->map()->is_extensible() &&
    3663      267231 :          TestElementsIntegrityLevel(object, level) &&
    3664      267231 :          TestPropertiesIntegrityLevel(object, level);
    3665             : }
    3666             : 
    3667             : }  // namespace
    3668             : 
    3669      249317 : Maybe<bool> JSObject::TestIntegrityLevel(Handle<JSObject> object,
    3670             :                                          IntegrityLevel level) {
    3671      747859 :   if (!object->map()->IsCustomElementsReceiverMap() &&
    3672      498539 :       !object->HasSloppyArgumentsElements()) {
    3673      249192 :     return Just(FastTestIntegrityLevel(*object, level));
    3674             :   }
    3675         127 :   return GenericTestIntegrityLevel(Handle<JSReceiver>::cast(object), level);
    3676             : }
    3677             : 
    3678        4577 : Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
    3679             :                                         ShouldThrow should_throw) {
    3680             :   Isolate* isolate = object->GetIsolate();
    3681             : 
    3682        9154 :   if (!object->HasSloppyArgumentsElements()) {
    3683        4524 :     return PreventExtensionsWithTransition<NONE>(object, should_throw);
    3684             :   }
    3685             : 
    3686         106 :   if (object->IsAccessCheckNeeded() &&
    3687           0 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    3688           0 :     isolate->ReportFailedAccessCheck(object);
    3689           0 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    3690           0 :     RETURN_FAILURE(isolate, should_throw,
    3691             :                    NewTypeError(MessageTemplate::kNoAccess));
    3692             :   }
    3693             : 
    3694          53 :   if (!object->map()->is_extensible()) return Just(true);
    3695             : 
    3696         106 :   if (object->IsJSGlobalProxy()) {
    3697           0 :     PrototypeIterator iter(isolate, object);
    3698           0 :     if (iter.IsAtEnd()) return Just(true);
    3699             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    3700             :     return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter),
    3701           0 :                              should_throw);
    3702             :   }
    3703             : 
    3704         106 :   if (object->map()->has_named_interceptor() ||
    3705             :       object->map()->has_indexed_interceptor()) {
    3706           0 :     RETURN_FAILURE(isolate, should_throw,
    3707             :                    NewTypeError(MessageTemplate::kCannotPreventExt));
    3708             :   }
    3709             : 
    3710          53 :   if (!object->HasFixedTypedArrayElements()) {
    3711             :     // If there are fast elements we normalize.
    3712          53 :     Handle<NumberDictionary> dictionary = NormalizeElements(object);
    3713             :     DCHECK(object->HasDictionaryElements() ||
    3714             :            object->HasSlowArgumentsElements());
    3715             : 
    3716             :     // Make sure that we never go back to fast case.
    3717          53 :     object->RequireSlowElements(*dictionary);
    3718             :   }
    3719             : 
    3720             :   // Do a map transition, other objects with this map may still
    3721             :   // be extensible.
    3722             :   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    3723             :   Handle<Map> new_map =
    3724          53 :       Map::Copy(isolate, handle(object->map(), isolate), "PreventExtensions");
    3725             : 
    3726             :   new_map->set_is_extensible(false);
    3727          53 :   JSObject::MigrateToMap(object, new_map);
    3728             :   DCHECK(!object->map()->is_extensible());
    3729             : 
    3730             :   return Just(true);
    3731             : }
    3732             : 
    3733     3780854 : bool JSObject::IsExtensible(Handle<JSObject> object) {
    3734             :   Isolate* isolate = object->GetIsolate();
    3735     7561753 :   if (object->IsAccessCheckNeeded() &&
    3736          40 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    3737             :     return true;
    3738             :   }
    3739     7561653 :   if (object->IsJSGlobalProxy()) {
    3740             :     PrototypeIterator iter(isolate, *object);
    3741        2793 :     if (iter.IsAtEnd()) return false;
    3742             :     DCHECK(iter.GetCurrent()->IsJSGlobalObject());
    3743        5586 :     return iter.GetCurrent<JSObject>()->map()->is_extensible();
    3744             :   }
    3745             :   return object->map()->is_extensible();
    3746             : }
    3747             : 
    3748             : namespace {
    3749             : 
    3750             : template <typename Dictionary>
    3751        6419 : void ApplyAttributesToDictionary(Isolate* isolate, ReadOnlyRoots roots,
    3752             :                                  Handle<Dictionary> dictionary,
    3753             :                                  const PropertyAttributes attributes) {
    3754        6419 :   int capacity = dictionary->Capacity();
    3755       66609 :   for (int i = 0; i < capacity; i++) {
    3756       66528 :     Object k;
    3757      103371 :     if (!dictionary->ToKey(roots, i, &k)) continue;
    3758       29703 :     if (k->FilterKey(ALL_PROPERTIES)) continue;
    3759       29685 :     PropertyDetails details = dictionary->DetailsAt(i);
    3760       29685 :     int attrs = attributes;
    3761             :     // READ_ONLY is an invalid attribute for JS setters/getters.
    3762       57616 :     if ((attributes & READ_ONLY) && details.kind() == kAccessor) {
    3763          54 :       Object v = dictionary->ValueAt(i);
    3764          45 :       if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
    3765             :     }
    3766             :     details = details.CopyAddAttributes(static_cast<PropertyAttributes>(attrs));
    3767       29685 :     dictionary->DetailsAtPut(isolate, i, details);
    3768             :   }
    3769        6419 : }
    3770             : 
    3771             : }  // namespace
    3772             : 
    3773             : template <PropertyAttributes attrs>
    3774      235736 : Maybe<bool> JSObject::PreventExtensionsWithTransition(
    3775             :     Handle<JSObject> object, ShouldThrow should_throw) {
    3776             :   STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
    3777             : 
    3778             :   // Sealing/freezing sloppy arguments or namespace objects should be handled
    3779             :   // elsewhere.
    3780             :   DCHECK(!object->HasSloppyArgumentsElements());
    3781             :   DCHECK_IMPLIES(object->IsJSModuleNamespace(), attrs == NONE);
    3782             : 
    3783             :   Isolate* isolate = object->GetIsolate();
    3784      471499 :   if (object->IsAccessCheckNeeded() &&
    3785          25 :       !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    3786          20 :     isolate->ReportFailedAccessCheck(object);
    3787          20 :     RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    3788           0 :     RETURN_FAILURE(isolate, should_throw,
    3789             :                    NewTypeError(MessageTemplate::kNoAccess));
    3790             :   }
    3791             : 
    3792        4523 :   if (attrs == NONE && !object->map()->is_extensible()) return Just(true);
    3793             : 
    3794      471269 :   if (object->IsJSGlobalProxy()) {
    3795          90 :     PrototypeIterator iter(isolate, object);
    3796          90 :     if (iter.IsAtEnd()) return Just(true);
    3797             :     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
    3798             :     return PreventExtensionsWithTransition<attrs>(
    3799          90 :         PrototypeIterator::GetCurrent<JSObject>(iter), should_throw);
    3800             :   }
    3801             : 
    3802      471091 :   if (object->map()->has_named_interceptor() ||
    3803             :       object->map()->has_indexed_interceptor()) {
    3804             :     MessageTemplate message = MessageTemplate::kNone;
    3805             :     switch (attrs) {
    3806             :       case NONE:
    3807             :         message = MessageTemplate::kCannotPreventExt;
    3808             :         break;
    3809             : 
    3810             :       case SEALED:
    3811             :         message = MessageTemplate::kCannotSeal;
    3812             :         break;
    3813             : 
    3814             :       case FROZEN:
    3815             :         message = MessageTemplate::kCannotFreeze;
    3816             :         break;
    3817             :     }
    3818           3 :     RETURN_FAILURE(isolate, should_throw, NewTypeError(message));
    3819             :   }
    3820             : 
    3821             :   Handle<NumberDictionary> new_element_dictionary;
    3822      941799 :   if (!object->HasFixedTypedArrayElements() &&
    3823      471030 :       !object->HasDictionaryElements() &&
    3824      470772 :       !object->HasSlowStringWrapperElements()) {
    3825      470459 :     int length = object->IsJSArray()
    3826      241680 :                      ? Smi::ToInt(Handle<JSArray>::cast(object)->length())
    3827      705686 :                      : object->elements()->length();
    3828      470460 :     new_element_dictionary =
    3829             :         length == 0 ? isolate->factory()->empty_slow_element_dictionary()
    3830      254826 :                     : object->GetElementsAccessor()->Normalize(object);
    3831             :   }
    3832             : 
    3833             :   Handle<Symbol> transition_marker;
    3834             :   if (attrs == NONE) {
    3835             :     transition_marker = isolate->factory()->nonextensible_symbol();
    3836             :   } else if (attrs == SEALED) {
    3837             :     transition_marker = isolate->factory()->sealed_symbol();
    3838             :   } else {
    3839             :     DCHECK(attrs == FROZEN);
    3840             :     transition_marker = isolate->factory()->frozen_symbol();
    3841             :   }
    3842             : 
    3843             :   Handle<Map> old_map(object->map(), isolate);
    3844      235545 :   TransitionsAccessor transitions(isolate, old_map);
    3845      235545 :   Map transition = transitions.SearchSpecial(*transition_marker);
    3846      235544 :   if (!transition.is_null()) {
    3847             :     Handle<Map> transition_map(transition, isolate);
    3848             :     DCHECK(transition_map->has_dictionary_elements() ||
    3849             :            transition_map->has_fixed_typed_array_elements() ||
    3850             :            transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    3851             :     DCHECK(!transition_map->is_extensible());
    3852       99641 :     JSObject::MigrateToMap(object, transition_map);
    3853      135903 :   } else if (transitions.CanHaveMoreTransitions()) {
    3854             :     // Create a new descriptor array with the appropriate property attributes
    3855             :     Handle<Map> new_map = Map::CopyForPreventExtensions(
    3856      135117 :         isolate, old_map, attrs, transition_marker, "CopyForPreventExtensions");
    3857      135118 :     JSObject::MigrateToMap(object, new_map);
    3858             :   } else {
    3859             :     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
    3860             :     // Slow path: need to normalize properties for safety
    3861         786 :     NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
    3862             :                         "SlowPreventExtensions");
    3863             : 
    3864             :     // Create a new map, since other objects with this map may be extensible.
    3865             :     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
    3866             :     Handle<Map> new_map = Map::Copy(isolate, handle(object->map(), isolate),
    3867         786 :                                     "SlowCopyForPreventExtensions");
    3868             :     new_map->set_is_extensible(false);
    3869         786 :     if (!new_element_dictionary.is_null()) {
    3870             :       ElementsKind new_kind =
    3871             :           IsStringWrapperElementsKind(old_map->elements_kind())
    3872             :               ? SLOW_STRING_WRAPPER_ELEMENTS
    3873         786 :               : DICTIONARY_ELEMENTS;
    3874        1572 :       new_map->set_elements_kind(new_kind);
    3875             :     }
    3876         786 :     JSObject::MigrateToMap(object, new_map);
    3877             : 
    3878             :     if (attrs != NONE) {
    3879             :       ReadOnlyRoots roots(isolate);
    3880         304 :       if (object->IsJSGlobalObject()) {
    3881             :         Handle<GlobalDictionary> dictionary(
    3882         162 :             JSGlobalObject::cast(*object)->global_dictionary(), isolate);
    3883          81 :         ApplyAttributesToDictionary(isolate, roots, dictionary, attrs);
    3884             :       } else {
    3885         142 :         Handle<NameDictionary> dictionary(object->property_dictionary(),
    3886          71 :                                           isolate);
    3887          71 :         ApplyAttributesToDictionary(isolate, roots, dictionary, attrs);
    3888             :       }
    3889             :     }
    3890             :   }
    3891             : 
    3892             :   // Both seal and preventExtensions always go through without modifications to
    3893             :   // typed array elements. Freeze works only if there are no actual elements.
    3894      235544 :   if (object->HasFixedTypedArrayElements()) {
    3895          36 :     if (attrs == FROZEN &&
    3896             :         JSArrayBufferView::cast(*object)->byte_length() > 0) {
    3897          27 :       isolate->Throw(*isolate->factory()->NewTypeError(
    3898          54 :           MessageTemplate::kCannotFreezeArrayBufferView));
    3899             :       return Nothing<bool>();
    3900             :     }
    3901             :     return Just(true);
    3902             :   }
    3903             : 
    3904             :   DCHECK(object->map()->has_dictionary_elements() ||
    3905             :          object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS);
    3906      235487 :   if (!new_element_dictionary.is_null()) {
    3907      470460 :     object->set_elements(*new_element_dictionary);
    3908             :   }
    3909             : 
    3910      470973 :   if (object->elements() !=
    3911             :       ReadOnlyRoots(isolate).empty_slow_element_dictionary()) {
    3912       13470 :     Handle<NumberDictionary> dictionary(object->element_dictionary(), isolate);
    3913             :     // Make sure we never go back to the fast case
    3914        6735 :     object->RequireSlowElements(*dictionary);
    3915             :     if (attrs != NONE) {
    3916        6267 :       ApplyAttributesToDictionary(isolate, ReadOnlyRoots(isolate), dictionary,
    3917        6267 :                                   attrs);
    3918             :     }
    3919             :   }
    3920             : 
    3921             :   return Just(true);
    3922             : }
    3923             : 
    3924    15152184 : Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
    3925             :                                         Representation representation,
    3926             :                                         FieldIndex index) {
    3927             :   Isolate* isolate = object->GetIsolate();
    3928    15152184 :   if (object->IsUnboxedDoubleField(index)) {
    3929             :     double value = object->RawFastDoublePropertyAt(index);
    3930       19683 :     return isolate->factory()->NewHeapNumber(value);
    3931             :   }
    3932    30265019 :   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
    3933    15132515 :   return Object::WrapForRead(isolate, raw_value, representation);
    3934             : }
    3935             : 
    3936             : // TODO(cbruni/jkummerow): Consider moving this into elements.cc.
    3937      143580 : bool JSObject::HasEnumerableElements() {
    3938             :   // TODO(cbruni): cleanup
    3939      143580 :   JSObject object = *this;
    3940      143580 :   switch (object->GetElementsKind()) {
    3941             :     case PACKED_SMI_ELEMENTS:
    3942             :     case PACKED_ELEMENTS:
    3943             :     case PACKED_DOUBLE_ELEMENTS: {
    3944             :       int length = object->IsJSArray()
    3945             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    3946       88794 :                        : object->elements()->length();
    3947       29607 :       return length > 0;
    3948             :     }
    3949             :     case HOLEY_SMI_ELEMENTS:
    3950             :     case HOLEY_ELEMENTS: {
    3951      227262 :       FixedArray elements = FixedArray::cast(object->elements());
    3952             :       int length = object->IsJSArray()
    3953             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    3954      172060 :                        : elements->length();
    3955             :       Isolate* isolate = GetIsolate();
    3956     2566284 :       for (int i = 0; i < length; i++) {
    3957     2463786 :         if (!elements->is_the_hole(isolate, i)) return true;
    3958             :       }
    3959             :       return false;
    3960             :     }
    3961             :     case HOLEY_DOUBLE_ELEMENTS: {
    3962             :       int length = object->IsJSArray()
    3963             :                        ? Smi::ToInt(JSArray::cast(object)->length())
    3964         135 :                        : object->elements()->length();
    3965             :       // Zero-length arrays would use the empty FixedArray...
    3966          45 :       if (length == 0) return false;
    3967             :       // ...so only cast to FixedDoubleArray otherwise.
    3968          90 :       FixedDoubleArray elements = FixedDoubleArray::cast(object->elements());
    3969          45 :       for (int i = 0; i < length; i++) {
    3970          45 :         if (!elements->is_the_hole(i)) return true;
    3971             :       }
    3972             :       return false;
    3973             :     }
    3974             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
    3975             : 
    3976             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    3977             : #undef TYPED_ARRAY_CASE
    3978             :       {
    3979           0 :         int length = object->elements()->length();
    3980           0 :         return length > 0;
    3981             :       }
    3982             :     case DICTIONARY_ELEMENTS: {
    3983         432 :       NumberDictionary elements = NumberDictionary::cast(object->elements());
    3984         216 :       return elements->NumberOfEnumerableProperties() > 0;
    3985             :     }
    3986             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    3987             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    3988             :       // We're approximating non-empty arguments objects here.
    3989             :       return true;
    3990             :     case FAST_STRING_WRAPPER_ELEMENTS:
    3991             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    3992           0 :       if (String::cast(JSValue::cast(object)->value())->length() > 0) {
    3993             :         return true;
    3994             :       }
    3995           0 :       return object->elements()->length() > 0;
    3996             :     case NO_ELEMENTS:
    3997           0 :       return false;
    3998             :   }
    3999           0 :   UNREACHABLE();
    4000             : }
    4001             : 
    4002      434167 : MaybeHandle<Object> JSObject::DefineAccessor(Handle<JSObject> object,
    4003             :                                              Handle<Name> name,
    4004             :                                              Handle<Object> getter,
    4005             :                                              Handle<Object> setter,
    4006             :                                              PropertyAttributes attributes) {
    4007             :   Isolate* isolate = object->GetIsolate();
    4008             : 
    4009             :   LookupIterator it = LookupIterator::PropertyOrElement(
    4010      434167 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    4011      434167 :   return DefineAccessor(&it, getter, setter, attributes);
    4012             : }
    4013             : 
    4014     1891348 : MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it,
    4015             :                                              Handle<Object> getter,
    4016             :                                              Handle<Object> setter,
    4017             :                                              PropertyAttributes attributes) {
    4018             :   Isolate* isolate = it->isolate();
    4019             : 
    4020      630451 :   it->UpdateProtector();
    4021             : 
    4022      630451 :   if (it->state() == LookupIterator::ACCESS_CHECK) {
    4023        1738 :     if (!it->HasAccess()) {
    4024           5 :       isolate->ReportFailedAccessCheck(it->GetHolder<JSObject>());
    4025           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    4026           0 :       return isolate->factory()->undefined_value();
    4027             :     }
    4028        1733 :     it->Next();
    4029             :   }
    4030             : 
    4031      630446 :   Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver());
    4032             :   // Ignore accessors on typed arrays.
    4033      657847 :   if (it->IsElement() && object->HasFixedTypedArrayElements()) {
    4034           0 :     return it->factory()->undefined_value();
    4035             :   }
    4036             : 
    4037             :   DCHECK(getter->IsCallable() || getter->IsUndefined(isolate) ||
    4038             :          getter->IsNull(isolate) || getter->IsFunctionTemplateInfo());
    4039             :   DCHECK(setter->IsCallable() || setter->IsUndefined(isolate) ||
    4040             :          setter->IsNull(isolate) || setter->IsFunctionTemplateInfo());
    4041      630446 :   it->TransitionToAccessorProperty(getter, setter, attributes);
    4042             : 
    4043      630446 :   return isolate->factory()->undefined_value();
    4044             : }
    4045             : 
    4046       61220 : MaybeHandle<Object> JSObject::SetAccessor(Handle<JSObject> object,
    4047             :                                           Handle<Name> name,
    4048             :                                           Handle<AccessorInfo> info,
    4049             :                                           PropertyAttributes attributes) {
    4050             :   Isolate* isolate = object->GetIsolate();
    4051             : 
    4052             :   LookupIterator it = LookupIterator::PropertyOrElement(
    4053       61220 :       isolate, object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    4054             : 
    4055             :   // Duplicate ACCESS_CHECK outside of GetPropertyAttributes for the case that
    4056             :   // the FailedAccessCheckCallbackFunction doesn't throw an exception.
    4057             :   //
    4058             :   // TODO(verwaest): Force throw an exception if the callback doesn't, so we can
    4059             :   // remove reliance on default return values.
    4060       61220 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    4061        7780 :     if (!it.HasAccess()) {
    4062           5 :       isolate->ReportFailedAccessCheck(object);
    4063           5 :       RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
    4064           0 :       return it.factory()->undefined_value();
    4065             :     }
    4066        7775 :     it.Next();
    4067             :   }
    4068             : 
    4069             :   // Ignore accessors on typed arrays.
    4070       61227 :   if (it.IsElement() && object->HasFixedTypedArrayElements()) {
    4071           0 :     return it.factory()->undefined_value();
    4072             :   }
    4073             : 
    4074       61215 :   CHECK(GetPropertyAttributes(&it).IsJust());
    4075             : 
    4076             :   // ES5 forbids turning a property into an accessor if it's not
    4077             :   // configurable. See 8.6.1 (Table 5).
    4078       61276 :   if (it.IsFound() && !it.IsConfigurable()) {
    4079          50 :     return it.factory()->undefined_value();
    4080             :   }
    4081             : 
    4082       61190 :   it.TransitionToAccessorPair(info, attributes);
    4083             : 
    4084       61190 :   return object;
    4085             : }
    4086             : 
    4087         237 : Object JSObject::SlowReverseLookup(Object value) {
    4088         237 :   if (HasFastProperties()) {
    4089             :     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
    4090         180 :     DescriptorArray descs = map()->instance_descriptors();
    4091             :     bool value_is_number = value->IsNumber();
    4092         993 :     for (int i = 0; i < number_of_own_descriptors; i++) {
    4093         822 :       PropertyDetails details = descs->GetDetails(i);
    4094         822 :       if (details.location() == kField) {
    4095             :         DCHECK_EQ(kData, details.kind());
    4096         765 :         FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
    4097         765 :         if (IsUnboxedDoubleField(field_index)) {
    4098           0 :           if (value_is_number) {
    4099             :             double property = RawFastDoublePropertyAt(field_index);
    4100           0 :             if (property == value->Number()) {
    4101           0 :               return descs->GetKey(i);
    4102             :             }
    4103             :           }
    4104             :         } else {
    4105         765 :           Object property = RawFastPropertyAt(field_index);
    4106         765 :           if (field_index.is_double()) {
    4107             :             DCHECK(property->IsMutableHeapNumber());
    4108           0 :             if (value_is_number && property->Number() == value->Number()) {
    4109           0 :               return descs->GetKey(i);
    4110             :             }
    4111         765 :           } else if (property == value) {
    4112           9 :             return descs->GetKey(i);
    4113             :           }
    4114             :         }
    4115             :       } else {
    4116             :         DCHECK_EQ(kDescriptor, details.location());
    4117          57 :         if (details.kind() == kData) {
    4118           0 :           if (descs->GetStrongValue(i) == value) {
    4119           0 :             return descs->GetKey(i);
    4120             :           }
    4121             :         }
    4122             :       }
    4123             :     }
    4124         342 :     return GetReadOnlyRoots().undefined_value();
    4125         114 :   } else if (IsJSGlobalObject()) {
    4126         114 :     return JSGlobalObject::cast(*this)->global_dictionary()->SlowReverseLookup(
    4127          57 :         value);
    4128             :   } else {
    4129           0 :     return property_dictionary()->SlowReverseLookup(value);
    4130             :   }
    4131             : }
    4132             : 
    4133           0 : void JSObject::PrototypeRegistryCompactionCallback(HeapObject value,
    4134             :                                                    int old_index,
    4135             :                                                    int new_index) {
    4136             :   DCHECK(value->IsMap() && Map::cast(value)->is_prototype_map());
    4137             :   Map map = Map::cast(value);
    4138             :   DCHECK(map->prototype_info()->IsPrototypeInfo());
    4139             :   PrototypeInfo proto_info = PrototypeInfo::cast(map->prototype_info());
    4140             :   DCHECK_EQ(old_index, proto_info->registry_slot());
    4141             :   proto_info->set_registry_slot(new_index);
    4142           0 : }
    4143             : 
    4144             : // static
    4145     3194099 : void JSObject::MakePrototypesFast(Handle<Object> receiver,
    4146             :                                   WhereToStart where_to_start,
    4147             :                                   Isolate* isolate) {
    4148     6388209 :   if (!receiver->IsJSReceiver()) return;
    4149     8375327 :   for (PrototypeIterator iter(isolate, Handle<JSReceiver>::cast(receiver),
    4150     3148921 :                               where_to_start);
    4151     7303859 :        !iter.IsAtEnd(); iter.Advance()) {
    4152             :     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
    4153    13548763 :     if (!current->IsJSObject()) return;
    4154     5202730 :     Handle<JSObject> current_obj = Handle<JSObject>::cast(current);
    4155     5202727 :     Map current_map = current_obj->map();
    4156     5202727 :     if (current_map->is_prototype_map()) {
    4157             :       // If the map is already marked as should be fast, we're done. Its
    4158             :       // prototypes will have been marked already as well.
    4159     6614422 :       if (current_map->should_be_fast_prototype_map()) return;
    4160             :       Handle<Map> map(current_map, isolate);
    4161      363897 :       Map::SetShouldBeFastPrototypeMap(map, true, isolate);
    4162      363897 :       JSObject::OptimizeAsPrototype(current_obj);
    4163             :     }
    4164             :   }
    4165             : }
    4166             : 
    4167    24250646 : static bool PrototypeBenefitsFromNormalization(Handle<JSObject> object) {
    4168             :   DisallowHeapAllocation no_gc;
    4169    24250648 :   if (!object->HasFastProperties()) return false;
    4170    46102000 :   if (object->IsJSGlobalProxy()) return false;
    4171    23029674 :   if (object->GetIsolate()->bootstrapper()->IsActive()) return false;
    4172     9426263 :   return !object->map()->is_prototype_map() ||
    4173     9426263 :          !object->map()->should_be_fast_prototype_map();
    4174             : }
    4175             : 
    4176             : // static
    4177    24361746 : void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
    4178             :                                    bool enable_setup_mode) {
    4179    73085278 :   if (object->IsJSGlobalObject()) return;
    4180    24265763 :   if (enable_setup_mode && PrototypeBenefitsFromNormalization(object)) {
    4181             :     // First normalize to ensure all JSFunctions are DATA_CONSTANT.
    4182             :     JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
    4183      327726 :                                   "NormalizeAsPrototype");
    4184             :   }
    4185    24265777 :   if (object->map()->is_prototype_map()) {
    4186    56669498 :     if (object->map()->should_be_fast_prototype_map() &&
    4187    36592463 :         !object->HasFastProperties()) {
    4188      281950 :       JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
    4189             :     }
    4190             :   } else {
    4191             :     Handle<Map> new_map = Map::Copy(object->GetIsolate(),
    4192             :                                     handle(object->map(), object->GetIsolate()),
    4193     4188745 :                                     "CopyAsPrototype");
    4194     4188747 :     JSObject::MigrateToMap(object, new_map);
    4195             :     object->map()->set_is_prototype_map(true);
    4196             : 
    4197             :     // Replace the pointer to the exact constructor with the Object function
    4198             :     // from the same context if undetectable from JS. This is to avoid keeping
    4199             :     // memory alive unnecessarily.
    4200     4188748 :     Object maybe_constructor = object->map()->GetConstructor();
    4201     4188749 :     if (maybe_constructor->IsJSFunction()) {
    4202     4188072 :       JSFunction constructor = JSFunction::cast(maybe_constructor);
    4203     4188072 :       if (!constructor->shared()->IsApiFunction()) {
    4204     4132458 :         Context context = constructor->context()->native_context();
    4205     4132458 :         JSFunction object_function = context->object_function();
    4206     4132458 :         object->map()->SetConstructor(object_function);
    4207             :       }
    4208             :     }
    4209             :   }
    4210             : }
    4211             : 
    4212             : // static
    4213      361323 : void JSObject::ReoptimizeIfPrototype(Handle<JSObject> object) {
    4214      361323 :   if (!object->map()->is_prototype_map()) return;
    4215       57493 :   if (!object->map()->should_be_fast_prototype_map()) return;
    4216       39137 :   OptimizeAsPrototype(object);
    4217             : }
    4218             : 
    4219             : // static
    4220     1723289 : void JSObject::LazyRegisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
    4221             :   // Contract: In line with InvalidatePrototypeChains()'s requirements,
    4222             :   // leaf maps don't need to register as users, only prototypes do.
    4223             :   DCHECK(user->is_prototype_map());
    4224             : 
    4225     1723289 :   Handle<Map> current_user = user;
    4226             :   Handle<PrototypeInfo> current_user_info =
    4227     1723289 :       Map::GetOrCreatePrototypeInfo(user, isolate);
    4228     4441442 :   for (PrototypeIterator iter(isolate, user); !iter.IsAtEnd(); iter.Advance()) {
    4229             :     // Walk up the prototype chain as far as links haven't been registered yet.
    4230     1589948 :     if (current_user_info->registry_slot() != PrototypeInfo::UNREGISTERED) {
    4231             :       break;
    4232             :     }
    4233             :     Handle<Object> maybe_proto = PrototypeIterator::GetCurrent(iter);
    4234             :     // Proxies on the prototype chain are not supported. They make it
    4235             :     // impossible to make any assumptions about the prototype chain anyway.
    4236     2719086 :     if (maybe_proto->IsJSProxy()) return;
    4237      497429 :     Handle<JSObject> proto = Handle<JSObject>::cast(maybe_proto);
    4238             :     Handle<PrototypeInfo> proto_info =
    4239      497429 :         Map::GetOrCreatePrototypeInfo(proto, isolate);
    4240             :     Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
    4241             :     Handle<WeakArrayList> registry =
    4242      994855 :         maybe_registry->IsSmi()
    4243             :             ? handle(ReadOnlyRoots(isolate->heap()).empty_weak_array_list(),
    4244      117641 :                      isolate)
    4245      615069 :             : Handle<WeakArrayList>::cast(maybe_registry);
    4246      497427 :     int slot = 0;
    4247             :     Handle<WeakArrayList> new_array =
    4248      497427 :         PrototypeUsers::Add(isolate, registry, current_user, &slot);
    4249      497429 :     current_user_info->set_registry_slot(slot);
    4250      497429 :     if (!maybe_registry.is_identical_to(new_array)) {
    4251      264368 :       proto_info->set_prototype_users(*new_array);
    4252             :     }
    4253      497429 :     if (FLAG_trace_prototype_users) {
    4254             :       PrintF("Registering %p as a user of prototype %p (map=%p).\n",
    4255             :              reinterpret_cast<void*>(current_user->ptr()),
    4256             :              reinterpret_cast<void*>(proto->ptr()),
    4257           0 :              reinterpret_cast<void*>(proto->map()->ptr()));
    4258             :     }
    4259             : 
    4260             :     current_user = handle(proto->map(), isolate);
    4261             :     current_user_info = proto_info;
    4262             :   }
    4263             : }
    4264             : 
    4265             : // Can be called regardless of whether |user| was actually registered with
    4266             : // |prototype|. Returns true when there was a registration.
    4267             : // static
    4268     3090180 : bool JSObject::UnregisterPrototypeUser(Handle<Map> user, Isolate* isolate) {
    4269             :   DCHECK(user->is_prototype_map());
    4270             :   // If it doesn't have a PrototypeInfo, it was never registered.
    4271     6180363 :   if (!user->prototype_info()->IsPrototypeInfo()) return false;
    4272             :   // If it had no prototype before, see if it had users that might expect
    4273             :   // registration.
    4274     1142588 :   if (!user->prototype()->IsJSObject()) {
    4275             :     Object users =
    4276       69724 :         PrototypeInfo::cast(user->prototype_info())->prototype_users();
    4277             :     return users->IsWeakArrayList();
    4278             :   }
    4279             :   Handle<JSObject> prototype(JSObject::cast(user->prototype()), isolate);
    4280             :   Handle<PrototypeInfo> user_info =
    4281      501569 :       Map::GetOrCreatePrototypeInfo(user, isolate);
    4282             :   int slot = user_info->registry_slot();
    4283      501570 :   if (slot == PrototypeInfo::UNREGISTERED) return false;
    4284             :   DCHECK(prototype->map()->is_prototype_map());
    4285             :   Object maybe_proto_info = prototype->map()->prototype_info();
    4286             :   // User knows its registry slot, prototype info and user registry must exist.
    4287             :   DCHECK(maybe_proto_info->IsPrototypeInfo());
    4288             :   Handle<PrototypeInfo> proto_info(PrototypeInfo::cast(maybe_proto_info),
    4289             :                                    isolate);
    4290             :   Handle<WeakArrayList> prototype_users(
    4291             :       WeakArrayList::cast(proto_info->prototype_users()), isolate);
    4292             :   DCHECK_EQ(prototype_users->Get(slot), HeapObjectReference::Weak(*user));
    4293      124786 :   PrototypeUsers::MarkSlotEmpty(*prototype_users, slot);
    4294      124785 :   if (FLAG_trace_prototype_users) {
    4295             :     PrintF("Unregistering %p as a user of prototype %p.\n",
    4296             :            reinterpret_cast<void*>(user->ptr()),
    4297           0 :            reinterpret_cast<void*>(prototype->ptr()));
    4298             :   }
    4299             :   return true;
    4300             : }
    4301             : 
    4302             : namespace {
    4303             : 
    4304             : // This function must be kept in sync with
    4305             : // AccessorAssembler::InvalidateValidityCellIfPrototype() which does pre-checks
    4306             : // before jumping here.
    4307    14986425 : void InvalidateOnePrototypeValidityCellInternal(Map map) {
    4308             :   DCHECK(map->is_prototype_map());
    4309    14986425 :   if (FLAG_trace_prototype_users) {
    4310             :     PrintF("Invalidating prototype map %p 's cell\n",
    4311           0 :            reinterpret_cast<void*>(map.ptr()));
    4312             :   }
    4313    14986425 :   Object maybe_cell = map->prototype_validity_cell();
    4314    14986431 :   if (maybe_cell->IsCell()) {
    4315             :     // Just set the value; the cell will be replaced lazily.
    4316    14921731 :     Cell cell = Cell::cast(maybe_cell);
    4317    14921731 :     cell->set_value(Smi::FromInt(Map::kPrototypeChainInvalid));
    4318             :   }
    4319    14986431 : }
    4320             : 
    4321    14162507 : void InvalidatePrototypeChainsInternal(Map map) {
    4322    14162507 :   InvalidateOnePrototypeValidityCellInternal(map);
    4323             : 
    4324    14162511 :   Object maybe_proto_info = map->prototype_info();
    4325    25810472 :   if (!maybe_proto_info->IsPrototypeInfo()) return;
    4326             :   PrototypeInfo proto_info = PrototypeInfo::cast(maybe_proto_info);
    4327     6821568 :   if (!proto_info->prototype_users()->IsWeakArrayList()) {
    4328             :     return;
    4329             :   }
    4330             :   WeakArrayList prototype_users =
    4331     2514549 :       WeakArrayList::cast(proto_info->prototype_users());
    4332             :   // For now, only maps register themselves as users.
    4333    14491684 :   for (int i = PrototypeUsers::kFirstIndex; i < prototype_users->length();
    4334             :        ++i) {
    4335     4731293 :     HeapObject heap_object;
    4336     7184907 :     if (prototype_users->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
    4337             :         heap_object->IsMap()) {
    4338             :       // Walk the prototype chain (backwards, towards leaf objects) if
    4339             :       // necessary.
    4340     2453614 :       InvalidatePrototypeChainsInternal(Map::cast(heap_object));
    4341             :     }
    4342             :   }
    4343             : }
    4344             : 
    4345             : }  // namespace
    4346             : 
    4347             : // static
    4348     8573190 : Map JSObject::InvalidatePrototypeChains(Map map) {
    4349             :   DisallowHeapAllocation no_gc;
    4350    11708897 :   InvalidatePrototypeChainsInternal(map);
    4351     8573191 :   return map;
    4352             : }
    4353             : 
    4354             : // We also invalidate global objects validity cell when a new lexical
    4355             : // environment variable is added. This is necessary to ensure that
    4356             : // Load/StoreGlobalIC handlers that load/store from global object's prototype
    4357             : // get properly invalidated.
    4358             : // Note, that the normal Load/StoreICs that load/store through the global object
    4359             : // in the prototype chain are not affected by appearance of a new lexical
    4360             : // variable and therefore we don't propagate invalidation down.
    4361             : // static
    4362      823919 : void JSObject::InvalidatePrototypeValidityCell(JSGlobalObject global) {
    4363             :   DisallowHeapAllocation no_gc;
    4364      823919 :   InvalidateOnePrototypeValidityCellInternal(global->map());
    4365      823919 : }
    4366             : 
    4367      210624 : Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
    4368             :                                    Handle<Object> value, bool from_javascript,
    4369             :                                    ShouldThrow should_throw) {
    4370             :   Isolate* isolate = object->GetIsolate();
    4371             : 
    4372             : #ifdef DEBUG
    4373             :   int size = object->Size();
    4374             : #endif
    4375             : 
    4376      210624 :   if (from_javascript) {
    4377      381565 :     if (object->IsAccessCheckNeeded() &&
    4378          35 :         !isolate->MayAccess(handle(isolate->context(), isolate), object)) {
    4379           0 :       isolate->ReportFailedAccessCheck(object);
    4380           0 :       RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
    4381           0 :       RETURN_FAILURE(isolate, should_throw,
    4382             :                      NewTypeError(MessageTemplate::kNoAccess));
    4383             :     }
    4384             :   } else {
    4385             :     DCHECK(!object->IsAccessCheckNeeded());
    4386             :   }
    4387             : 
    4388             :   // Silently ignore the change if value is not a JSObject or null.
    4389             :   // SpiderMonkey behaves this way.
    4390      444662 :   if (!value->IsJSReceiver() && !value->IsNull(isolate)) return Just(true);
    4391             : 
    4392             :   bool all_extensible = object->map()->is_extensible();
    4393             :   Handle<JSObject> real_receiver = object;
    4394      210609 :   if (from_javascript) {
    4395             :     // Find the first object in the chain whose prototype object is not
    4396             :     // hidden.
    4397             :     PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
    4398      190765 :                            PrototypeIterator::END_AT_NON_HIDDEN);
    4399      384704 :     while (!iter.IsAtEnd()) {
    4400             :       // Casting to JSObject is fine because hidden prototypes are never
    4401             :       // JSProxies.
    4402             :       real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
    4403        3174 :       iter.Advance();
    4404        6348 :       all_extensible = all_extensible && real_receiver->map()->is_extensible();
    4405             :     }
    4406             :   }
    4407             :   Handle<Map> map(real_receiver->map(), isolate);
    4408             : 
    4409             :   // Nothing to do if prototype is already set.
    4410      210609 :   if (map->prototype() == *value) return Just(true);
    4411             : 
    4412      184928 :   bool immutable_proto = map->is_immutable_proto();
    4413      184928 :   if (immutable_proto) {
    4414         171 :     RETURN_FAILURE(
    4415             :         isolate, should_throw,
    4416             :         NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
    4417             :   }
    4418             : 
    4419             :   // From 8.6.2 Object Internal Methods
    4420             :   // ...
    4421             :   // In addition, if [[Extensible]] is false the value of the [[Class]] and
    4422             :   // [[Prototype]] internal properties of the object may not be modified.
    4423             :   // ...
    4424             :   // Implementation specific extensions that modify [[Class]], [[Prototype]]
    4425             :   // or [[Extensible]] must not violate the invariants defined in the preceding
    4426             :   // paragraph.
    4427      184865 :   if (!all_extensible) {
    4428         495 :     RETURN_FAILURE(isolate, should_throw,
    4429             :                    NewTypeError(MessageTemplate::kNonExtensibleProto, object));
    4430             :   }
    4431             : 
    4432             :   // Before we can set the prototype we need to be sure prototype cycles are
    4433             :   // prevented.  It is sufficient to validate that the receiver is not in the
    4434             :   // new prototype chain.
    4435      369244 :   if (value->IsJSReceiver()) {
    4436      550217 :     for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
    4437             :                                 kStartAtReceiver);
    4438      377266 :          !iter.IsAtEnd(); iter.Advance()) {
    4439      754688 :       if (iter.GetCurrent<JSReceiver>() == *object) {
    4440             :         // Cycle detected.
    4441         198 :         RETURN_FAILURE(isolate, should_throw,
    4442             :                        NewTypeError(MessageTemplate::kCyclicProto));
    4443             :       }
    4444             :     }
    4445             :   }
    4446             : 
    4447             :   // Set the new prototype of the object.
    4448             : 
    4449             :   isolate->UpdateNoElementsProtectorOnSetPrototype(real_receiver);
    4450             : 
    4451      184544 :   Handle<Map> new_map = Map::TransitionToPrototype(isolate, map, value);
    4452             :   DCHECK(new_map->prototype() == *value);
    4453      184544 :   JSObject::MigrateToMap(real_receiver, new_map);
    4454             : 
    4455             :   DCHECK(size == object->Size());
    4456             :   return Just(true);
    4457             : }
    4458             : 
    4459             : // static
    4460          24 : void JSObject::SetImmutableProto(Handle<JSObject> object) {
    4461             :   DCHECK(!object->IsAccessCheckNeeded());  // Never called from JS
    4462             :   Handle<Map> map(object->map(), object->GetIsolate());
    4463             : 
    4464             :   // Nothing to do if prototype is already set.
    4465          42 :   if (map->is_immutable_proto()) return;
    4466             : 
    4467             :   Handle<Map> new_map =
    4468           6 :       Map::TransitionToImmutableProto(object->GetIsolate(), map);
    4469           6 :   object->synchronized_set_map(*new_map);
    4470             : }
    4471             : 
    4472      430472 : void JSObject::EnsureCanContainElements(Handle<JSObject> object,
    4473             :                                         Arguments* args, uint32_t first_arg,
    4474             :                                         uint32_t arg_count,
    4475             :                                         EnsureElementsMode mode) {
    4476             :   // Elements in |Arguments| are ordered backwards (because they're on the
    4477             :   // stack), but the method that's called here iterates over them in forward
    4478             :   // direction.
    4479             :   return EnsureCanContainElements(
    4480      860944 :       object, args->slot_at(first_arg + arg_count - 1), arg_count, mode);
    4481             : }
    4482             : 
    4483   257471431 : ElementsAccessor* JSObject::GetElementsAccessor() {
    4484   515238330 :   return ElementsAccessor::ForKind(GetElementsKind());
    4485             : }
    4486             : 
    4487     9450215 : void JSObject::ValidateElements(JSObject object) {
    4488             : #ifdef ENABLE_SLOW_DCHECKS
    4489             :   if (FLAG_enable_slow_asserts) {
    4490             :     object->GetElementsAccessor()->Validate(object);
    4491             :   }
    4492             : #endif
    4493     9450215 : }
    4494             : 
    4495      102666 : bool JSObject::WouldConvertToSlowElements(uint32_t index) {
    4496      102666 :   if (!HasFastElements()) return false;
    4497       24608 :   uint32_t capacity = static_cast<uint32_t>(elements()->length());
    4498             :   uint32_t new_capacity;
    4499       12304 :   return ShouldConvertToSlowElements(*this, capacity, index, &new_capacity);
    4500             : }
    4501             : 
    4502      878477 : static bool ShouldConvertToFastElements(JSObject object,
    4503             :                                         NumberDictionary dictionary,
    4504             :                                         uint32_t index,
    4505             :                                         uint32_t* new_capacity) {
    4506             :   // If properties with non-standard attributes or accessors were added, we
    4507             :   // cannot go back to fast elements.
    4508      878477 :   if (dictionary->requires_slow_elements()) return false;
    4509             : 
    4510             :   // Adding a property with this index will require slow elements.
    4511      855097 :   if (index >= static_cast<uint32_t>(Smi::kMaxValue)) return false;
    4512             : 
    4513      854974 :   if (object->IsJSArray()) {
    4514      569737 :     Object length = JSArray::cast(object)->length();
    4515      569737 :     if (!length->IsSmi()) return false;
    4516      569719 :     *new_capacity = static_cast<uint32_t>(Smi::ToInt(length));
    4517      285237 :   } else if (object->IsJSSloppyArgumentsObject()) {
    4518             :     return false;
    4519             :   } else {
    4520      186111 :     *new_capacity = dictionary->max_number_key() + 1;
    4521             :   }
    4522     1511660 :   *new_capacity = Max(index + 1, *new_capacity);
    4523             : 
    4524      755830 :   uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
    4525      755830 :                              NumberDictionary::kEntrySize;
    4526             : 
    4527             :   // Turn fast if the dictionary only saves 50% space.
    4528      755830 :   return 2 * dictionary_size >= *new_capacity;
    4529             : }
    4530             : 
    4531         488 : static ElementsKind BestFittingFastElementsKind(JSObject object) {
    4532         488 :   if (!object->map()->CanHaveFastTransitionableElementsKind()) {
    4533             :     return HOLEY_ELEMENTS;
    4534             :   }
    4535         222 :   if (object->HasSloppyArgumentsElements()) {
    4536             :     return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
    4537             :   }
    4538         222 :   if (object->HasStringWrapperElements()) {
    4539             :     return FAST_STRING_WRAPPER_ELEMENTS;
    4540             :   }
    4541             :   DCHECK(object->HasDictionaryElements());
    4542         213 :   NumberDictionary dictionary = object->element_dictionary();
    4543             :   ElementsKind kind = HOLEY_SMI_ELEMENTS;
    4544      218012 :   for (int i = 0; i < dictionary->Capacity(); i++) {
    4545      217844 :     Object key = dictionary->KeyAt(i);
    4546      217844 :     if (key->IsNumber()) {
    4547       72427 :       Object value = dictionary->ValueAt(i);
    4548       72472 :       if (!value->IsNumber()) return HOLEY_ELEMENTS;
    4549       72382 :       if (!value->IsSmi()) {
    4550        6838 :         if (!FLAG_unbox_double_arrays) return HOLEY_ELEMENTS;
    4551             :         kind = HOLEY_DOUBLE_ELEMENTS;
    4552             :       }
    4553             :     }
    4554             :   }
    4555             :   return kind;
    4556             : }
    4557             : 
    4558             : // static
    4559     6201325 : void JSObject::AddDataElement(Handle<JSObject> object, uint32_t index,
    4560             :                               Handle<Object> value,
    4561             :                               PropertyAttributes attributes) {
    4562             :   DCHECK(object->map()->is_extensible());
    4563             : 
    4564             :   Isolate* isolate = object->GetIsolate();
    4565             : 
    4566     6201325 :   uint32_t old_length = 0;
    4567     6201325 :   uint32_t new_capacity = 0;
    4568             : 
    4569    12402651 :   if (object->IsJSArray()) {
    4570     5714917 :     CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length));
    4571             :   }
    4572             : 
    4573     6201327 :   ElementsKind kind = object->GetElementsKind();
    4574     6201327 :   FixedArrayBase elements = object->elements();
    4575             :   ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
    4576     6201326 :   if (IsSloppyArgumentsElementsKind(kind)) {
    4577      119568 :     elements = SloppyArgumentsElements::cast(elements)->arguments();
    4578             :     dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
    4579     6081758 :   } else if (IsStringWrapperElementsKind(kind)) {
    4580             :     dictionary_kind = SLOW_STRING_WRAPPER_ELEMENTS;
    4581             :   }
    4582             : 
    4583     6201326 :   if (attributes != NONE) {
    4584             :     kind = dictionary_kind;
    4585     6182093 :   } else if (elements->IsNumberDictionary()) {
    4586             :     kind = ShouldConvertToFastElements(
    4587      878477 :                *object, NumberDictionary::cast(elements), index, &new_capacity)
    4588             :                ? BestFittingFastElementsKind(*object)
    4589      878965 :                : dictionary_kind;
    4590     5303614 :   } else if (ShouldConvertToSlowElements(
    4591             :                  *object, static_cast<uint32_t>(elements->length()), index,
    4592     5303614 :                  &new_capacity)) {
    4593             :     kind = dictionary_kind;
    4594             :   }
    4595             : 
    4596     6201325 :   ElementsKind to = value->OptimalElementsKind();
    4597     8962203 :   if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
    4598             :     to = GetHoleyElementsKind(to);
    4599             :     kind = GetHoleyElementsKind(kind);
    4600             :   }
    4601             :   to = GetMoreGeneralElementsKind(kind, to);
    4602             :   ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
    4603     6201325 :   accessor->Add(object, index, value, attributes, new_capacity);
    4604             : 
    4605    12402654 :   if (object->IsJSArray() && index >= old_length) {
    4606             :     Handle<Object> new_length =
    4607     1543680 :         isolate->factory()->NewNumberFromUint(index + 1);
    4608     1543680 :     JSArray::cast(*object)->set_length(*new_length);
    4609             :   }
    4610     6201326 : }
    4611             : 
    4612             : template <AllocationSiteUpdateMode update_or_check>
    4613      877018 : bool JSObject::UpdateAllocationSite(Handle<JSObject> object,
    4614             :                                     ElementsKind to_kind) {
    4615     1754037 :   if (!object->IsJSArray()) return false;
    4616             : 
    4617      624629 :   if (!Heap::InYoungGeneration(*object)) return false;
    4618             : 
    4619      613225 :   if (Heap::IsLargeObject(*object)) return false;
    4620             : 
    4621             :   Handle<AllocationSite> site;
    4622             :   {
    4623             :     DisallowHeapAllocation no_allocation;
    4624             : 
    4625             :     Heap* heap = object->GetHeap();
    4626             :     AllocationMemento memento =
    4627     1226452 :         heap->FindAllocationMemento<Heap::kForRuntime>(object->map(), *object);
    4628      613226 :     if (memento.is_null()) return false;
    4629             : 
    4630             :     // Walk through to the Allocation Site
    4631      745857 :     site = handle(memento->GetAllocationSite(), heap->isolate());
    4632             :   }
    4633             :   return AllocationSite::DigestTransitionFeedback<update_or_check>(site,
    4634      372928 :                                                                    to_kind);
    4635             : }
    4636             : 
    4637             : template bool
    4638             : JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>(
    4639             :     Handle<JSObject> object, ElementsKind to_kind);
    4640             : 
    4641             : template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>(
    4642             :     Handle<JSObject> object, ElementsKind to_kind);
    4643             : 
    4644      141988 : void JSObject::TransitionElementsKind(Handle<JSObject> object,
    4645             :                                       ElementsKind to_kind) {
    4646      141989 :   ElementsKind from_kind = object->GetElementsKind();
    4647             : 
    4648      141990 :   if (IsHoleyElementsKind(from_kind)) {
    4649             :     to_kind = GetHoleyElementsKind(to_kind);
    4650             :   }
    4651             : 
    4652      283981 :   if (from_kind == to_kind) return;
    4653             : 
    4654             :   // This method should never be called for any other case.
    4655             :   DCHECK(IsFastElementsKind(from_kind));
    4656             :   DCHECK(IsFastElementsKind(to_kind));
    4657             :   DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
    4658             : 
    4659      141847 :   UpdateAllocationSite(object, to_kind);
    4660      565013 :   if (object->elements() == object->GetReadOnlyRoots().empty_fixed_array() ||
    4661             :       IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
    4662             :     // No change is needed to the elements() buffer, the transition
    4663             :     // only requires a map change.
    4664      137213 :     Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
    4665      137212 :     MigrateToMap(object, new_map);
    4666             :     if (FLAG_trace_elements_transitions) {
    4667             :       Handle<FixedArrayBase> elms(object->elements(), object->GetIsolate());
    4668             :       PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
    4669             :     }
    4670             :   } else {
    4671             :     DCHECK((IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
    4672             :            (IsDoubleElementsKind(from_kind) && IsObjectElementsKind(to_kind)));
    4673        9268 :     uint32_t c = static_cast<uint32_t>(object->elements()->length());
    4674        4634 :     ElementsAccessor::ForKind(to_kind)->GrowCapacityAndConvert(object, c);
    4675             :   }
    4676             : }
    4677             : 
    4678             : template <typename BackingStore>
    4679      283102 : static int HoleyElementsUsage(JSObject object, BackingStore store) {
    4680             :   Isolate* isolate = object->GetIsolate();
    4681             :   int limit = object->IsJSArray() ? Smi::ToInt(JSArray::cast(object)->length())
    4682      285823 :                                   : store->length();
    4683             :   int used = 0;
    4684   299010200 :   for (int i = 0; i < limit; ++i) {
    4685   298727098 :     if (!store->is_the_hole(isolate, i)) ++used;
    4686             :   }
    4687      283102 :   return used;
    4688             : }
    4689             : 
    4690      294630 : int JSObject::GetFastElementsUsage() {
    4691      294630 :   FixedArrayBase store = elements();
    4692      294630 :   switch (GetElementsKind()) {
    4693             :     case PACKED_SMI_ELEMENTS:
    4694             :     case PACKED_DOUBLE_ELEMENTS:
    4695             :     case PACKED_ELEMENTS:
    4696       11501 :       return IsJSArray() ? Smi::ToInt(JSArray::cast(*this)->length())
    4697       34406 :                          : store->length();
    4698             :     case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
    4699         739 :       store = SloppyArgumentsElements::cast(store)->arguments();
    4700             :       V8_FALLTHROUGH;
    4701             :     case HOLEY_SMI_ELEMENTS:
    4702             :     case HOLEY_ELEMENTS:
    4703             :     case FAST_STRING_WRAPPER_ELEMENTS:
    4704      282952 :       return HoleyElementsUsage(*this, FixedArray::cast(store));
    4705             :     case HOLEY_DOUBLE_ELEMENTS:
    4706         354 :       if (elements()->length() == 0) return 0;
    4707         150 :       return HoleyElementsUsage(*this, FixedDoubleArray::cast(store));
    4708             : 
    4709             :     case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
    4710             :     case SLOW_STRING_WRAPPER_ELEMENTS:
    4711             :     case DICTIONARY_ELEMENTS:
    4712             :     case NO_ELEMENTS:
    4713             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
    4714             : 
    4715             :       TYPED_ARRAYS(TYPED_ARRAY_CASE)
    4716             : #undef TYPED_ARRAY_CASE
    4717           0 :       UNREACHABLE();
    4718             :   }
    4719             :   return 0;
    4720             : }
    4721             : 
    4722      114158 : MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it,
    4723             :                                                          bool* done) {
    4724             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
    4725      114158 :   return GetPropertyWithInterceptorInternal(it, it->GetInterceptor(), done);
    4726             : }
    4727             : 
    4728        5842 : Maybe<bool> JSObject::HasRealNamedProperty(Handle<JSObject> object,
    4729             :                                            Handle<Name> name) {
    4730             :   LookupIterator it = LookupIterator::PropertyOrElement(
    4731        5842 :       object->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    4732        5842 :   return HasProperty(&it);
    4733             : }
    4734             : 
    4735          17 : Maybe<bool> JSObject::HasRealElementProperty(Handle<JSObject> object,
    4736             :                                              uint32_t index) {
    4737             :   Isolate* isolate = object->GetIsolate();
    4738             :   LookupIterator it(isolate, object, index, object,
    4739             :                     LookupIterator::OWN_SKIP_INTERCEPTOR);
    4740          17 :   return HasProperty(&it);
    4741             : }
    4742             : 
    4743           5 : Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
    4744             :                                                    Handle<Name> name) {
    4745             :   LookupIterator it = LookupIterator::PropertyOrElement(
    4746           5 :       object->GetIsolate(), object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
    4747           5 :   Maybe<PropertyAttributes> maybe_result = GetPropertyAttributes(&it);
    4748           5 :   return maybe_result.IsJust() ? Just(it.state() == LookupIterator::ACCESSOR)
    4749          10 :                                : Nothing<bool>();
    4750             : }
    4751             : 
    4752           0 : bool JSObject::IsApiWrapper() {
    4753             :   // These object types can carry information relevant for embedders. The
    4754             :   // *_API_* types are generated through templates which can have embedder
    4755             :   // fields. The other types have their embedder fields added at compile time.
    4756             :   auto instance_type = map()->instance_type();
    4757           0 :   return instance_type == JS_API_OBJECT_TYPE ||
    4758           0 :          instance_type == JS_ARRAY_BUFFER_TYPE ||
    4759           0 :          instance_type == JS_DATA_VIEW_TYPE ||
    4760           0 :          instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
    4761           0 :          instance_type == JS_TYPED_ARRAY_TYPE;
    4762             : }
    4763             : 
    4764       26695 : bool JSObject::IsDroppableApiWrapper() {
    4765             :   auto instance_type = map()->instance_type();
    4766       26695 :   return instance_type == JS_API_OBJECT_TYPE ||
    4767       26695 :          instance_type == JS_SPECIAL_API_OBJECT_TYPE;
    4768             : }
    4769             : 
    4770             : // static
    4771           9 : MaybeHandle<NativeContext> JSBoundFunction::GetFunctionRealm(
    4772             :     Handle<JSBoundFunction> function) {
    4773             :   DCHECK(function->map()->is_constructor());
    4774             :   return JSReceiver::GetFunctionRealm(
    4775          18 :       handle(function->bound_target_function(), function->GetIsolate()));
    4776             : }
    4777             : 
    4778             : // static
    4779          77 : MaybeHandle<String> JSBoundFunction::GetName(Isolate* isolate,
    4780             :                                              Handle<JSBoundFunction> function) {
    4781             :   Handle<String> prefix = isolate->factory()->bound__string();
    4782             :   Handle<String> target_name = prefix;
    4783             :   Factory* factory = isolate->factory();
    4784             :   // Concatenate the "bound " up to the last non-bound target.
    4785         231 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    4786           0 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, target_name,
    4787             :                                factory->NewConsString(prefix, target_name),
    4788             :                                String);
    4789           0 :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    4790           0 :                       isolate);
    4791             :   }
    4792         154 :   if (function->bound_target_function()->IsJSFunction()) {
    4793             :     Handle<JSFunction> target(
    4794         154 :         JSFunction::cast(function->bound_target_function()), isolate);
    4795          77 :     Handle<Object> name = JSFunction::GetName(isolate, target);
    4796         154 :     if (!name->IsString()) return target_name;
    4797          77 :     return factory->NewConsString(target_name, Handle<String>::cast(name));
    4798             :   }
    4799             :   // This will omit the proper target name for bound JSProxies.
    4800           0 :   return target_name;
    4801             : }
    4802             : 
    4803             : // static
    4804         311 : Maybe<int> JSBoundFunction::GetLength(Isolate* isolate,
    4805             :                                       Handle<JSBoundFunction> function) {
    4806         622 :   int nof_bound_arguments = function->bound_arguments()->length();
    4807        1689 :   while (function->bound_target_function()->IsJSBoundFunction()) {
    4808         756 :     function = handle(JSBoundFunction::cast(function->bound_target_function()),
    4809         756 :                       isolate);
    4810             :     // Make sure we never overflow {nof_bound_arguments}, the number of
    4811             :     // arguments of a function is strictly limited by the max length of an
    4812             :     // JSAarray, Smi::kMaxValue is thus a reasonably good overestimate.
    4813         756 :     int length = function->bound_arguments()->length();
    4814         378 :     if (V8_LIKELY(Smi::kMaxValue - nof_bound_arguments > length)) {
    4815         378 :       nof_bound_arguments += length;
    4816             :     } else {
    4817             :       nof_bound_arguments = Smi::kMaxValue;
    4818             :     }
    4819             :   }
    4820             :   // All non JSFunction targets get a direct property and don't use this
    4821             :   // accessor.
    4822         622 :   Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
    4823         622 :                             isolate);
    4824         311 :   Maybe<int> target_length = JSFunction::GetLength(isolate, target);
    4825         311 :   if (target_length.IsNothing()) return target_length;
    4826             : 
    4827         311 :   int length = Max(0, target_length.FromJust() - nof_bound_arguments);
    4828             :   return Just(length);
    4829             : }
    4830             : 
    4831             : // static
    4832          55 : Handle<String> JSBoundFunction::ToString(Handle<JSBoundFunction> function) {
    4833             :   Isolate* const isolate = function->GetIsolate();
    4834          55 :   return isolate->factory()->function_native_code_string();
    4835             : }
    4836             : 
    4837             : // static
    4838      129402 : Handle<Object> JSFunction::GetName(Isolate* isolate,
    4839             :                                    Handle<JSFunction> function) {
    4840      129402 :   if (function->shared()->name_should_print_as_anonymous()) {
    4841          20 :     return isolate->factory()->anonymous_string();
    4842             :   }
    4843      258764 :   return handle(function->shared()->Name(), isolate);
    4844             : }
    4845             : 
    4846             : // static
    4847       53847 : Maybe<int> JSFunction::GetLength(Isolate* isolate,
    4848             :                                  Handle<JSFunction> function) {
    4849             :   int length = 0;
    4850       53847 :   IsCompiledScope is_compiled_scope(function->shared()->is_compiled_scope());
    4851       53847 :   if (is_compiled_scope.is_compiled()) {
    4852      105428 :     length = function->shared()->GetLength();
    4853             :   } else {
    4854             :     // If the function isn't compiled yet, the length is not computed
    4855             :     // correctly yet. Compile it now and return the right length.
    4856        1133 :     if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION,
    4857             :                           &is_compiled_scope)) {
    4858        1476 :       length = function->shared()->GetLength();
    4859             :     }
    4860        1133 :     if (isolate->has_pending_exception()) return Nothing<int>();
    4861             :   }
    4862             :   DCHECK_GE(length, 0);
    4863             :   return Just(length);
    4864             : }
    4865             : 
    4866             : // static
    4867        3342 : Handle<NativeContext> JSFunction::GetFunctionRealm(
    4868             :     Handle<JSFunction> function) {
    4869             :   DCHECK(function->map()->is_constructor());
    4870        6684 :   return handle(function->context()->native_context(), function->GetIsolate());
    4871             : }
    4872             : 
    4873      480173 : void JSFunction::MarkForOptimization(ConcurrencyMode mode) {
    4874      959971 :   Isolate* isolate = GetIsolate();
    4875      959971 :   if (!isolate->concurrent_recompilation_enabled() ||
    4876      479798 :       isolate->bootstrapper()->IsActive()) {
    4877             :     mode = ConcurrencyMode::kNotConcurrent;
    4878             :   }
    4879             : 
    4880             :   DCHECK(!is_compiled() || IsInterpreted());
    4881             :   DCHECK(shared()->IsInterpreted());
    4882             :   DCHECK(!IsOptimized());
    4883             :   DCHECK(!HasOptimizedCode());
    4884             :   DCHECK(shared()->allows_lazy_compilation() ||
    4885             :          !shared()->optimization_disabled());
    4886             : 
    4887      480173 :   if (mode == ConcurrencyMode::kConcurrent) {
    4888       28648 :     if (IsInOptimizationQueue()) {
    4889           0 :       if (FLAG_trace_concurrent_recompilation) {
    4890           0 :         PrintF("  ** Not marking ");
    4891           0 :         ShortPrint();
    4892           0 :         PrintF(" -- already in optimization queue.\n");
    4893             :       }
    4894      480174 :       return;
    4895             :     }
    4896       28648 :     if (FLAG_trace_concurrent_recompilation) {
    4897           0 :       PrintF("  ** Marking ");
    4898           0 :       ShortPrint();
    4899           0 :       PrintF(" for concurrent recompilation.\n");
    4900             :     }
    4901             :   }
    4902             : 
    4903             :   SetOptimizationMarker(mode == ConcurrencyMode::kConcurrent
    4904             :                             ? OptimizationMarker::kCompileOptimizedConcurrent
    4905      480174 :                             : OptimizationMarker::kCompileOptimized);
    4906             : }
    4907             : 
    4908             : // static
    4909     8409425 : void JSFunction::EnsureFeedbackVector(Handle<JSFunction> function) {
    4910             :   Isolate* const isolate = function->GetIsolate();
    4911             :   DCHECK(function->shared()->is_compiled());
    4912             :   DCHECK(FLAG_lite_mode || function->shared()->HasFeedbackMetadata());
    4913    19882720 :   if (!function->has_feedback_vector() &&
    4914    11473287 :       function->shared()->HasFeedbackMetadata()) {
    4915     6127709 :     Handle<SharedFunctionInfo> shared(function->shared(), isolate);
    4916     3063855 :     if (!shared->HasAsmWasmData()) {
    4917             :       DCHECK(function->shared()->HasBytecodeArray());
    4918             :       Handle<FeedbackVector> feedback_vector =
    4919     3062072 :           FeedbackVector::New(isolate, shared);
    4920     9186211 :       if (function->raw_feedback_cell() ==
    4921     3062068 :           isolate->heap()->many_closures_cell()) {
    4922             :         Handle<FeedbackCell> feedback_cell =
    4923     1518610 :             isolate->factory()->NewOneClosureCell(feedback_vector);
    4924     1518611 :         function->set_raw_feedback_cell(*feedback_cell);
    4925             :       } else {
    4926     3086924 :         function->raw_feedback_cell()->set_value(*feedback_vector);
    4927             :       }
    4928             :     }
    4929             :   }
    4930     8409434 : }
    4931             : 
    4932             : namespace {
    4933             : 
    4934      377709 : void SetInstancePrototype(Isolate* isolate, Handle<JSFunction> function,
    4935             :                           Handle<JSReceiver> value) {
    4936             :   // Now some logic for the maps of the objects that are created by using this
    4937             :   // function as a constructor.
    4938      262438 :   if (function->has_initial_map()) {
    4939             :     // If the function has allocated the initial map replace it with a
    4940             :     // copy containing the new prototype.  Also complete any in-object
    4941             :     // slack tracking that is in progress at this point because it is
    4942             :     // still tracking the old copy.
    4943      115271 :     function->CompleteInobjectSlackTrackingIfActive();
    4944             : 
    4945      230542 :     Handle<Map> initial_map(function->initial_map(), isolate);
    4946             : 
    4947      229765 :     if (!isolate->bootstrapper()->IsActive() &&
    4948             :         initial_map->instance_type() == JS_OBJECT_TYPE) {
    4949             :       // Put the value in the initial map field until an initial map is needed.
    4950             :       // At that point, a new initial map is created and the prototype is put
    4951             :       // into the initial map where it belongs.
    4952      228322 :       function->set_prototype_or_initial_map(*value);
    4953             :     } else {
    4954             :       Handle<Map> new_map =
    4955        1110 :           Map::Copy(isolate, initial_map, "SetInstancePrototype");
    4956        1110 :       JSFunction::SetInitialMap(function, new_map, value);
    4957             : 
    4958             :       // If the function is used as the global Array function, cache the
    4959             :       // updated initial maps (and transitioned versions) in the native context.
    4960        2220 :       Handle<Context> native_context(function->context()->native_context(),
    4961        2220 :                                      isolate);
    4962             :       Handle<Object> array_function(
    4963        2220 :           native_context->get(Context::ARRAY_FUNCTION_INDEX), isolate);
    4964        3219 :       if (array_function->IsJSFunction() &&
    4965             :           *function == JSFunction::cast(*array_function)) {
    4966         111 :         CacheInitialJSArrayMaps(native_context, new_map);
    4967             :       }
    4968             :     }
    4969             : 
    4970             :     // Deoptimize all code that embeds the previous initial map.
    4971      230542 :     initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
    4972      115271 :         isolate, DependentCode::kInitialMapChangedGroup);
    4973             :   } else {
    4974             :     // Put the value in the initial map field until an initial map is
    4975             :     // needed.  At that point, a new initial map is created and the
    4976             :     // prototype is put into the initial map where it belongs.
    4977      294334 :     function->set_prototype_or_initial_map(*value);
    4978      294334 :     if (value->IsJSObject()) {
    4979             :       // Optimize as prototype to detach it from its transition tree.
    4980      147104 :       JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
    4981             :     }
    4982             :   }
    4983      262438 : }
    4984             : 
    4985             : }  // anonymous namespace
    4986             : 
    4987      262438 : void JSFunction::SetPrototype(Handle<JSFunction> function,
    4988             :                               Handle<Object> value) {
    4989             :   DCHECK(function->IsConstructor() ||
    4990             :          IsGeneratorFunction(function->shared()->kind()));
    4991             :   Isolate* isolate = function->GetIsolate();
    4992             :   Handle<JSReceiver> construct_prototype;
    4993             : 
    4994             :   // If the value is not a JSReceiver, store the value in the map's
    4995             :   // constructor field so it can be accessed.  Also, set the prototype
    4996             :   // used for constructing objects to the original object prototype.
    4997             :   // See ECMA-262 13.2.2.
    4998      524876 :   if (!value->IsJSReceiver()) {
    4999             :     // Copy the map so this does not affect unrelated functions.
    5000             :     // Remove map transitions because they point to maps with a
    5001             :     // different prototype.
    5002             :     Handle<Map> new_map =
    5003       94222 :         Map::Copy(isolate, handle(function->map(), isolate), "SetPrototype");
    5004             : 
    5005       94222 :     JSObject::MigrateToMap(function, new_map);
    5006       94222 :     new_map->SetConstructor(*value);
    5007             :     new_map->set_has_non_instance_prototype(true);
    5008             : 
    5009      188444 :     FunctionKind kind = function->shared()->kind();
    5010      188444 :     Handle<Context> native_context(function->context()->native_context(),
    5011      188444 :                                    isolate);
    5012             : 
    5013             :     construct_prototype = Handle<JSReceiver>(
    5014             :         IsGeneratorFunction(kind)
    5015             :             ? IsAsyncFunction(kind)
    5016       94240 :                   ? native_context->initial_async_generator_prototype()
    5017       94294 :                   : native_context->initial_generator_prototype()
    5018      188363 :             : native_context->initial_object_prototype(),
    5019      376960 :         isolate);
    5020             :   } else {
    5021      168216 :     construct_prototype = Handle<JSReceiver>::cast(value);
    5022             :     function->map()->set_has_non_instance_prototype(false);
    5023             :   }
    5024             : 
    5025      262438 :   SetInstancePrototype(isolate, function, construct_prototype);
    5026      262438 : }
    5027             : 
    5028     4495096 : void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
    5029             :                                Handle<Object> prototype) {
    5030     4495098 :   if (map->prototype() != *prototype)
    5031     4494548 :     Map::SetPrototype(function->GetIsolate(), map, prototype);
    5032     8990204 :   function->set_prototype_or_initial_map(*map);
    5033     8990204 :   map->SetConstructor(*function);
    5034     4495101 :   if (FLAG_trace_maps) {
    5035        3003 :     LOG(function->GetIsolate(), MapEvent("InitialMap", Map(), *map, "",
    5036             :                                          function->shared()->DebugName()));
    5037             :   }
    5038     4495101 : }
    5039             : 
    5040    18755306 : void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
    5041             :   DCHECK(function->has_prototype_slot());
    5042             :   DCHECK(function->IsConstructor() ||
    5043             :          IsResumableFunction(function->shared()->kind()));
    5044    37212778 :   if (function->has_initial_map()) return;
    5045             :   Isolate* isolate = function->GetIsolate();
    5046             : 
    5047             :   // First create a new map with the size and number of in-object properties
    5048             :   // suggested by the function.
    5049             :   InstanceType instance_type;
    5050      595687 :   if (IsResumableFunction(function->shared()->kind())) {
    5051       17322 :     instance_type = IsAsyncGeneratorFunction(function->shared()->kind())
    5052             :                         ? JS_ASYNC_GENERATOR_OBJECT_TYPE
    5053        8661 :                         : JS_GENERATOR_OBJECT_TYPE;
    5054             :   } else {
    5055             :     instance_type = JS_OBJECT_TYPE;
    5056             :   }
    5057             : 
    5058             :   int instance_size;
    5059             :   int inobject_properties;
    5060             :   int expected_nof_properties =
    5061      297844 :       CalculateExpectedNofProperties(isolate, function);
    5062             :   CalculateInstanceSizeHelper(instance_type, false, 0, expected_nof_properties,
    5063      297844 :                               &instance_size, &inobject_properties);
    5064             : 
    5065             :   Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size,
    5066             :                                                TERMINAL_FAST_ELEMENTS_KIND,
    5067      297844 :                                                inobject_properties);
    5068             : 
    5069             :   // Fetch or allocate prototype.
    5070             :   Handle<Object> prototype;
    5071      297844 :   if (function->has_instance_prototype()) {
    5072      475426 :     prototype = handle(function->instance_prototype(), isolate);
    5073             :   } else {
    5074       60131 :     prototype = isolate->factory()->NewFunctionPrototype(function);
    5075             :   }
    5076             :   DCHECK(map->has_fast_object_elements());
    5077             : 
    5078             :   // Finally link initial map and constructor function.
    5079             :   DCHECK(prototype->IsJSReceiver());
    5080      297844 :   JSFunction::SetInitialMap(function, map, prototype);
    5081      297844 :   map->StartInobjectSlackTracking();
    5082             : }
    5083             : 
    5084             : #ifdef DEBUG
    5085             : namespace {
    5086             : 
    5087             : bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
    5088             :   switch (instance_type) {
    5089             :     case JS_API_OBJECT_TYPE:
    5090             :     case JS_ARRAY_BUFFER_TYPE:
    5091             :     case JS_ARRAY_TYPE:
    5092             :     case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
    5093             :     case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
    5094             :     case JS_DATA_VIEW_TYPE:
    5095             :     case JS_DATE_TYPE:
    5096             :     case JS_FUNCTION_TYPE:
    5097             :     case JS_GENERATOR_OBJECT_TYPE:
    5098             : #ifdef V8_INTL_SUPPORT
    5099             :     case JS_INTL_COLLATOR_TYPE:
    5100             :     case JS_INTL_DATE_TIME_FORMAT_TYPE:
    5101             :     case JS_INTL_LIST_FORMAT_TYPE:
    5102             :     case JS_INTL_LOCALE_TYPE:
    5103             :     case JS_INTL_NUMBER_FORMAT_TYPE:
    5104             :     case JS_INTL_PLURAL_RULES_TYPE:
    5105             :     case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
    5106             :     case JS_INTL_SEGMENT_ITERATOR_TYPE:
    5107             :     case JS_INTL_SEGMENTER_TYPE:
    5108             :     case JS_INTL_V8_BREAK_ITERATOR_TYPE:
    5109             : #endif
    5110             :     case JS_ASYNC_FUNCTION_OBJECT_TYPE:
    5111             :     case JS_ASYNC_GENERATOR_OBJECT_TYPE:
    5112             :     case JS_MAP_TYPE:
    5113             :     case JS_MESSAGE_OBJECT_TYPE:
    5114             :     case JS_OBJECT_TYPE:
    5115             :     case JS_ERROR_TYPE:
    5116             :     case JS_ARGUMENTS_TYPE:
    5117             :     case JS_PROMISE_TYPE:
    5118             :     case JS_REGEXP_TYPE:
    5119             :     case JS_SET_TYPE:
    5120             :     case JS_SPECIAL_API_OBJECT_TYPE:
    5121             :     case JS_TYPED_ARRAY_TYPE:
    5122             :     case JS_VALUE_TYPE:
    5123             :     case JS_WEAK_MAP_TYPE:
    5124             :     case JS_WEAK_SET_TYPE:
    5125             :     case WASM_GLOBAL_TYPE:
    5126             :     case WASM_INSTANCE_TYPE:
    5127             :     case WASM_MEMORY_TYPE:
    5128             :     case WASM_MODULE_TYPE:
    5129             :     case WASM_TABLE_TYPE:
    5130             :       return true;
    5131             : 
    5132             :     case BIGINT_TYPE:
    5133             :     case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
    5134             :     case BYTECODE_ARRAY_TYPE:
    5135             :     case BYTE_ARRAY_TYPE:
    5136             :     case CELL_TYPE:
    5137             :     case CODE_TYPE:
    5138             :     case FILLER_TYPE:
    5139             :     case FIXED_ARRAY_TYPE:
    5140             :     case SCRIPT_CONTEXT_TABLE_TYPE:
    5141             :     case FIXED_DOUBLE_ARRAY_TYPE:
    5142             :     case FEEDBACK_METADATA_TYPE:
    5143             :     case FOREIGN_TYPE:
    5144             :     case FREE_SPACE_TYPE:
    5145             :     case HASH_TABLE_TYPE:
    5146             :     case ORDERED_HASH_MAP_TYPE:
    5147             :     case ORDERED_HASH_SET_TYPE:
    5148             :     case ORDERED_NAME_DICTIONARY_TYPE:
    5149             :     case NAME_DICTIONARY_TYPE:
    5150             :     case GLOBAL_DICTIONARY_TYPE:
    5151             :     case NUMBER_DICTIONARY_TYPE:
    5152             :     case SIMPLE_NUMBER_DICTIONARY_TYPE:
    5153             :     case STRING_TABLE_TYPE:
    5154             :     case HEAP_NUMBER_TYPE:
    5155             :     case JS_BOUND_FUNCTION_TYPE:
    5156             :     case JS_GLOBAL_OBJECT_TYPE:
    5157             :     case JS_GLOBAL_PROXY_TYPE:
    5158             :     case JS_PROXY_TYPE:
    5159             :     case MAP_TYPE:
    5160             :     case MUTABLE_HEAP_NUMBER_TYPE:
    5161             :     case ODDBALL_TYPE:
    5162             :     case PROPERTY_CELL_TYPE:
    5163             :     case SHARED_FUNCTION_INFO_TYPE:
    5164             :     case SYMBOL_TYPE:
    5165             :     case ALLOCATION_SITE_TYPE:
    5166             : 
    5167             : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
    5168             :   case FIXED_##TYPE##_ARRAY_TYPE:
    5169             : #undef TYPED_ARRAY_CASE
    5170             : 
    5171             : #define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
    5172             :       STRUCT_LIST(MAKE_STRUCT_CASE)
    5173             : #undef MAKE_STRUCT_CASE
    5174             :       // We must not end up here for these instance types at all.
    5175             :       UNREACHABLE();
    5176             :     // Fall through.
    5177             :     default:
    5178             :       return false;
    5179             :   }
    5180             : }
    5181             : 
    5182             : }  // namespace
    5183             : #endif
    5184             : 
    5185             : namespace {
    5186             : 
    5187      448023 : bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
    5188             :                               Handle<JSFunction> constructor,
    5189             :                               Handle<Map> constructor_initial_map) {
    5190             :   // Use the default intrinsic prototype instead.
    5191      448024 :   if (!new_target->has_prototype_slot()) return false;
    5192             :   // Check that |function|'s initial map still in sync with the |constructor|,
    5193             :   // otherwise we must create a new initial map for |function|.
    5194     1331143 :   if (new_target->has_initial_map() &&
    5195      883129 :       new_target->initial_map()->GetConstructor() == *constructor) {
    5196             :     DCHECK(new_target->instance_prototype()->IsJSReceiver());
    5197             :     return true;
    5198             :   }
    5199             :   InstanceType instance_type = constructor_initial_map->instance_type();
    5200             :   DCHECK(CanSubclassHaveInobjectProperties(instance_type));
    5201             :   // Create a new map with the size and number of in-object properties
    5202             :   // suggested by |function|.
    5203             : 
    5204             :   // Link initial map and constructor function if the new.target is actually a
    5205             :   // subclass constructor.
    5206      611407 :   if (!IsDerivedConstructor(new_target->shared()->kind())) return false;
    5207             : 
    5208             :   int instance_size;
    5209             :   int in_object_properties;
    5210             :   int embedder_fields =
    5211       11217 :       JSObject::GetEmbedderFieldCount(*constructor_initial_map);
    5212             :   int expected_nof_properties =
    5213       11217 :       JSFunction::CalculateExpectedNofProperties(isolate, new_target);
    5214             :   JSFunction::CalculateInstanceSizeHelper(
    5215             :       instance_type, true, embedder_fields, expected_nof_properties,
    5216       11217 :       &instance_size, &in_object_properties);
    5217             : 
    5218       22434 :   int pre_allocated = constructor_initial_map->GetInObjectProperties() -
    5219       11217 :                       constructor_initial_map->UnusedPropertyFields();
    5220       22434 :   CHECK_LE(constructor_initial_map->UsedInstanceSize(), instance_size);
    5221       11216 :   int unused_property_fields = in_object_properties - pre_allocated;
    5222             :   Handle<Map> map =
    5223             :       Map::CopyInitialMap(isolate, constructor_initial_map, instance_size,
    5224       11216 :                           in_object_properties, unused_property_fields);
    5225       11217 :   map->set_new_target_is_base(false);
    5226       22434 :   Handle<Object> prototype(new_target->instance_prototype(), isolate);
    5227       11217 :   JSFunction::SetInitialMap(new_target, map, prototype);
    5228             :   DCHECK(new_target->instance_prototype()->IsJSReceiver());
    5229       22434 :   map->SetConstructor(*constructor);
    5230       11217 :   map->set_construction_counter(Map::kNoSlackTracking);
    5231       11217 :   map->StartInobjectSlackTracking();
    5232       11217 :   return true;
    5233             : }
    5234             : 
    5235             : }  // namespace
    5236             : 
    5237             : // static
    5238     3252119 : MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
    5239             :                                            Handle<JSFunction> constructor,
    5240             :                                            Handle<JSReceiver> new_target) {
    5241     3252119 :   EnsureHasInitialMap(constructor);
    5242             : 
    5243     6504254 :   Handle<Map> constructor_initial_map(constructor->initial_map(), isolate);
    5244     3252129 :   if (*new_target == *constructor) return constructor_initial_map;
    5245             : 
    5246             :   Handle<Map> result_map;
    5247             :   // Fast case, new.target is a subclass of constructor. The map is cacheable
    5248             :   // (and may already have been cached). new.target.prototype is guaranteed to
    5249             :   // be a JSReceiver.
    5250      899012 :   if (new_target->IsJSFunction()) {
    5251      448023 :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
    5252      448022 :     if (FastInitializeDerivedMap(isolate, function, constructor,
    5253             :                                  constructor_initial_map)) {
    5254      307053 :       return handle(function->initial_map(), isolate);
    5255             :     }
    5256             :   }
    5257             : 
    5258             :   // Slow path, new.target is either a proxy or can't cache the map.
    5259             :   // new.target.prototype is not guaranteed to be a JSReceiver, and may need to
    5260             :   // fall back to the intrinsicDefaultProto.
    5261             :   Handle<Object> prototype;
    5262      591960 :   if (new_target->IsJSFunction()) {
    5263      294495 :     Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
    5264      294495 :     if (function->has_prototype_slot()) {
    5265             :       // Make sure the new.target.prototype is cached.
    5266      294486 :       EnsureHasInitialMap(function);
    5267      588973 :       prototype = handle(function->prototype(), isolate);
    5268             :     } else {
    5269             :       // No prototype property, use the intrinsict default proto further down.
    5270             :       prototype = isolate->factory()->undefined_value();
    5271             :     }
    5272             :   } else {
    5273             :     Handle<String> prototype_string = isolate->factory()->prototype_string();
    5274        2970 :     ASSIGN_RETURN_ON_EXCEPTION(
    5275             :         isolate, prototype,
    5276             :         JSReceiver::GetProperty(isolate, new_target, prototype_string), Map);
    5277             :     // The above prototype lookup might change the constructor and its
    5278             :     // prototype, hence we have to reload the initial map.
    5279        1404 :     EnsureHasInitialMap(constructor);
    5280        2808 :     constructor_initial_map = handle(constructor->initial_map(), isolate);
    5281             :   }
    5282             : 
    5283             :   // If prototype is not a JSReceiver, fetch the intrinsicDefaultProto from the
    5284             :   // correct realm. Rather than directly fetching the .prototype, we fetch the
    5285             :   // constructor that points to the .prototype. This relies on
    5286             :   // constructor.prototype being FROZEN for those constructors.
    5287      591798 :   if (!prototype->IsJSReceiver()) {
    5288             :     Handle<Context> context;
    5289        2700 :     ASSIGN_RETURN_ON_EXCEPTION(isolate, context,
    5290             :                                JSReceiver::GetFunctionRealm(new_target), Map);
    5291             :     DCHECK(context->IsNativeContext());
    5292             :     Handle<Object> maybe_index = JSReceiver::GetDataProperty(
    5293        1350 :         constructor, isolate->factory()->native_context_index_symbol());
    5294        2700 :     int index = maybe_index->IsSmi() ? Smi::ToInt(*maybe_index)
    5295        2601 :                                      : Context::OBJECT_FUNCTION_INDEX;
    5296             :     Handle<JSFunction> realm_constructor(JSFunction::cast(context->get(index)),
    5297        2700 :                                          isolate);
    5298        2700 :     prototype = handle(realm_constructor->prototype(), isolate);
    5299             :   }
    5300             : 
    5301      295901 :   Handle<Map> map = Map::CopyInitialMap(isolate, constructor_initial_map);
    5302      295896 :   map->set_new_target_is_base(false);
    5303      591796 :   CHECK(prototype->IsJSReceiver());
    5304      295899 :   if (map->prototype() != *prototype)
    5305      295144 :     Map::SetPrototype(isolate, map, prototype);
    5306      591798 :   map->SetConstructor(*constructor);
    5307      295900 :   return map;
    5308             : }
    5309             : 
    5310     3674696 : int JSFunction::ComputeInstanceSizeWithMinSlack(Isolate* isolate) {
    5311     3674696 :   CHECK(has_initial_map());
    5312     7349396 :   if (initial_map()->IsInobjectSlackTrackingInProgress()) {
    5313        6092 :     int slack = initial_map()->ComputeMinObjectSlack(isolate);
    5314       12184 :     return initial_map()->InstanceSizeFromSlack(slack);
    5315             :   }
    5316     7337210 :   return initial_map()->instance_size();
    5317             : }
    5318             : 
    5319           0 : void JSFunction::PrintName(FILE* out) {
    5320           0 :   std::unique_ptr<char[]> name = shared()->DebugName()->ToCString();
    5321           0 :   PrintF(out, "%s", name.get());
    5322           0 : }
    5323             : 
    5324      517649 : Handle<String> JSFunction::GetName(Handle<JSFunction> function) {
    5325             :   Isolate* isolate = function->GetIsolate();
    5326             :   Handle<Object> name =
    5327      517649 :       JSReceiver::GetDataProperty(function, isolate->factory()->name_string());
    5328     1035298 :   if (name->IsString()) return Handle<String>::cast(name);
    5329     1033912 :   return handle(function->shared()->DebugName(), isolate);
    5330             : }
    5331             : 
    5332      406896 : Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
    5333             :   Isolate* isolate = function->GetIsolate();
    5334             :   Handle<Object> name = JSReceiver::GetDataProperty(
    5335      406896 :       function, isolate->factory()->display_name_string());
    5336      813792 :   if (name->IsString()) return Handle<String>::cast(name);
    5337      406862 :   return JSFunction::GetName(function);
    5338             : }
    5339             : 
    5340        6913 : bool JSFunction::SetName(Handle<JSFunction> function, Handle<Name> name,
    5341             :                          Handle<String> prefix) {
    5342             :   Isolate* isolate = function->GetIsolate();
    5343             :   Handle<String> function_name;
    5344       13826 :   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name,
    5345             :                                    Name::ToFunctionName(isolate, name), false);
    5346        6904 :   if (prefix->length() > 0) {
    5347        3183 :     IncrementalStringBuilder builder(isolate);
    5348        3183 :     builder.AppendString(prefix);
    5349             :     builder.AppendCharacter(' ');
    5350        3183 :     builder.AppendString(function_name);
    5351        6366 :     ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, function_name, builder.Finish(),
    5352             :                                      false);
    5353             :   }
    5354       13772 :   RETURN_ON_EXCEPTION_VALUE(
    5355             :       isolate,
    5356             :       JSObject::DefinePropertyOrElementIgnoreAttributes(
    5357             :           function, isolate->factory()->name_string(), function_name,
    5358             :           static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)),
    5359             :       false);
    5360        6886 :   return true;
    5361             : }
    5362             : 
    5363             : namespace {
    5364             : 
    5365     1082633 : Handle<String> NativeCodeFunctionSourceString(
    5366             :     Handle<SharedFunctionInfo> shared_info) {
    5367             :   Isolate* const isolate = shared_info->GetIsolate();
    5368     1082633 :   IncrementalStringBuilder builder(isolate);
    5369             :   builder.AppendCString("function ");
    5370     2165266 :   builder.AppendString(handle(shared_info->Name(), isolate));
    5371             :   builder.AppendCString("() { [native code] }");
    5372     2165266 :   return builder.Finish().ToHandleChecked();
    5373             : }
    5374             : 
    5375             : }  // namespace
    5376             : 
    5377             : // static
    5378     1889586 : Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
    5379             :   Isolate* const isolate = function->GetIsolate();
    5380     3779172 :   Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
    5381             : 
    5382             :   // Check if {function} should hide its source code.
    5383     1889586 :   if (!shared_info->IsUserJavaScript()) {
    5384     1082561 :     return NativeCodeFunctionSourceString(shared_info);
    5385             :   }
    5386             : 
    5387             :   // Check if we should print {function} as a class.
    5388             :   Handle<Object> maybe_class_positions = JSReceiver::GetDataProperty(
    5389      807025 :       function, isolate->factory()->class_positions_symbol());
    5390     1614050 :   if (maybe_class_positions->IsClassPositions()) {
    5391             :     ClassPositions class_positions =
    5392             :         ClassPositions::cast(*maybe_class_positions);
    5393             :     int start_position = class_positions->start();
    5394             :     int end_position = class_positions->end();
    5395             :     Handle<String> script_source(
    5396       43444 :         String::cast(Script::cast(shared_info->script())->source()), isolate);
    5397             :     return isolate->factory()->NewSubString(script_source, start_position,
    5398       21722 :                                             end_position);
    5399             :   }
    5400             : 
    5401             :   // Check if we have source code for the {function}.
    5402      785303 :   if (!shared_info->HasSourceCode()) {
    5403           0 :     return NativeCodeFunctionSourceString(shared_info);
    5404             :   }
    5405             : 
    5406      785303 :   if (shared_info->function_token_position() == kNoSourcePosition) {
    5407             :     // If the function token position isn't valid, return [native code] to
    5408             :     // ensure calling eval on the returned source code throws rather than
    5409             :     // giving inconsistent call behaviour.
    5410             :     isolate->CountUsage(
    5411          72 :         v8::Isolate::UseCounterFeature::kFunctionTokenOffsetTooLongForToString);
    5412          72 :     return NativeCodeFunctionSourceString(shared_info);
    5413             :   }
    5414             :   return Handle<String>::cast(
    5415      785231 :       SharedFunctionInfo::GetSourceCodeHarmony(shared_info));
    5416             : }
    5417             : 
    5418             : // static
    5419      309061 : int JSFunction::CalculateExpectedNofProperties(Isolate* isolate,
    5420             :                                                Handle<JSFunction> function) {
    5421             :   int expected_nof_properties = 0;
    5422     1252140 :   for (PrototypeIterator iter(isolate, function, kStartAtReceiver);
    5423     1577098 :        !iter.IsAtEnd(); iter.Advance()) {
    5424             :     Handle<JSReceiver> current =
    5425             :         PrototypeIterator::GetCurrent<JSReceiver>(iter);
    5426     1886142 :     if (!current->IsJSFunction()) break;
    5427      634233 :     Handle<JSFunction> func = Handle<JSFunction>::cast(current);
    5428             :     // The super constructor should be compiled for the number of expected
    5429             :     // properties to be available.
    5430     1268466 :     Handle<SharedFunctionInfo> shared(func->shared(), isolate);
    5431      634233 :     IsCompiledScope is_compiled_scope(shared->is_compiled_scope());
    5432      661108 :     if (is_compiled_scope.is_compiled() ||
    5433             :         Compiler::Compile(func, Compiler::CLEAR_EXCEPTION,
    5434       26875 :                           &is_compiled_scope)) {
    5435             :       DCHECK(shared->is_compiled());
    5436      634224 :       int count = shared->expected_nof_properties();
    5437             :       // Check that the estimate is sane.
    5438      634224 :       if (expected_nof_properties <= JSObject::kMaxInObjectProperties - count) {
    5439      634019 :         expected_nof_properties += count;
    5440             :       } else {
    5441         205 :         return JSObject::kMaxInObjectProperties;
    5442             :       }
    5443             :     } else {
    5444             :       // In case there was a compilation error for the constructor we will
    5445             :       // throw an error during instantiation.
    5446             :       break;
    5447             :     }
    5448             :   }
    5449             :   // Inobject slack tracking will reclaim redundant inobject space
    5450             :   // later, so we can afford to adjust the estimate generously,
    5451             :   // meaning we over-allocate by at least 8 slots in the beginning.
    5452      308856 :   if (expected_nof_properties > 0) {
    5453      226359 :     expected_nof_properties += 8;
    5454      226359 :     if (expected_nof_properties > JSObject::kMaxInObjectProperties) {
    5455             :       expected_nof_properties = JSObject::kMaxInObjectProperties;
    5456             :     }
    5457             :   }
    5458      308856 :   return expected_nof_properties;
    5459             : }
    5460             : 
    5461             : // static
    5462      309061 : void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type,
    5463             :                                              bool has_prototype_slot,
    5464             :                                              int requested_embedder_fields,
    5465             :                                              int requested_in_object_properties,
    5466             :                                              int* instance_size,
    5467             :                                              int* in_object_properties) {
    5468             :   DCHECK_LE(static_cast<unsigned>(requested_embedder_fields),
    5469             :             JSObject::kMaxEmbedderFields);
    5470      309061 :   int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot);
    5471      309061 :   if (requested_embedder_fields) {
    5472             :     // If there are embedder fields, then the embedder fields start offset must
    5473             :     // be properly aligned (embedder fields are located between object header
    5474             :     // and inobject fields).
    5475             :     header_size = RoundUp<kSystemPointerSize>(header_size);
    5476             :     requested_embedder_fields *= kEmbedderDataSlotSizeInTaggedSlots;
    5477             :   }
    5478             :   int max_nof_fields =
    5479      309061 :       (JSObject::kMaxInstanceSize - header_size) >> kTaggedSizeLog2;
    5480      309061 :   CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties);
    5481      309061 :   CHECK_LE(static_cast<unsigned>(requested_embedder_fields),
    5482             :            static_cast<unsigned>(max_nof_fields));
    5483             :   *in_object_properties = Min(requested_in_object_properties,
    5484      618122 :                               max_nof_fields - requested_embedder_fields);
    5485             :   *instance_size =
    5486      309061 :       header_size +
    5487      618122 :       ((requested_embedder_fields + *in_object_properties) << kTaggedSizeLog2);
    5488      309061 :   CHECK_EQ(*in_object_properties,
    5489             :            ((*instance_size - header_size) >> kTaggedSizeLog2) -
    5490             :                requested_embedder_fields);
    5491      309061 :   CHECK_LE(static_cast<unsigned>(*instance_size),
    5492             :            static_cast<unsigned>(JSObject::kMaxInstanceSize));
    5493      309061 : }
    5494             : 
    5495       52118 : void JSFunction::ClearTypeFeedbackInfo() {
    5496       52118 :   ResetIfBytecodeFlushed();
    5497       52118 :   if (has_feedback_vector()) {
    5498       52085 :     FeedbackVector vector = feedback_vector();
    5499             :     Isolate* isolate = GetIsolate();
    5500       52085 :     if (vector->ClearSlots(isolate)) {
    5501             :       IC::OnFeedbackChanged(isolate, vector, FeedbackSlot::Invalid(), *this,
    5502       27389 :                             "ClearTypeFeedbackInfo");
    5503             :     }
    5504             :   }
    5505       52118 : }
    5506             : 
    5507      823919 : void JSGlobalObject::InvalidatePropertyCell(Handle<JSGlobalObject> global,
    5508             :                                             Handle<Name> name) {
    5509             :   // Regardless of whether the property is there or not invalidate
    5510             :   // Load/StoreGlobalICs that load/store through global object's prototype.
    5511      823919 :   JSObject::InvalidatePrototypeValidityCell(*global);
    5512             : 
    5513             :   DCHECK(!global->HasFastProperties());
    5514     1647838 :   auto dictionary = handle(global->global_dictionary(), global->GetIsolate());
    5515      823919 :   int entry = dictionary->FindEntry(global->GetIsolate(), name);
    5516     1647838 :   if (entry == GlobalDictionary::kNotFound) return;
    5517          87 :   PropertyCell::InvalidateEntry(global->GetIsolate(), dictionary, entry);
    5518             : }
    5519             : 
    5520     8149955 : Handle<PropertyCell> JSGlobalObject::EnsureEmptyPropertyCell(
    5521             :     Handle<JSGlobalObject> global, Handle<Name> name,
    5522             :     PropertyCellType cell_type, int* entry_out) {
    5523             :   Isolate* isolate = global->GetIsolate();
    5524             :   DCHECK(!global->HasFastProperties());
    5525    16299912 :   Handle<GlobalDictionary> dictionary(global->global_dictionary(), isolate);
    5526     8149956 :   int entry = dictionary->FindEntry(isolate, name);
    5527             :   Handle<PropertyCell> cell;
    5528     8149958 :   if (entry != GlobalDictionary::kNotFound) {
    5529        3043 :     if (entry_out) *entry_out = entry;
    5530        6086 :     cell = handle(dictionary->CellAt(entry), isolate);
    5531        6086 :     PropertyCellType original_cell_type = cell->property_details().cell_type();
    5532             :     DCHECK(original_cell_type == PropertyCellType::kInvalidated ||
    5533             :            original_cell_type == PropertyCellType::kUninitialized);
    5534             :     DCHECK(cell->value()->IsTheHole(isolate));
    5535        3043 :     if (original_cell_type == PropertyCellType::kInvalidated) {
    5536         481 :       cell = PropertyCell::InvalidateEntry(isolate, dictionary, entry);
    5537             :     }
    5538             :     PropertyDetails details(kData, NONE, cell_type);
    5539        6086 :     cell->set_property_details(details);
    5540        3043 :     return cell;
    5541             :   }
    5542     8146915 :   cell = isolate->factory()->NewPropertyCell(name);
    5543             :   PropertyDetails details(kData, NONE, cell_type);
    5544             :   dictionary = GlobalDictionary::Add(isolate, dictionary, name, cell, details,
    5545     8146914 :                                      entry_out);
    5546             :   // {*entry_out} is initialized inside GlobalDictionary::Add().
    5547    16293826 :   global->SetProperties(*dictionary);
    5548     8146914 :   return cell;
    5549             : }
    5550             : 
    5551             : // static
    5552      148972 : MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
    5553             :                                 Handle<JSReceiver> new_target, double tv) {
    5554             :   Isolate* const isolate = constructor->GetIsolate();
    5555             :   Handle<JSObject> result;
    5556      297944 :   ASSIGN_RETURN_ON_EXCEPTION(
    5557             :       isolate, result,
    5558             :       JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
    5559             :       JSDate);
    5560      148972 :   if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
    5561      148477 :     tv = DoubleToInteger(tv) + 0.0;
    5562             :   } else {
    5563             :     tv = std::numeric_limits<double>::quiet_NaN();
    5564             :   }
    5565      148972 :   Handle<Object> value = isolate->factory()->NewNumber(tv);
    5566      446916 :   Handle<JSDate>::cast(result)->SetValue(*value, std::isnan(tv));
    5567      148972 :   return Handle<JSDate>::cast(result);
    5568             : }
    5569             : 
    5570             : // static
    5571      143859 : double JSDate::CurrentTimeValue(Isolate* isolate) {
    5572      143859 :   if (FLAG_log_internal_timer_events) LOG(isolate, CurrentTimeEvent());
    5573             : 
    5574             :   // According to ECMA-262, section 15.9.1, page 117, the precision of
    5575             :   // the number in a Date object representing a particular instant in
    5576             :   // time is milliseconds. Therefore, we floor the result of getting
    5577             :   // the OS time.
    5578      287718 :   return Floor(V8::GetCurrentPlatform()->CurrentClockTimeMillis());
    5579             : }
    5580             : 
    5581             : // static
    5582       11142 : Address JSDate::GetField(Address raw_object, Address smi_index) {
    5583             :   Object object(raw_object);
    5584             :   Smi index(smi_index);
    5585             :   return JSDate::cast(object)
    5586       33426 :       ->DoGetField(static_cast<FieldIndex>(index->value()))
    5587       33426 :       ->ptr();
    5588             : }
    5589             : 
    5590       11142 : Object JSDate::DoGetField(FieldIndex index) {
    5591             :   DCHECK_NE(index, kDateValue);
    5592             : 
    5593       11142 :   DateCache* date_cache = GetIsolate()->date_cache();
    5594             : 
    5595       11142 :   if (index < kFirstUncachedField) {
    5596        5427 :     Object stamp = cache_stamp();
    5597       10854 :     if (stamp != date_cache->stamp() && stamp->IsSmi()) {
    5598             :       // Since the stamp is not NaN, the value is also not NaN.
    5599             :       int64_t local_time_ms =
    5600         756 :           date_cache->ToLocal(static_cast<int64_t>(value()->Number()));
    5601         378 :       SetCachedFields(local_time_ms, date_cache);
    5602             :     }
    5603        5427 :     switch (index) {
    5604             :       case kYear:
    5605             :         return year();
    5606             :       case kMonth:
    5607             :         return month();
    5608             :       case kDay:
    5609             :         return day();
    5610             :       case kWeekday:
    5611             :         return weekday();
    5612             :       case kHour:
    5613             :         return hour();
    5614             :       case kMinute:
    5615             :         return min();
    5616             :       case kSecond:
    5617             :         return sec();
    5618             :       default:
    5619           0 :         UNREACHABLE();
    5620             :     }
    5621             :   }
    5622             : 
    5623        5715 :   if (index >= kFirstUTCField) {
    5624        5553 :     return GetUTCField(index, value()->Number(), date_cache);
    5625             :   }
    5626             : 
    5627         162 :   double time = value()->Number();
    5628         216 :   if (std::isnan(time)) return GetReadOnlyRoots().nan_value();
    5629             : 
    5630         108 :   int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time));
    5631             :   int days = DateCache::DaysFromTime(local_time_ms);
    5632             : 
    5633         108 :   if (index == kDays) return Smi::FromInt(days);
    5634             : 
    5635             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
    5636         216 :   if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000);
    5637             :   DCHECK_EQ(index, kTimeInDay);
    5638           0 :   return Smi::FromInt(time_in_day_ms);
    5639             : }
    5640             : 
    5641        5553 : Object JSDate::GetUTCField(FieldIndex index, double value,
    5642             :                            DateCache* date_cache) {
    5643             :   DCHECK_GE(index, kFirstUTCField);
    5644             : 
    5645       10656 :   if (std::isnan(value)) return GetReadOnlyRoots().nan_value();
    5646             : 
    5647         450 :   int64_t time_ms = static_cast<int64_t>(value);
    5648             : 
    5649         450 :   if (index == kTimezoneOffset) {
    5650         126 :     GetIsolate()->CountUsage(v8::Isolate::kDateGetTimezoneOffset);
    5651         126 :     return Smi::FromInt(date_cache->TimezoneOffset(time_ms));
    5652             :   }
    5653             : 
    5654             :   int days = DateCache::DaysFromTime(time_ms);
    5655             : 
    5656         333 :   if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days));
    5657             : 
    5658         315 :   if (index <= kDayUTC) {
    5659             :     int year, month, day;
    5660         117 :     date_cache->YearMonthDayFromDays(days, &year, &month, &day);
    5661         153 :     if (index == kYearUTC) return Smi::FromInt(year);
    5662         117 :     if (index == kMonthUTC) return Smi::FromInt(month);
    5663             :     DCHECK_EQ(index, kDayUTC);
    5664          90 :     return Smi::FromInt(day);
    5665             :   }
    5666             : 
    5667             :   int time_in_day_ms = DateCache::TimeInDay(time_ms, days);
    5668         198 :   switch (index) {
    5669             :     case kHourUTC:
    5670         180 :       return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000));
    5671             :     case kMinuteUTC:
    5672          90 :       return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60);
    5673             :     case kSecondUTC:
    5674          72 :       return Smi::FromInt((time_in_day_ms / 1000) % 60);
    5675             :     case kMillisecondUTC:
    5676          54 :       return Smi::FromInt(time_in_day_ms % 1000);
    5677             :     case kDaysUTC:
    5678           0 :       return Smi::FromInt(days);
    5679             :     case kTimeInDayUTC:
    5680           0 :       return Smi::FromInt(time_in_day_ms);
    5681             :     default:
    5682           0 :       UNREACHABLE();
    5683             :   }
    5684             : 
    5685             :   UNREACHABLE();
    5686             : }
    5687             : 
    5688             : // static
    5689       11151 : Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
    5690             :   Isolate* const isolate = date->GetIsolate();
    5691       11151 :   Handle<Object> value = isolate->factory()->NewNumber(v);
    5692             :   bool value_is_nan = std::isnan(v);
    5693       22302 :   date->SetValue(*value, value_is_nan);
    5694       11151 :   return value;
    5695             : }
    5696             : 
    5697      160123 : void JSDate::SetValue(Object value, bool is_value_nan) {
    5698      160123 :   set_value(value);
    5699      160123 :   if (is_value_nan) {
    5700       22320 :     HeapNumber nan = GetReadOnlyRoots().nan_value();
    5701       11160 :     set_cache_stamp(nan, SKIP_WRITE_BARRIER);
    5702       11160 :     set_year(nan, SKIP_WRITE_BARRIER);
    5703       11160 :     set_month(nan, SKIP_WRITE_BARRIER);
    5704       11160 :     set_day(nan, SKIP_WRITE_BARRIER);
    5705       11160 :     set_hour(nan, SKIP_WRITE_BARRIER);
    5706       11160 :     set_min(nan, SKIP_WRITE_BARRIER);
    5707       11160 :     set_sec(nan, SKIP_WRITE_BARRIER);
    5708       11160 :     set_weekday(nan, SKIP_WRITE_BARRIER);
    5709             :   } else {
    5710      148963 :     set_cache_stamp(Smi::FromInt(DateCache::kInvalidStamp), SKIP_WRITE_BARRIER);
    5711             :   }
    5712      160123 : }
    5713             : 
    5714         378 : void JSDate::SetCachedFields(int64_t local_time_ms, DateCache* date_cache) {
    5715             :   int days = DateCache::DaysFromTime(local_time_ms);
    5716             :   int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days);
    5717             :   int year, month, day;
    5718         378 :   date_cache->YearMonthDayFromDays(days, &year, &month, &day);
    5719             :   int weekday = date_cache->Weekday(days);
    5720         378 :   int hour = time_in_day_ms / (60 * 60 * 1000);
    5721         378 :   int min = (time_in_day_ms / (60 * 1000)) % 60;
    5722         378 :   int sec = (time_in_day_ms / 1000) % 60;
    5723         378 :   set_cache_stamp(date_cache->stamp());
    5724         756 :   set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
    5725         756 :   set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
    5726         756 :   set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
    5727         378 :   set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
    5728         378 :   set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
    5729         378 :   set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
    5730         378 :   set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
    5731         378 : }
    5732             : 
    5733        9108 : int JSMessageObject::GetLineNumber() const {
    5734        9108 :   if (start_position() == -1) return Message::kNoLineNumberInfo;
    5735             : 
    5736        8988 :   Handle<Script> the_script(script(), GetIsolate());
    5737             : 
    5738             :   Script::PositionInfo info;
    5739             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
    5740        8988 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
    5741        8988 :                                offset_flag)) {
    5742             :     return Message::kNoLineNumberInfo;
    5743             :   }
    5744             : 
    5745        8988 :   return info.line + 1;
    5746             : }
    5747             : 
    5748       15099 : int JSMessageObject::GetColumnNumber() const {
    5749       15099 :   if (start_position() == -1) return -1;
    5750             : 
    5751       14924 :   Handle<Script> the_script(script(), GetIsolate());
    5752             : 
    5753             :   Script::PositionInfo info;
    5754             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
    5755       14924 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
    5756       14924 :                                offset_flag)) {
    5757             :     return -1;
    5758             :   }
    5759             : 
    5760       14924 :   return info.column;  // Note: No '+1' in contrast to GetLineNumber.
    5761             : }
    5762             : 
    5763        6291 : Handle<String> JSMessageObject::GetSourceLine() const {
    5764             :   Isolate* isolate = GetIsolate();
    5765        6291 :   Handle<Script> the_script(script(), isolate);
    5766             : 
    5767        6291 :   if (the_script->type() == Script::TYPE_WASM) {
    5768             :     return isolate->factory()->empty_string();
    5769             :   }
    5770             : 
    5771             :   Script::PositionInfo info;
    5772             :   const Script::OffsetFlag offset_flag = Script::WITH_OFFSET;
    5773        6291 :   if (!Script::GetPositionInfo(the_script, start_position(), &info,
    5774        6291 :                                offset_flag)) {
    5775             :     return isolate->factory()->empty_string();
    5776             :   }
    5777             : 
    5778        6291 :   Handle<String> src = handle(String::cast(the_script->source()), isolate);
    5779        6291 :   return isolate->factory()->NewSubString(src, info.line_start, info.line_end);
    5780             : }
    5781             : 
    5782             : }  // namespace internal
    5783      178779 : }  // namespace v8

Generated by: LCOV version 1.10