LCOV - code coverage report
Current view: top level - src/objects - js-objects.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1817 1994 91.1 %
Date: 2019-03-21 Functions: 185 192 96.4 %

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

Generated by: LCOV version 1.10