LCOV - code coverage report
Current view: top level - src/ic - ic.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 992 1119 88.7 %
Date: 2019-03-21 Functions: 79 105 75.2 %

          Line data    Source code
       1             : // Copyright 2012 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/ic/ic.h"
       6             : 
       7             : #include "src/accessors.h"
       8             : #include "src/api-arguments-inl.h"
       9             : #include "src/api.h"
      10             : #include "src/arguments-inl.h"
      11             : #include "src/ast/ast.h"
      12             : #include "src/base/bits.h"
      13             : #include "src/code-factory.h"
      14             : #include "src/conversions.h"
      15             : #include "src/execution.h"
      16             : #include "src/field-type.h"
      17             : #include "src/frames-inl.h"
      18             : #include "src/handles-inl.h"
      19             : #include "src/ic/call-optimization.h"
      20             : #include "src/ic/handler-configuration-inl.h"
      21             : #include "src/ic/ic-inl.h"
      22             : #include "src/ic/ic-stats.h"
      23             : #include "src/ic/stub-cache.h"
      24             : #include "src/isolate-inl.h"
      25             : #include "src/objects/api-callbacks.h"
      26             : #include "src/objects/data-handler-inl.h"
      27             : #include "src/objects/hash-table-inl.h"
      28             : #include "src/objects/heap-number-inl.h"
      29             : #include "src/objects/js-array-inl.h"
      30             : #include "src/objects/module-inl.h"
      31             : #include "src/objects/struct-inl.h"
      32             : #include "src/prototype.h"
      33             : #include "src/runtime-profiler.h"
      34             : #include "src/runtime/runtime-utils.h"
      35             : #include "src/runtime/runtime.h"
      36             : #include "src/tracing/trace-event.h"
      37             : #include "src/tracing/tracing-category-observer.h"
      38             : 
      39             : namespace v8 {
      40             : namespace internal {
      41             : 
      42           0 : char IC::TransitionMarkFromState(IC::State state) {
      43           0 :   switch (state) {
      44             :     case NO_FEEDBACK:
      45           0 :       UNREACHABLE();
      46             :     case UNINITIALIZED:
      47             :       return '0';
      48             :     case PREMONOMORPHIC:
      49           0 :       return '.';
      50             :     case MONOMORPHIC:
      51           0 :       return '1';
      52             :     case RECOMPUTE_HANDLER:
      53           0 :       return '^';
      54             :     case POLYMORPHIC:
      55           0 :       return 'P';
      56             :     case MEGAMORPHIC:
      57           0 :       return 'N';
      58             :     case GENERIC:
      59           0 :       return 'G';
      60             :   }
      61           0 :   UNREACHABLE();
      62             : }
      63             : 
      64             : namespace {
      65             : 
      66             : const char* GetModifier(KeyedAccessLoadMode mode) {
      67           0 :   if (mode == LOAD_IGNORE_OUT_OF_BOUNDS) return ".IGNORE_OOB";
      68             :   return "";
      69             : }
      70             : 
      71             : const char* GetModifier(KeyedAccessStoreMode mode) {
      72           0 :   switch (mode) {
      73             :     case STORE_NO_TRANSITION_HANDLE_COW:
      74             :       return ".COW";
      75             :     case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
      76             :       return ".STORE+COW";
      77             :     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
      78             :       return ".IGNORE_OOB";
      79             :     default:
      80             :       break;
      81             :   }
      82             :   DCHECK(!IsCOWHandlingStoreMode(mode));
      83           0 :   return IsGrowStoreMode(mode) ? ".GROW" : "";
      84             : }
      85             : 
      86             : }  // namespace
      87             : 
      88     7331046 : void IC::TraceIC(const char* type, Handle<Object> name) {
      89     7331046 :   if (V8_LIKELY(!TracingFlags::is_ic_stats_enabled())) return;
      90           0 :   if (AddressIsDeoptimizedCode()) return;
      91           0 :   State new_state = nexus()->ic_state();
      92           0 :   TraceIC(type, name, state(), new_state);
      93             : }
      94             : 
      95           0 : void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
      96             :                  State new_state) {
      97           0 :   if (V8_LIKELY(!TracingFlags::is_ic_stats_enabled())) return;
      98             : 
      99             :   Map map;
     100           0 :   if (!receiver_map().is_null()) {
     101             :     map = *receiver_map();
     102             :   }
     103             : 
     104             :   const char* modifier = "";
     105           0 :   if (IsKeyedLoadIC()) {
     106           0 :     KeyedAccessLoadMode mode = nexus()->GetKeyedAccessLoadMode();
     107             :     modifier = GetModifier(mode);
     108           0 :   } else if (IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind())) {
     109           0 :     KeyedAccessStoreMode mode = nexus()->GetKeyedAccessStoreMode();
     110             :     modifier = GetModifier(mode);
     111             :   }
     112             : 
     113           0 :   bool keyed_prefix = is_keyed() && !IsStoreInArrayLiteralICKind(kind());
     114             : 
     115           0 :   if (!(TracingFlags::ic_stats.load(std::memory_order_relaxed) &
     116             :         v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING)) {
     117           0 :     LOG(isolate(), ICEvent(type, keyed_prefix, map, *name,
     118             :                            TransitionMarkFromState(old_state),
     119             :                            TransitionMarkFromState(new_state), modifier,
     120             :                            slow_stub_reason_));
     121             :     return;
     122             :   }
     123             : 
     124           0 :   ICStats::instance()->Begin();
     125             :   ICInfo& ic_info = ICStats::instance()->Current();
     126           0 :   ic_info.type = keyed_prefix ? "Keyed" : "";
     127             :   ic_info.type += type;
     128             : 
     129             :   Object maybe_function =
     130           0 :       Object(Memory<Address>(fp_ + JavaScriptFrameConstants::kFunctionOffset));
     131             :   DCHECK(maybe_function->IsJSFunction());
     132           0 :   JSFunction function = JSFunction::cast(maybe_function);
     133             :   int code_offset = 0;
     134           0 :   if (function->IsInterpreted()) {
     135           0 :     code_offset = InterpretedFrame::GetBytecodeOffset(fp());
     136             :   } else {
     137           0 :     code_offset = static_cast<int>(pc() - function->code()->InstructionStart());
     138             :   }
     139           0 :   JavaScriptFrame::CollectFunctionAndOffsetForICStats(
     140           0 :       function, function->abstract_code(), code_offset);
     141             : 
     142             :   // Reserve enough space for IC transition state, the longest length is 17.
     143           0 :   ic_info.state.reserve(17);
     144             :   ic_info.state = "(";
     145           0 :   ic_info.state += TransitionMarkFromState(old_state);
     146             :   ic_info.state += "->";
     147           0 :   ic_info.state += TransitionMarkFromState(new_state);
     148             :   ic_info.state += modifier;
     149             :   ic_info.state += ")";
     150           0 :   ic_info.map = reinterpret_cast<void*>(map.ptr());
     151           0 :   if (!map.is_null()) {
     152           0 :     ic_info.is_dictionary_map = map->is_dictionary_map();
     153           0 :     ic_info.number_of_own_descriptors = map->NumberOfOwnDescriptors();
     154           0 :     ic_info.instance_type = std::to_string(map->instance_type());
     155             :   }
     156             :   // TODO(lpy) Add name as key field in ICStats.
     157           0 :   ICStats::instance()->End();
     158             : }
     159             : 
     160     7600431 : IC::IC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot,
     161             :        FeedbackSlotKind kind)
     162             :     : isolate_(isolate),
     163             :       vector_set_(false),
     164             :       kind_(kind),
     165             :       target_maps_set_(false),
     166             :       slow_stub_reason_(nullptr),
     167    15200862 :       nexus_(vector, slot) {
     168             :   // To improve the performance of the (much used) IC code, we unfold a few
     169             :   // levels of the stack frame iteration code. This yields a ~35% speedup when
     170             :   // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
     171             :   const Address entry = Isolate::c_entry_fp(isolate->thread_local_top());
     172             :   Address* constant_pool = nullptr;
     173             :   if (FLAG_enable_embedded_constant_pool) {
     174             :     constant_pool = reinterpret_cast<Address*>(
     175             :         entry + ExitFrameConstants::kConstantPoolOffset);
     176             :   }
     177             :   Address* pc_address =
     178     7600434 :       reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
     179     7600434 :   Address fp = Memory<Address>(entry + ExitFrameConstants::kCallerFPOffset);
     180             : #ifdef DEBUG
     181             :   StackFrameIterator it(isolate);
     182             :   for (int i = 0; i < 1; i++) it.Advance();
     183             :   StackFrame* frame = it.frame();
     184             :   DCHECK(fp == frame->fp() && pc_address == frame->pc_address());
     185             : #endif
     186             :   // For interpreted functions, some bytecode handlers construct a
     187             :   // frame. We have to skip the constructed frame to find the interpreted
     188             :   // function's frame. Check if the there is an additional frame, and if there
     189             :   // is skip this frame. However, the pc should not be updated. The call to
     190             :   // ICs happen from bytecode handlers.
     191             :   intptr_t frame_marker =
     192    15200868 :       Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
     193     7600434 :   if (frame_marker == StackFrame::TypeToMarker(StackFrame::STUB)) {
     194     6604852 :     fp = Memory<Address>(fp + TypedFrameConstants::kCallerFPOffset);
     195             :   }
     196     7600434 :   fp_ = fp;
     197             :   if (FLAG_enable_embedded_constant_pool) {
     198             :     constant_pool_address_ = constant_pool;
     199             :   }
     200     7600434 :   pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
     201             :   DCHECK_IMPLIES(!vector.is_null(), kind_ == nexus_.kind());
     202     7600434 :   state_ = (vector.is_null()) ? NO_FEEDBACK : nexus_.ic_state();
     203     7600418 :   old_state_ = state_;
     204     7600418 : }
     205             : 
     206     2943601 : JSFunction IC::GetHostFunction() const {
     207             :   // Compute the JavaScript frame for the frame pointer of this IC
     208             :   // structure. We need this to be able to find the function
     209             :   // corresponding to the frame.
     210     2943601 :   StackFrameIterator it(isolate());
     211     8515119 :   while (it.frame()->fp() != this->fp()) it.Advance();
     212             :   JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
     213             :   // Find the function on the stack and both the active code for the
     214             :   // function and the original code.
     215     5887305 :   return frame->function();
     216             : }
     217             : 
     218     3636735 : static void LookupForRead(LookupIterator* it, bool is_has_property) {
     219     3685725 :   for (; it->IsFound(); it->Next()) {
     220     3410593 :     switch (it->state()) {
     221             :       case LookupIterator::NOT_FOUND:
     222             :       case LookupIterator::TRANSITION:
     223           0 :         UNREACHABLE();
     224             :       case LookupIterator::JSPROXY:
     225             :         return;
     226             :       case LookupIterator::INTERCEPTOR: {
     227             :         // If there is a getter, return; otherwise loop to perform the lookup.
     228             :         Handle<JSObject> holder = it->GetHolder<JSObject>();
     229        2640 :         if (!holder->GetNamedInterceptor()->getter()->IsUndefined(
     230             :                 it->isolate())) {
     231             :           return;
     232             :         }
     233         267 :         if (is_has_property &&
     234         159 :             !holder->GetNamedInterceptor()->query()->IsUndefined(
     235             :                 it->isolate())) {
     236             :           return;
     237             :         }
     238             :         break;
     239             :       }
     240             :       case LookupIterator::ACCESS_CHECK:
     241             :         // ICs know how to perform access checks on global proxies.
     242       24557 :         if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && it->HasAccess()) {
     243             :           break;
     244             :         }
     245             :         return;
     246             :       case LookupIterator::ACCESSOR:
     247             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     248             :       case LookupIterator::DATA:
     249             :         return;
     250             :     }
     251             :   }
     252             : }
     253             : 
     254      411819 : bool IC::ShouldRecomputeHandler(Handle<String> name) {
     255      411819 :   if (!RecomputeHandlerForName(name)) return false;
     256             : 
     257             :   // This is a contextual access, always just update the handler and stay
     258             :   // monomorphic.
     259      403683 :   if (IsGlobalIC()) return true;
     260             : 
     261      374972 :   maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
     262             : 
     263             :   // The current map wasn't handled yet. There's no reason to stay monomorphic,
     264             :   // *unless* we're moving from a deprecated map to its replacement, or
     265             :   // to a more general elements kind.
     266             :   // TODO(verwaest): Check if the current map is actually what the old map
     267             :   // would transition to.
     268      374972 :   if (maybe_handler_.is_null()) {
     269      362390 :     if (!receiver_map()->IsJSObjectMap()) return false;
     270      353586 :     Map first_map = FirstTargetMap();
     271      353587 :     if (first_map.is_null()) return false;
     272             :     Handle<Map> old_map(first_map, isolate());
     273      219362 :     if (old_map->is_deprecated()) return true;
     274      431066 :     return IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
     275      215533 :                                                receiver_map()->elements_kind());
     276             :   }
     277             : 
     278             :   return true;
     279             : }
     280             : 
     281      411819 : bool IC::RecomputeHandlerForName(Handle<Object> name) {
     282      411819 :   if (is_keyed()) {
     283             :     // Determine whether the failure is due to a name failure.
     284       18484 :     if (!name->IsName()) return false;
     285       10347 :     Name stub_name = nexus()->GetName();
     286       10347 :     if (*name != stub_name) return false;
     287             :   }
     288             : 
     289             :   return true;
     290             : }
     291             : 
     292     7417433 : void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
     293     7417433 :   if (state() == NO_FEEDBACK) return;
     294     7417433 :   update_receiver_map(receiver);
     295     7417432 :   if (!name->IsString()) return;
     296     7064916 :   if (state() != MONOMORPHIC && state() != POLYMORPHIC) return;
     297      411936 :   if (receiver->IsNullOrUndefined(isolate())) return;
     298             : 
     299             :   // Remove the target from the code cache if it became invalid
     300             :   // because of changes in the prototype chain to avoid hitting it
     301             :   // again.
     302      411820 :   if (ShouldRecomputeHandler(Handle<String>::cast(name))) {
     303             :     MarkRecomputeHandler(name);
     304             :   }
     305             : }
     306             : 
     307        1423 : MaybeHandle<Object> IC::TypeError(MessageTemplate index, Handle<Object> object,
     308             :                                   Handle<Object> key) {
     309             :   HandleScope scope(isolate());
     310        4269 :   THROW_NEW_ERROR(isolate(), NewTypeError(index, key, object), Object);
     311             : }
     312             : 
     313      172515 : MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) {
     314             :   HandleScope scope(isolate());
     315      517545 :   THROW_NEW_ERROR(
     316             :       isolate(), NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     317             : }
     318             : 
     319             : // static
     320     2943647 : void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus,
     321             :                            JSFunction host_function, const char* reason) {
     322     2943647 :   FeedbackVector vector = nexus->vector();
     323     2943647 :   FeedbackSlot slot = nexus->slot();
     324     2943647 :   OnFeedbackChanged(isolate, vector, slot, host_function, reason);
     325     2943652 : }
     326             : 
     327             : // static
     328     2971285 : void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector vector,
     329             :                            FeedbackSlot slot, JSFunction host_function,
     330             :                            const char* reason) {
     331     2971285 :   if (FLAG_trace_opt_verbose) {
     332             :     // TODO(leszeks): The host function is only needed for this print, we could
     333             :     // remove it as a parameter if we're of with removing this trace (or only
     334             :     // tracing the feedback vector, not the function name).
     335           0 :     if (vector->profiler_ticks() != 0) {
     336           0 :       PrintF("[resetting ticks for ");
     337           0 :       host_function->ShortPrint();
     338             :       PrintF(" due from %d due to IC change: %s]\n", vector->profiler_ticks(),
     339           0 :              reason);
     340             :     }
     341             :   }
     342             :   vector->set_profiler_ticks(0);
     343             : 
     344             : #ifdef V8_TRACE_FEEDBACK_UPDATES
     345             :   if (FLAG_trace_feedback_updates) {
     346             :     int slot_count = vector->metadata()->slot_count();
     347             : 
     348             :     StdoutStream os;
     349             :     if (slot.IsInvalid()) {
     350             :       os << "[Feedback slots in ";
     351             :     } else {
     352             :       os << "[Feedback slot " << slot.ToInt() << "/" << slot_count << " in ";
     353             :     }
     354             :     vector->shared_function_info()->ShortPrint(os);
     355             :     if (slot.IsInvalid()) {
     356             :       os << " updated - ";
     357             :     } else {
     358             :       os << " updated to ";
     359             :       vector->FeedbackSlotPrint(os, slot);
     360             :       os << " - ";
     361             :     }
     362             :     os << reason << "]" << std::endl;
     363             :   }
     364             : #endif
     365             : 
     366             :   isolate->runtime_profiler()->NotifyICChanged();
     367             :   // TODO(2029): When an optimized function is patched, it would
     368             :   // be nice to propagate the corresponding type information to its
     369             :   // unoptimized version for the benefit of later inlining.
     370     2971285 : }
     371             : 
     372     7627410 : static bool MigrateDeprecated(Handle<Object> object) {
     373     7627410 :   if (!object->IsJSObject()) return false;
     374             :   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     375     7520254 :   if (!receiver->map()->is_deprecated()) return false;
     376        1409 :   JSObject::MigrateInstance(Handle<JSObject>::cast(object));
     377        1409 :   return true;
     378             : }
     379             : 
     380       47560 : bool IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
     381             :   DCHECK_EQ(MEGAMORPHIC, new_state);
     382             :   DCHECK_IMPLIES(!is_keyed(), key->IsName());
     383             :   // Even though we don't change the feedback data, we still want to reset the
     384             :   // profiler ticks. Real-world observations suggest that optimizing these
     385             :   // functions doesn't improve performance.
     386             :   bool changed =
     387       95120 :       nexus()->ConfigureMegamorphic(key->IsName() ? PROPERTY : ELEMENT);
     388       47559 :   vector_set_ = true;
     389       47559 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Megamorphic");
     390       47560 :   return changed;
     391             : }
     392             : 
     393      686667 : void IC::ConfigureVectorState(Handle<Map> map) {
     394      686667 :   nexus()->ConfigurePremonomorphic(map);
     395      686667 :   vector_set_ = true;
     396      686667 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Premonomorphic");
     397      686672 : }
     398             : 
     399           0 : void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
     400             :                               Handle<Object> handler) {
     401      342202 :   ConfigureVectorState(name, map, MaybeObjectHandle(handler));
     402           0 : }
     403             : 
     404     1983061 : void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
     405             :                               const MaybeObjectHandle& handler) {
     406     1983061 :   if (IsGlobalIC()) {
     407       44655 :     nexus()->ConfigureHandlerMode(handler);
     408             :   } else {
     409             :     // Non-keyed ICs don't track the name explicitly.
     410     1938406 :     if (!is_keyed()) name = Handle<Name>::null();
     411     1938406 :     nexus()->ConfigureMonomorphic(name, map, handler);
     412             :   }
     413             : 
     414     1983069 :   vector_set_ = true;
     415     1983069 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(),
     416     1983100 :                     IsLoadGlobalIC() ? "LoadGlobal" : "Monomorphic");
     417     1983100 : }
     418             : 
     419      226319 : void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
     420             :                               MaybeObjectHandles* handlers) {
     421             :   DCHECK(!IsGlobalIC());
     422             :   // Non-keyed ICs don't track the name explicitly.
     423      226319 :   if (!is_keyed()) name = Handle<Name>::null();
     424      226319 :   nexus()->ConfigurePolymorphic(name, maps, handlers);
     425             : 
     426      226321 :   vector_set_ = true;
     427      226321 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Polymorphic");
     428      226321 : }
     429             : 
     430     3637797 : MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
     431     3637797 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
     432             : 
     433             :   // If the object is undefined or null it's illegal to try to get any
     434             :   // of its properties; throw a TypeError in that case.
     435     7279043 :   if (IsAnyHas() ? !object->IsJSReceiver()
     436             :                  : object->IsNullOrUndefined(isolate())) {
     437        1061 :     if (use_ic && state() != PREMONOMORPHIC) {
     438             :       // Ensure the IC state progresses.
     439         998 :       TRACE_HANDLER_STATS(isolate(), LoadIC_NonReceiver);
     440         998 :       update_receiver_map(object);
     441         998 :       PatchCache(name, slow_stub());
     442         998 :       TraceIC("LoadIC", name);
     443             :     }
     444             : 
     445        1061 :     if (*name == ReadOnlyRoots(isolate()).iterator_symbol()) {
     446         177 :       return Runtime::ThrowIteratorError(isolate(), object);
     447             :     }
     448             :     return TypeError(IsAnyHas() ? MessageTemplate::kInvalidInOperatorUse
     449             :                                 : MessageTemplate::kNonObjectPropertyLoad,
     450         884 :                      object, name);
     451             :   }
     452             : 
     453     3636736 :   if (MigrateDeprecated(object)) use_ic = false;
     454             : 
     455     3636743 :   if (state() != UNINITIALIZED) {
     456     1320462 :     JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate());
     457     1320466 :     update_receiver_map(object);
     458             :   }
     459             : 
     460     3636743 :   LookupIterator it(isolate(), object, name);
     461             : 
     462             :   // Named lookup in the object.
     463     3636738 :   LookupForRead(&it, IsAnyHas());
     464             : 
     465     3636737 :   if (name->IsPrivate()) {
     466       15561 :     if (name->IsPrivateName() && !it.IsFound()) {
     467             :       Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
     468             :                                  isolate());
     469             :       return TypeError(MessageTemplate::kInvalidPrivateFieldRead, object,
     470         307 :                        name_string);
     471             :     }
     472             : 
     473             :     // IC handling of private symbols/fields lookup on JSProxy is not
     474             :     // supported.
     475       15254 :     if (object->IsJSProxy()) {
     476             :       use_ic = false;
     477             :     }
     478             :   }
     479             : 
     480     3636423 :   if (it.IsFound() || !ShouldThrowReferenceError()) {
     481             :     // Update inline cache and stub cache.
     482     3464549 :     if (use_ic) UpdateCaches(&it);
     483             : 
     484     3464555 :     if (IsAnyHas()) {
     485             :       // Named lookup in the object.
     486        3390 :       Maybe<bool> maybe = JSReceiver::HasProperty(&it);
     487        3390 :       if (maybe.IsNothing()) return MaybeHandle<Object>();
     488             :       return maybe.FromJust() ? ReadOnlyRoots(isolate()).true_value_handle()
     489        6308 :                               : ReadOnlyRoots(isolate()).false_value_handle();
     490             :     }
     491             : 
     492             :     // Get the property.
     493             :     Handle<Object> result;
     494             : 
     495     6922319 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
     496             :                                Object);
     497     3460057 :     if (it.IsFound()) {
     498     3382542 :       return result;
     499       77515 :     } else if (!ShouldThrowReferenceError()) {
     500       77402 :       LOG(isolate(), SuspectReadEvent(*name, *object));
     501       77402 :       return result;
     502             :     }
     503             :   }
     504      171987 :   return ReferenceError(name);
     505             : }
     506             : 
     507     2264992 : MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) {
     508     2264992 :   Handle<JSGlobalObject> global = isolate()->global_object();
     509             : 
     510     2264987 :   if (name->IsString()) {
     511             :     // Look up in script context table.
     512             :     Handle<String> str_name = Handle<String>::cast(name);
     513             :     Handle<ScriptContextTable> script_contexts(
     514     4529974 :         global->native_context()->script_context_table(), isolate());
     515             : 
     516             :     ScriptContextTable::LookupResult lookup_result;
     517     2264986 :     if (ScriptContextTable::Lookup(isolate(), *script_contexts, *str_name,
     518             :                                    &lookup_result)) {
     519             :       Handle<Context> script_context = ScriptContextTable::GetContext(
     520       57166 :           isolate(), script_contexts, lookup_result.context_index);
     521             : 
     522             :       Handle<Object> result(script_context->get(lookup_result.slot_index),
     523       57166 :                             isolate());
     524             : 
     525       57166 :       if (result->IsTheHole(isolate())) {
     526             :         // Do not install stubs and stay pre-monomorphic for
     527             :         // uninitialized accesses.
     528         515 :         return ReferenceError(name);
     529             :       }
     530             : 
     531       56651 :       bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
     532       56651 :       if (use_ic) {
     533      113302 :         if (nexus()->ConfigureLexicalVarMode(
     534             :                 lookup_result.context_index, lookup_result.slot_index,
     535       56651 :                 lookup_result.mode == VariableMode::kConst)) {
     536       56651 :           TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_LoadScriptContextField);
     537             :         } else {
     538             :           // Given combination of indices can't be encoded, so use slow stub.
     539           0 :           TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_SlowStub);
     540           0 :           PatchCache(name, slow_stub());
     541             :         }
     542       56651 :         TraceIC("LoadGlobalIC", name);
     543             :       }
     544       56651 :       return result;
     545             :     }
     546             :   }
     547     2207822 :   return LoadIC::Load(global, name);
     548             : }
     549             : 
     550       21875 : static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
     551             :                                        Handle<Map> new_receiver_map) {
     552             :   DCHECK(!new_receiver_map.is_null());
     553       56743 :   for (Handle<Map> map : *receiver_maps) {
     554       77974 :     if (!map.is_null() && map.is_identical_to(new_receiver_map)) {
     555             :       return false;
     556             :     }
     557             :   }
     558       17756 :   receiver_maps->push_back(new_receiver_map);
     559       17756 :   return true;
     560             : }
     561             : 
     562      387129 : bool IC::UpdatePolymorphicIC(Handle<Name> name,
     563             :                              const MaybeObjectHandle& handler) {
     564             :   DCHECK(IsHandler(*handler));
     565      387129 :   if (is_keyed() && state() != RECOMPUTE_HANDLER) {
     566       26832 :     if (nexus()->GetName() != *name) return false;
     567             :   }
     568      378609 :   Handle<Map> map = receiver_map();
     569             :   MapHandles maps;
     570             :   MaybeObjectHandles handlers;
     571             : 
     572      378609 :   TargetMaps(&maps);
     573      378612 :   int number_of_maps = static_cast<int>(maps.size());
     574             :   int deprecated_maps = 0;
     575             :   int handler_to_overwrite = -1;
     576      378612 :   if (!nexus()->FindHandlers(&handlers, number_of_maps)) return false;
     577             : 
     578     1171221 :   for (int i = 0; i < number_of_maps; i++) {
     579      793212 :     Handle<Map> current_map = maps.at(i);
     580      396606 :     if (current_map->is_deprecated()) {
     581             :       // Filter out deprecated maps to ensure their instances get migrated.
     582        5368 :       ++deprecated_maps;
     583      391238 :     } else if (map.is_identical_to(current_map)) {
     584             :       // If both map and handler stayed the same (and the name is also the
     585             :       // same as checked above, for keyed accesses), we're not progressing
     586             :       // in the lattice and need to go MEGAMORPHIC instead. There's one
     587             :       // exception to this rule, which is when we're in RECOMPUTE_HANDLER
     588             :       // state, there we allow to migrate to a new handler.
     589       12002 :       if (handler.is_identical_to(handlers[i]) &&
     590             :           state() != RECOMPUTE_HANDLER) {
     591             :         return false;
     592             :       }
     593             :       // If the receiver type is already in the polymorphic IC, this indicates
     594             :       // there was a prototoype chain failure. In that case, just overwrite the
     595             :       // handler.
     596             :       handler_to_overwrite = i;
     597      757669 :     } else if (handler_to_overwrite == -1 &&
     598      378431 :                IsTransitionOfMonomorphicTarget(*current_map, *map)) {
     599             :       handler_to_overwrite = i;
     600             :     }
     601             :   }
     602             : 
     603             :   int number_of_valid_maps =
     604      378043 :       number_of_maps - deprecated_maps - (handler_to_overwrite != -1);
     605             : 
     606      378043 :   if (number_of_valid_maps >= FLAG_max_polymorphic_map_count) return false;
     607      364785 :   if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
     608             :     return false;
     609             :   }
     610             : 
     611             :   number_of_valid_maps++;
     612      364783 :   if (number_of_valid_maps == 1) {
     613      153480 :     ConfigureVectorState(name, receiver_map(), handler);
     614             :   } else {
     615      219391 :     if (is_keyed() && nexus()->GetName() != *name) return false;
     616      211303 :     if (handler_to_overwrite >= 0) {
     617        3188 :       handlers[handler_to_overwrite] = handler;
     618        1594 :       if (!map.is_identical_to(maps.at(handler_to_overwrite))) {
     619        1207 :         maps[handler_to_overwrite] = map;
     620             :       }
     621             :     } else {
     622      209709 :       maps.push_back(map);
     623      209709 :       handlers.push_back(handler);
     624             :     }
     625             : 
     626      211305 :     ConfigureVectorState(name, maps, &handlers);
     627             :   }
     628             : 
     629             :   return true;
     630             : }
     631             : 
     632           0 : void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler,
     633             :                              Handle<Name> name) {
     634             :   DCHECK(IsHandler(*handler));
     635     1486802 :   ConfigureVectorState(name, receiver_map(), handler);
     636           0 : }
     637             : 
     638       13015 : void IC::CopyICToMegamorphicCache(Handle<Name> name) {
     639             :   MapHandles maps;
     640             :   MaybeObjectHandles handlers;
     641       13015 :   TargetMaps(&maps);
     642       26030 :   if (!nexus()->FindHandlers(&handlers, static_cast<int>(maps.size()))) return;
     643      112692 :   for (int i = 0; i < static_cast<int>(maps.size()); i++) {
     644      100204 :     UpdateMegamorphicCache(maps.at(i), name, handlers.at(i));
     645             :   }
     646             : }
     647             : 
     648      385929 : bool IC::IsTransitionOfMonomorphicTarget(Map source_map, Map target_map) {
     649      385929 :   if (source_map.is_null()) return true;
     650      385930 :   if (target_map.is_null()) return false;
     651      385931 :   if (source_map->is_abandoned_prototype_map()) return false;
     652             :   ElementsKind target_elements_kind = target_map->elements_kind();
     653      769246 :   bool more_general_transition = IsMoreGeneralElementsKindTransition(
     654      384623 :       source_map->elements_kind(), target_elements_kind);
     655             :   Map transitioned_map;
     656      384623 :   if (more_general_transition) {
     657             :     MapHandles map_list;
     658       37686 :     map_list.push_back(handle(target_map, isolate_));
     659             :     transitioned_map =
     660       12562 :         source_map->FindElementsKindTransitionedMap(isolate(), map_list);
     661             :   }
     662      384623 :   return transitioned_map == target_map;
     663             : }
     664             : 
     665           0 : void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
     666     1322707 :   PatchCache(name, MaybeObjectHandle(handler));
     667           0 : }
     668             : 
     669     2505834 : void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) {
     670             :   DCHECK(IsHandler(*handler));
     671             :   // Currently only load and store ICs support non-code handlers.
     672             :   DCHECK(IsAnyLoad() || IsAnyStore() || IsAnyHas());
     673     2505834 :   switch (state()) {
     674             :     case NO_FEEDBACK:
     675             :       break;
     676             :     case UNINITIALIZED:
     677             :     case PREMONOMORPHIC:
     678             :       UpdateMonomorphicIC(handler, name);
     679             :       break;
     680             :     case RECOMPUTE_HANDLER:
     681             :     case MONOMORPHIC:
     682      263331 :       if (IsGlobalIC()) {
     683             :         UpdateMonomorphicIC(handler, name);
     684             :         break;
     685             :       }
     686             :       V8_FALLTHROUGH;
     687             :     case POLYMORPHIC:
     688      387129 :       if (UpdatePolymorphicIC(name, handler)) break;
     689       22347 :       if (!is_keyed() || state() == RECOMPUTE_HANDLER) {
     690       13015 :         CopyICToMegamorphicCache(name);
     691             :       }
     692       22347 :       ConfigureVectorState(MEGAMORPHIC, name);
     693             :       V8_FALLTHROUGH;
     694             :     case MEGAMORPHIC:
     695      654253 :       UpdateMegamorphicCache(receiver_map(), name, handler);
     696             :       // Indicate that we've handled this case.
     697      654253 :       vector_set_ = true;
     698      654253 :       break;
     699             :     case GENERIC:
     700           0 :       UNREACHABLE();
     701             :       break;
     702             :   }
     703     2505884 : }
     704             : 
     705     3463146 : void LoadIC::UpdateCaches(LookupIterator* lookup) {
     706     5607009 :   if (state() == UNINITIALIZED && !IsLoadGlobalIC()) {
     707             :     // This is the first time we execute this inline cache. Set the target to
     708             :     // the pre monomorphic stub to delay setting the monomorphic state.
     709      108573 :     TRACE_HANDLER_STATS(isolate(), LoadIC_Premonomorphic);
     710      108565 :     ConfigureVectorState(receiver_map());
     711      108565 :     TraceIC("LoadIC", lookup->name());
     712      108565 :     return;
     713             :   }
     714             : 
     715             :   Handle<Object> code;
     716     3354581 :   if (lookup->state() == LookupIterator::ACCESS_CHECK) {
     717          35 :     code = slow_stub();
     718     3354546 :   } else if (!lookup->IsFound()) {
     719       75832 :     TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
     720       75832 :     Handle<Smi> smi_handler = LoadHandler::LoadNonExistent(isolate());
     721             :     code = LoadHandler::LoadFullChain(
     722             :         isolate(), receiver_map(),
     723       75831 :         MaybeObjectHandle(isolate()->factory()->null_value()), smi_handler);
     724             :   } else {
     725     3278714 :     if (IsLoadGlobalIC()) {
     726     2035024 :       if (lookup->TryLookupCachedProperty()) {
     727             :         DCHECK_EQ(LookupIterator::DATA, lookup->state());
     728             :       }
     729     4068357 :       if (lookup->state() == LookupIterator::DATA &&
     730             :           lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
     731             :         DCHECK(lookup->GetReceiver()->IsJSGlobalObject());
     732             :         // Now update the cell in the feedback vector.
     733     4065808 :         nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell());
     734     2032905 :         TraceIC("LoadGlobalIC", lookup->name());
     735     2032902 :         return;
     736             :       }
     737             :     }
     738     1245810 :     code = ComputeHandler(lookup);
     739             :   }
     740             : 
     741     1321669 :   PatchCache(lookup->name(), code);
     742     1321697 :   TraceIC("LoadIC", lookup->name());
     743             : }
     744             : 
     745           0 : StubCache* IC::stub_cache() {
     746             :   DCHECK(!IsAnyHas());
     747      704071 :   if (IsAnyLoad()) {
     748           0 :     return isolate()->load_stub_cache();
     749             :   } else {
     750             :     DCHECK(IsAnyStore());
     751           0 :     return isolate()->store_stub_cache();
     752             :   }
     753             : }
     754             : 
     755      704354 : void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
     756             :                                 const MaybeObjectHandle& handler) {
     757      704354 :   if (!IsAnyHas()) {
     758     1408143 :     stub_cache()->Set(*name, *map, *handler);
     759             :   }
     760      704354 : }
     761             : 
     762           0 : void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) {
     763             :   DCHECK_EQ(LookupIterator::ACCESSOR, lookup->state());
     764           0 :   if (V8_LIKELY(!TracingFlags::is_runtime_stats_enabled())) return;
     765           0 :   if (IsAnyLoad() || IsAnyHas()) {
     766           0 :     TRACE_HANDLER_STATS(isolate(), LoadIC_HandlerCacheHit_Accessor);
     767             :   } else {
     768             :     DCHECK(IsAnyStore());
     769           0 :     TRACE_HANDLER_STATS(isolate(), StoreIC_HandlerCacheHit_Accessor);
     770             :   }
     771             : }
     772             : 
     773     1245838 : Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
     774             :   Handle<Object> receiver = lookup->GetReceiver();
     775             :   ReadOnlyRoots roots(isolate());
     776             : 
     777             :   // `in` cannot be called on strings, and will always return true for string
     778             :   // wrapper length and function prototypes. The latter two cases are given
     779             :   // LoadHandler::LoadNativeDataProperty below.
     780     1245838 :   if (!IsAnyHas()) {
     781     1283180 :     if (receiver->IsString() && *lookup->name() == roots.length_string()) {
     782       10167 :       TRACE_HANDLER_STATS(isolate(), LoadIC_StringLength);
     783       10167 :       return BUILTIN_CODE(isolate(), LoadIC_StringLength);
     784             :     }
     785             : 
     786     1236726 :     if (receiver->IsStringWrapper() &&
     787             :         *lookup->name() == roots.length_string()) {
     788          81 :       TRACE_HANDLER_STATS(isolate(), LoadIC_StringWrapperLength);
     789          81 :       return BUILTIN_CODE(isolate(), LoadIC_StringWrapperLength);
     790             :     }
     791             : 
     792             :     // Use specialized code for getting prototype of functions.
     793     1303030 :     if (receiver->IsJSFunction() &&
     794     1248295 :         *lookup->name() == roots.prototype_string() &&
     795     1248295 :         !JSFunction::cast(*receiver)->PrototypeRequiresRuntimeLookup()) {
     796       12461 :       TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
     797       12461 :       return BUILTIN_CODE(isolate(), LoadIC_FunctionPrototype);
     798             :     }
     799             :   }
     800             : 
     801     1223129 :   Handle<Map> map = receiver_map();
     802             :   Handle<JSObject> holder;
     803             :   bool receiver_is_holder;
     804     1223129 :   if (lookup->state() != LookupIterator::JSPROXY) {
     805             :     holder = lookup->GetHolder<JSObject>();
     806             :     receiver_is_holder = receiver.is_identical_to(holder);
     807             :   }
     808             : 
     809     1223129 :   switch (lookup->state()) {
     810             :     case LookupIterator::INTERCEPTOR: {
     811         821 :       Handle<Smi> smi_handler = LoadHandler::LoadInterceptor(isolate());
     812             : 
     813        1642 :       if (holder->GetNamedInterceptor()->non_masking()) {
     814             :         MaybeObjectHandle holder_ref(isolate()->factory()->null_value());
     815          72 :         if (!receiver_is_holder || IsLoadGlobalIC()) {
     816          24 :           holder_ref = MaybeObjectHandle::Weak(holder);
     817             :         }
     818          48 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonMaskingInterceptorDH);
     819             :         return LoadHandler::LoadFullChain(isolate(), map, holder_ref,
     820          48 :                                           smi_handler);
     821             :       }
     822             : 
     823         773 :       if (receiver_is_holder) {
     824             :         DCHECK(map->has_named_interceptor());
     825         666 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptorDH);
     826         666 :         return smi_handler;
     827             :       }
     828             : 
     829         107 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptorFromPrototypeDH);
     830             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     831         107 :                                             smi_handler);
     832             :     }
     833             : 
     834             :     case LookupIterator::ACCESSOR: {
     835             :       // Use simple field loads for some well-known callback properties.
     836             :       // The method will only return true for absolute truths based on the
     837             :       // receiver maps.
     838             :       FieldIndex index;
     839      156557 :       if (Accessors::IsJSObjectFieldAccessor(isolate(), map, lookup->name(),
     840             :                                              &index)) {
     841       54066 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
     842       54066 :         return LoadHandler::LoadField(isolate(), index);
     843             :       }
     844      102495 :       if (holder->IsJSModuleNamespace()) {
     845             :         Handle<ObjectHashTable> exports(
     846       39768 :             Handle<JSModuleNamespace>::cast(holder)->module()->exports(),
     847       19884 :             isolate());
     848       59652 :         int entry = exports->FindEntry(roots, lookup->name(),
     849       59652 :                                        Smi::ToInt(lookup->name()->GetHash()));
     850             :         // We found the accessor, so the entry must exist.
     851             :         DCHECK_NE(entry, ObjectHashTable::kNotFound);
     852             :         int index = ObjectHashTable::EntryToValueIndex(entry);
     853       19884 :         return LoadHandler::LoadModuleExport(isolate(), index);
     854             :       }
     855             : 
     856       82611 :       Handle<Object> accessors = lookup->GetAccessors();
     857       82612 :       if (accessors->IsAccessorPair()) {
     858       76285 :         if (lookup->TryLookupCachedProperty()) {
     859             :           DCHECK_EQ(LookupIterator::DATA, lookup->state());
     860          20 :           return ComputeHandler(lookup);
     861             :         }
     862             : 
     863             :         Handle<Object> getter(AccessorPair::cast(*accessors)->getter(),
     864             :                               isolate());
     865       76793 :         if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) {
     866         270 :           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     867         270 :           return slow_stub();
     868             :         }
     869             : 
     870      152248 :         if (getter->IsFunctionTemplateInfo() &&
     871       76253 :             FunctionTemplateInfo::cast(*getter)->BreakAtEntry()) {
     872             :           // Do not install an IC if the api function has a breakpoint.
     873          10 :           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     874          10 :           return slow_stub();
     875             :         }
     876             : 
     877             :         Handle<Smi> smi_handler;
     878             : 
     879       75985 :         CallOptimization call_optimization(isolate(), getter);
     880       75985 :         if (call_optimization.is_simple_api_call()) {
     881       10948 :           if (!call_optimization.IsCompatibleReceiverMap(map, holder) ||
     882       10843 :               !holder->HasFastProperties()) {
     883          69 :             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     884          69 :             return slow_stub();
     885             :           }
     886             : 
     887             :           CallOptimization::HolderLookup holder_lookup;
     888        3580 :           call_optimization.LookupHolderOfExpectedType(map, &holder_lookup);
     889             : 
     890             :           smi_handler = LoadHandler::LoadApiGetter(
     891        3580 :               isolate(), holder_lookup == CallOptimization::kHolderIsReceiver);
     892             : 
     893             :           Handle<Context> context(
     894        3579 :               call_optimization.GetAccessorContext(holder->map()), isolate());
     895             : 
     896        3585 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterFromPrototypeDH);
     897             :           return LoadHandler::LoadFromPrototype(
     898             :               isolate(), map, holder, smi_handler,
     899             :               MaybeObjectHandle::Weak(call_optimization.api_call_info()),
     900        3581 :               MaybeObjectHandle::Weak(context));
     901             :         }
     902             : 
     903       72335 :         if (holder->HasFastProperties()) {
     904             :           smi_handler =
     905       66546 :               LoadHandler::LoadAccessor(isolate(), lookup->GetAccessorIndex());
     906             : 
     907       66546 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadAccessorDH);
     908       66546 :           if (receiver_is_holder) return smi_handler;
     909       51620 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadAccessorFromPrototypeDH);
     910        5789 :         } else if (holder->IsJSGlobalObject()) {
     911         937 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobalFromPrototypeDH);
     912         937 :           smi_handler = LoadHandler::LoadGlobal(isolate());
     913             :           return LoadHandler::LoadFromPrototype(
     914             :               isolate(), map, holder, smi_handler,
     915        1874 :               MaybeObjectHandle::Weak(lookup->GetPropertyCell()));
     916             :         } else {
     917        4852 :           smi_handler = LoadHandler::LoadNormal(isolate());
     918             : 
     919        4852 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH);
     920        4852 :           if (receiver_is_holder) return smi_handler;
     921          63 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH);
     922             :         }
     923             : 
     924             :         return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     925       51683 :                                               smi_handler);
     926             :       }
     927             : 
     928             :       Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
     929             : 
     930       12654 :       if (v8::ToCData<Address>(info->getter()) == kNullAddress ||
     931       12642 :           !AccessorInfo::IsCompatibleReceiverMap(info, map) ||
     932       24704 :           !holder->HasFastProperties() ||
     933         340 :           (info->is_sloppy() && !receiver->IsJSReceiver())) {
     934         592 :         TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     935         592 :         return slow_stub();
     936             :       }
     937             : 
     938             :       Handle<Smi> smi_handler = LoadHandler::LoadNativeDataProperty(
     939        5735 :           isolate(), lookup->GetAccessorIndex());
     940        5739 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNativeDataPropertyDH);
     941        5735 :       if (receiver_is_holder) return smi_handler;
     942         303 :       TRACE_HANDLER_STATS(isolate(),
     943             :                           LoadIC_LoadNativeDataPropertyFromPrototypeDH);
     944             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     945         303 :                                             smi_handler);
     946             :     }
     947             : 
     948             :     case LookupIterator::DATA: {
     949             :       DCHECK_EQ(kData, lookup->property_details().kind());
     950             :       Handle<Smi> smi_handler;
     951     1060175 :       if (lookup->is_dictionary_holder()) {
     952       17968 :         if (holder->IsJSGlobalObject()) {
     953             :           // TODO(verwaest): Also supporting the global object as receiver is a
     954             :           // workaround for code that leaks the global object.
     955       11783 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobalDH);
     956       11783 :           smi_handler = LoadHandler::LoadGlobal(isolate());
     957             :           return LoadHandler::LoadFromPrototype(
     958             :               isolate(), map, holder, smi_handler,
     959       23566 :               MaybeObjectHandle::Weak(lookup->GetPropertyCell()));
     960             :         }
     961             : 
     962        6185 :         smi_handler = LoadHandler::LoadNormal(isolate());
     963        6185 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH);
     964        6185 :         if (receiver_is_holder) return smi_handler;
     965        3715 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH);
     966             : 
     967     1042207 :       } else if (lookup->property_details().location() == kField) {
     968     1042207 :         FieldIndex field = lookup->GetFieldIndex();
     969     1042210 :         smi_handler = LoadHandler::LoadField(isolate(), field);
     970     1042208 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
     971     1042214 :         if (receiver_is_holder) return smi_handler;
     972      325921 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
     973             :       } else {
     974             :         DCHECK_EQ(kDescriptor, lookup->property_details().location());
     975             :         smi_handler =
     976           0 :             LoadHandler::LoadConstant(isolate(), lookup->GetConstantIndex());
     977           0 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH);
     978           0 :         if (receiver_is_holder) return smi_handler;
     979           0 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH);
     980             :       }
     981             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     982      329636 :                                             smi_handler);
     983             :     }
     984             :     case LookupIterator::INTEGER_INDEXED_EXOTIC:
     985          45 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadIntegerIndexedExoticDH);
     986          45 :       return LoadHandler::LoadNonExistent(isolate());
     987             :     case LookupIterator::JSPROXY: {
     988             :       Handle<JSProxy> holder_proxy = lookup->GetHolder<JSProxy>();
     989             :       bool receiver_is_holder_proxy = receiver.is_identical_to(holder_proxy);
     990        5527 :       Handle<Smi> smi_handler = LoadHandler::LoadProxy(isolate());
     991        5527 :       if (receiver_is_holder_proxy) {
     992        4752 :         return smi_handler;
     993             :       }
     994             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder_proxy,
     995         775 :                                             smi_handler);
     996             :     }
     997             :     case LookupIterator::ACCESS_CHECK:
     998             :     case LookupIterator::NOT_FOUND:
     999             :     case LookupIterator::TRANSITION:
    1000           0 :       UNREACHABLE();
    1001             :   }
    1002             : 
    1003           0 :   return Handle<Code>::null();
    1004             : }
    1005             : 
    1006      377696 : static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
    1007             :   // This helper implements a few common fast cases for converting
    1008             :   // non-smi keys of keyed loads/stores to a smi or a string.
    1009      377696 :   if (key->IsHeapNumber()) {
    1010             :     double value = Handle<HeapNumber>::cast(key)->value();
    1011       92421 :     if (std::isnan(value)) {
    1012             :       key = isolate->factory()->NaN_string();
    1013             :     } else {
    1014             :       // Check bounds first to avoid undefined behavior in the conversion
    1015             :       // to int.
    1016       92139 :       if (value <= Smi::kMaxValue && value >= Smi::kMinValue) {
    1017             :         int int_value = FastD2I(value);
    1018         843 :         if (value == int_value) {
    1019             :           key = handle(Smi::FromInt(int_value), isolate);
    1020             :         }
    1021             :       }
    1022             :     }
    1023      285275 :   } else if (key->IsString()) {
    1024       47555 :     key = isolate->factory()->InternalizeString(Handle<String>::cast(key));
    1025             :   }
    1026      377696 :   return key;
    1027             : }
    1028             : 
    1029         566 : bool KeyedLoadIC::CanChangeToAllowOutOfBounds(Handle<Map> receiver_map) {
    1030         566 :   const MaybeObjectHandle& handler = nexus()->FindHandlerForMap(receiver_map);
    1031         566 :   if (handler.is_null()) return false;
    1032         566 :   return LoadHandler::GetKeyedAccessLoadMode(*handler) == STANDARD_LOAD;
    1033             : }
    1034             : 
    1035      132631 : void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver,
    1036             :                                     KeyedAccessLoadMode load_mode) {
    1037             :   Handle<Map> receiver_map(receiver->map(), isolate());
    1038             :   DCHECK(receiver_map->instance_type() != JS_VALUE_TYPE);  // Checked by caller.
    1039             :   MapHandles target_receiver_maps;
    1040      132631 :   TargetMaps(&target_receiver_maps);
    1041             : 
    1042      132631 :   if (target_receiver_maps.empty()) {
    1043      115588 :     Handle<Object> handler = LoadElementHandler(receiver_map, load_mode);
    1044             :     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1045             :   }
    1046             : 
    1047       46269 :   for (Handle<Map> map : target_receiver_maps) {
    1048       29306 :     if (map.is_null()) continue;
    1049       29306 :     if (map->instance_type() == JS_VALUE_TYPE) {
    1050             :       set_slow_stub_reason("JSValue");
    1051             :       return;
    1052             :     }
    1053       29297 :     if (map->instance_type() == JS_PROXY_TYPE) {
    1054             :       set_slow_stub_reason("JSProxy");
    1055             :       return;
    1056             :     }
    1057             :   }
    1058             : 
    1059             :   // The first time a receiver is seen that is a transitioned version of the
    1060             :   // previous monomorphic receiver type, assume the new ElementsKind is the
    1061             :   // monomorphic type. This benefits global arrays that only transition
    1062             :   // once, and all call sites accessing them are faster if they remain
    1063             :   // monomorphic. If this optimistic assumption is not true, the IC will
    1064             :   // miss again and it will become polymorphic and support both the
    1065             :   // untransitioned and transitioned maps.
    1066       37364 :   if (state() == MONOMORPHIC && !receiver->IsString() &&
    1067       27071 :       !receiver->IsJSProxy() &&
    1068       20216 :       IsMoreGeneralElementsKindTransition(
    1069             :           target_receiver_maps.at(0)->elements_kind(),
    1070       27071 :           Handle<JSObject>::cast(receiver)->GetElementsKind())) {
    1071        2513 :     Handle<Object> handler = LoadElementHandler(receiver_map, load_mode);
    1072             :     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1073             :   }
    1074             : 
    1075             :   DCHECK(state() != GENERIC);
    1076             : 
    1077             :   // Determine the list of receiver maps that this call site has seen,
    1078             :   // adding the map that was just encountered.
    1079       14450 :   if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
    1080             :     // If the {receiver_map} previously had a handler that didn't handle
    1081             :     // out-of-bounds access, but can generally handle it, we can just go
    1082             :     // on and update the handler appropriately below.
    1083        2954 :     if (load_mode != LOAD_IGNORE_OUT_OF_BOUNDS ||
    1084         566 :         !CanChangeToAllowOutOfBounds(receiver_map)) {
    1085             :       // If the miss wasn't due to an unseen map, a polymorphic stub
    1086             :       // won't help, use the generic stub.
    1087             :       set_slow_stub_reason("same map added twice");
    1088             :       return;
    1089             :     }
    1090             :   }
    1091             : 
    1092             :   // If the maximum number of receiver maps has been exceeded, use the generic
    1093             :   // version of the IC.
    1094       12615 :   if (target_receiver_maps.size() > kMaxKeyedPolymorphism) {
    1095             :     set_slow_stub_reason("max polymorph exceeded");
    1096             :     return;
    1097             :   }
    1098             : 
    1099             :   MaybeObjectHandles handlers;
    1100       10831 :   handlers.reserve(target_receiver_maps.size());
    1101       10831 :   LoadElementPolymorphicHandlers(&target_receiver_maps, &handlers, load_mode);
    1102             :   DCHECK_LE(1, target_receiver_maps.size());
    1103       10831 :   if (target_receiver_maps.size() == 1) {
    1104         552 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]);
    1105             :   } else {
    1106       10279 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
    1107             :   }
    1108             : }
    1109             : 
    1110             : namespace {
    1111             : 
    1112       26457 : bool AllowConvertHoleElementToUndefined(Isolate* isolate,
    1113             :                                         Handle<Map> receiver_map) {
    1114       26457 :   if (receiver_map->IsJSTypedArrayMap()) {
    1115             :     // For JSTypedArray we never lookup elements in the prototype chain.
    1116             :     return true;
    1117             :   }
    1118             : 
    1119             :   // For other {receiver}s we need to check the "no elements" protector.
    1120       25464 :   if (isolate->IsNoElementsProtectorIntact()) {
    1121       21332 :     if (receiver_map->IsStringMap()) {
    1122             :       return true;
    1123             :     }
    1124       21195 :     if (receiver_map->IsJSObjectMap()) {
    1125             :       // For other JSObjects (including JSArrays) we can only continue if
    1126             :       // the {receiver}s prototype is either the initial Object.prototype
    1127             :       // or the initial Array.prototype, which are both guarded by the
    1128             :       // "no elements" protector checked above.
    1129             :       Handle<Object> receiver_prototype(receiver_map->prototype(), isolate);
    1130             : 
    1131       42390 :       if (isolate->IsInAnyContext(*receiver_prototype,
    1132       29003 :                                   Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ||
    1133        7808 :           isolate->IsInAnyContext(*receiver_prototype,
    1134             :                                   Context::INITIAL_OBJECT_PROTOTYPE_INDEX)) {
    1135             :         return true;
    1136             :       }
    1137             :     }
    1138             :   }
    1139             : 
    1140             :   return false;
    1141             : }
    1142             : }  // namespace
    1143             : 
    1144      145677 : Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
    1145             :                                                KeyedAccessLoadMode load_mode) {
    1146             :   // Has a getter interceptor, or is any has and has a query interceptor.
    1147      145832 :   if (receiver_map->has_indexed_interceptor() &&
    1148      145832 :       (!receiver_map->GetIndexedInterceptor()->getter()->IsUndefined(
    1149          51 :            isolate()) ||
    1150          27 :        (IsAnyHas() &&
    1151      145704 :         !receiver_map->GetIndexedInterceptor()->query()->IsUndefined(
    1152      145808 :             isolate()))) &&
    1153      145808 :       !receiver_map->GetIndexedInterceptor()->non_masking()) {
    1154             :     // TODO(jgruber): Update counter name.
    1155         131 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedInterceptorStub);
    1156             :     return IsAnyHas() ? BUILTIN_CODE(isolate(), HasIndexedInterceptorIC)
    1157         262 :                       : BUILTIN_CODE(isolate(), LoadIndexedInterceptorIC);
    1158             :   }
    1159             : 
    1160             :   InstanceType instance_type = receiver_map->instance_type();
    1161      145546 :   if (instance_type < FIRST_NONSTRING_TYPE) {
    1162        1324 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedStringDH);
    1163        1356 :     if (IsAnyHas()) return BUILTIN_CODE(isolate(), HasIC_Slow);
    1164        1292 :     return LoadHandler::LoadIndexedString(isolate(), load_mode);
    1165             :   }
    1166      144222 :   if (instance_type < FIRST_JS_RECEIVER_TYPE) {
    1167           0 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_SlowStub);
    1168             :     return IsAnyHas() ? BUILTIN_CODE(isolate(), HasIC_Slow)
    1169           0 :                       : BUILTIN_CODE(isolate(), KeyedLoadIC_Slow);
    1170             :   }
    1171      144222 :   if (instance_type == JS_PROXY_TYPE) {
    1172         185 :     return LoadHandler::LoadProxy(isolate());
    1173             :   }
    1174             : 
    1175             :   ElementsKind elements_kind = receiver_map->elements_kind();
    1176      144037 :   if (IsSloppyArgumentsElementsKind(elements_kind)) {
    1177             :     // TODO(jgruber): Update counter name.
    1178        1745 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_KeyedLoadSloppyArgumentsStub);
    1179             :     return IsAnyHas() ? BUILTIN_CODE(isolate(), KeyedHasIC_SloppyArguments)
    1180        3490 :                       : BUILTIN_CODE(isolate(), KeyedLoadIC_SloppyArguments);
    1181             :   }
    1182      142292 :   bool is_js_array = instance_type == JS_ARRAY_TYPE;
    1183      142292 :   if (elements_kind == DICTIONARY_ELEMENTS) {
    1184        4691 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadElementDH);
    1185             :     return LoadHandler::LoadElement(isolate(), elements_kind, false,
    1186        4691 :                                     is_js_array, load_mode);
    1187             :   }
    1188             :   DCHECK(IsFastElementsKind(elements_kind) ||
    1189             :          IsFixedTypedArrayElementsKind(elements_kind));
    1190             :   bool convert_hole_to_undefined =
    1191      275202 :       (elements_kind == HOLEY_SMI_ELEMENTS ||
    1192      296484 :        elements_kind == HOLEY_ELEMENTS) &&
    1193       21282 :       AllowConvertHoleElementToUndefined(isolate(), receiver_map);
    1194      137601 :   TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadElementDH);
    1195             :   return LoadHandler::LoadElement(isolate(), elements_kind,
    1196             :                                   convert_hole_to_undefined, is_js_array,
    1197      137601 :                                   load_mode);
    1198             : }
    1199             : 
    1200       10831 : void KeyedLoadIC::LoadElementPolymorphicHandlers(
    1201             :     MapHandles* receiver_maps, MaybeObjectHandles* handlers,
    1202             :     KeyedAccessLoadMode load_mode) {
    1203             :   // Filter out deprecated maps to ensure their instances get migrated.
    1204             :   receiver_maps->erase(
    1205             :       std::remove_if(
    1206             :           receiver_maps->begin(), receiver_maps->end(),
    1207             :           [](const Handle<Map>& map) { return map->is_deprecated(); }),
    1208             :       receiver_maps->end());
    1209             : 
    1210       38407 :   for (Handle<Map> receiver_map : *receiver_maps) {
    1211             :     // Mark all stable receiver maps that have elements kind transition map
    1212             :     // among receiver_maps as unstable because the optimizing compilers may
    1213             :     // generate an elements kind transition for this kind of receivers.
    1214       27576 :     if (receiver_map->is_stable()) {
    1215             :       Map tmap = receiver_map->FindElementsKindTransitionedMap(isolate(),
    1216       17471 :                                                                *receiver_maps);
    1217       17471 :       if (!tmap.is_null()) {
    1218          27 :         receiver_map->NotifyLeafMapLayoutChange(isolate());
    1219             :       }
    1220             :     }
    1221       55152 :     handlers->push_back(
    1222             :         MaybeObjectHandle(LoadElementHandler(receiver_map, load_mode)));
    1223             :   }
    1224       10831 : }
    1225             : 
    1226             : namespace {
    1227             : 
    1228      141905 : bool ConvertKeyToIndex(Handle<Object> receiver, Handle<Object> key,
    1229             :                        uint32_t* index, InlineCacheState state) {
    1230      141905 :   if (!FLAG_use_ic || state == NO_FEEDBACK) return false;
    1231      283694 :   if (receiver->IsAccessCheckNeeded() || receiver->IsJSValue()) return false;
    1232             : 
    1233             :   // For regular JSReceiver or String receivers, the {key} must be a positive
    1234             :   // array index.
    1235      144366 :   if (receiver->IsJSReceiver() || receiver->IsString()) {
    1236      279032 :     if (key->ToArrayIndex(index)) return true;
    1237             :   }
    1238             :   // For JSTypedArray receivers, we can also support negative keys, which we
    1239             :   // just map into the [2**31, 2**32 - 1] range via a bit_cast. This is valid
    1240             :   // because JSTypedArray::length is always a Smi, so such keys will always
    1241             :   // be detected as OOB.
    1242        8785 :   if (receiver->IsJSTypedArray()) {
    1243             :     int32_t signed_index;
    1244         377 :     if (key->ToInt32(&signed_index)) {
    1245         206 :       *index = bit_cast<uint32_t>(signed_index);
    1246         206 :       return true;
    1247             :     }
    1248             :   }
    1249             :   return false;
    1250             : }
    1251             : 
    1252      371222 : bool IsOutOfBoundsAccess(Handle<Object> receiver, uint32_t index) {
    1253      371222 :   uint32_t length = 0;
    1254      371222 :   if (receiver->IsJSArray()) {
    1255      619062 :     JSArray::cast(*receiver)->length()->ToArrayLength(&length);
    1256       61691 :   } else if (receiver->IsString()) {
    1257        1252 :     length = String::cast(*receiver)->length();
    1258       60439 :   } else if (receiver->IsJSObject()) {
    1259       60192 :     length = JSObject::cast(*receiver)->elements()->length();
    1260             :   } else {
    1261             :     return false;
    1262             :   }
    1263      370975 :   return index >= length;
    1264             : }
    1265             : 
    1266      132631 : KeyedAccessLoadMode GetLoadMode(Isolate* isolate, Handle<Object> receiver,
    1267             :                                 uint32_t index) {
    1268      132631 :   if (IsOutOfBoundsAccess(receiver, index)) {
    1269             :     DCHECK(receiver->IsHeapObject());
    1270             :     Handle<Map> receiver_map(Handle<HeapObject>::cast(receiver)->map(),
    1271             :                              isolate);
    1272        5175 :     if (AllowConvertHoleElementToUndefined(isolate, receiver_map)) {
    1273        3453 :       return LOAD_IGNORE_OUT_OF_BOUNDS;
    1274             :     }
    1275             :   }
    1276             :   return STANDARD_LOAD;
    1277             : }
    1278             : 
    1279             : }  // namespace
    1280             : 
    1281      142026 : MaybeHandle<Object> KeyedLoadIC::RuntimeLoad(Handle<Object> object,
    1282             :                                              Handle<Object> key) {
    1283             :   Handle<Object> result;
    1284             : 
    1285      142026 :   if (IsKeyedLoadIC()) {
    1286      280010 :     ASSIGN_RETURN_ON_EXCEPTION(
    1287             :         isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
    1288             :         Object);
    1289             :   } else {
    1290             :     DCHECK(IsKeyedHasIC());
    1291        4042 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
    1292             :                                Runtime::HasProperty(isolate(), object, key),
    1293             :                                Object);
    1294             :   }
    1295      141493 :   return result;
    1296             : }
    1297             : 
    1298      214602 : MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
    1299             :                                       Handle<Object> key) {
    1300      214602 :   if (MigrateDeprecated(object)) {
    1301         121 :     return RuntimeLoad(object, key);
    1302             :   }
    1303             : 
    1304             :   Handle<Object> load_handle;
    1305             : 
    1306             :   // Check for non-string values that can be converted into an
    1307             :   // internalized string directly or is representable as a smi.
    1308      214481 :   key = TryConvertKey(key, isolate());
    1309             : 
    1310             :   uint32_t index;
    1311      253883 :   if ((key->IsInternalizedString() &&
    1312      433680 :        !String::cast(*key)->AsArrayIndex(&index)) ||
    1313             :       key->IsSymbol()) {
    1314      145152 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle,
    1315             :                                LoadIC::Load(object, Handle<Name>::cast(key)),
    1316             :                                Object);
    1317      141905 :   } else if (ConvertKeyToIndex(object, key, &index, state())) {
    1318      132631 :     KeyedAccessLoadMode load_mode = GetLoadMode(isolate(), object, index);
    1319      132631 :     UpdateLoadElement(Handle<HeapObject>::cast(object), load_mode);
    1320      132631 :     if (is_vector_set()) {
    1321      128932 :       TraceIC("LoadIC", key);
    1322             :     }
    1323             :   }
    1324             : 
    1325      213562 :   if (vector_needs_update()) {
    1326       13008 :     ConfigureVectorState(MEGAMORPHIC, key);
    1327       13008 :     TraceIC("LoadIC", key);
    1328             :   }
    1329             : 
    1330      213562 :   if (!load_handle.is_null()) return load_handle;
    1331             : 
    1332      141905 :   return RuntimeLoad(object, key);
    1333             : }
    1334             : 
    1335     2849074 : bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
    1336             :                              StoreOrigin store_origin) {
    1337             :   // Disable ICs for non-JSObjects for now.
    1338             :   Handle<Object> object = it->GetReceiver();
    1339     2849074 :   if (object->IsJSProxy()) return true;
    1340     2848915 :   if (!object->IsJSObject()) return false;
    1341             :   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
    1342             :   DCHECK(!receiver->map()->is_deprecated());
    1343             : 
    1344     2848581 :   if (it->state() != LookupIterator::TRANSITION) {
    1345     2853607 :     for (; it->IsFound(); it->Next()) {
    1346     2359943 :       switch (it->state()) {
    1347             :         case LookupIterator::NOT_FOUND:
    1348             :         case LookupIterator::TRANSITION:
    1349           0 :           UNREACHABLE();
    1350             :         case LookupIterator::JSPROXY:
    1351             :           return true;
    1352             :         case LookupIterator::INTERCEPTOR: {
    1353             :           Handle<JSObject> holder = it->GetHolder<JSObject>();
    1354         295 :           InterceptorInfo info = holder->GetNamedInterceptor();
    1355         295 :           if (it->HolderIsReceiverOrHiddenPrototype()) {
    1356         741 :             return !info->non_masking() && receiver.is_identical_to(holder) &&
    1357             :                    !info->setter()->IsUndefined(isolate());
    1358          48 :           } else if (!info->getter()->IsUndefined(isolate()) ||
    1359             :                      !info->query()->IsUndefined(isolate())) {
    1360             :             return false;
    1361             :           }
    1362             :           break;
    1363             :         }
    1364             :         case LookupIterator::ACCESS_CHECK:
    1365        2527 :           if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
    1366             :           break;
    1367             :         case LookupIterator::ACCESSOR:
    1368      228801 :           return !it->IsReadOnly();
    1369             :         case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1370          90 :           return false;
    1371             :         case LookupIterator::DATA: {
    1372     2128023 :           if (it->IsReadOnly()) return false;
    1373             :           Handle<JSObject> holder = it->GetHolder<JSObject>();
    1374     2114879 :           if (receiver.is_identical_to(holder)) {
    1375     2109321 :             it->PrepareForDataProperty(value);
    1376             :             // The previous receiver map might just have been deprecated,
    1377             :             // so reload it.
    1378     2109324 :             update_receiver_map(receiver);
    1379     2109325 :             return true;
    1380             :           }
    1381             : 
    1382             :           // Receiver != holder.
    1383        5558 :           if (receiver->IsJSGlobalProxy()) {
    1384         640 :             PrototypeIterator iter(isolate(), receiver);
    1385             :             return it->GetHolder<Object>().is_identical_to(
    1386             :                 PrototypeIterator::GetCurrent(iter));
    1387             :           }
    1388             : 
    1389        4918 :           if (it->HolderIsReceiverOrHiddenPrototype()) return false;
    1390             : 
    1391        4918 :           if (it->ExtendingNonExtensible(receiver)) return false;
    1392        4918 :           it->PrepareTransitionToDataProperty(receiver, value, NONE,
    1393        4918 :                                               store_origin);
    1394        4918 :           return it->IsCacheableTransition();
    1395             :         }
    1396             :       }
    1397             :     }
    1398             :   }
    1399             : 
    1400      491150 :   receiver = it->GetStoreTarget<JSObject>();
    1401      491149 :   if (it->ExtendingNonExtensible(receiver)) return false;
    1402      491077 :   it->PrepareTransitionToDataProperty(receiver, value, NONE, store_origin);
    1403      491073 :   return it->IsCacheableTransition();
    1404             : }
    1405             : 
    1406     1708160 : MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name,
    1407             :                                          Handle<Object> value) {
    1408             :   DCHECK(name->IsString());
    1409             : 
    1410             :   // Look up in script context table.
    1411             :   Handle<String> str_name = Handle<String>::cast(name);
    1412     1708160 :   Handle<JSGlobalObject> global = isolate()->global_object();
    1413             :   Handle<ScriptContextTable> script_contexts(
    1414     3416320 :       global->native_context()->script_context_table(), isolate());
    1415             : 
    1416             :   ScriptContextTable::LookupResult lookup_result;
    1417     1708160 :   if (ScriptContextTable::Lookup(isolate(), *script_contexts, *str_name,
    1418             :                                  &lookup_result)) {
    1419             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    1420          70 :         isolate(), script_contexts, lookup_result.context_index);
    1421          70 :     if (lookup_result.mode == VariableMode::kConst) {
    1422          20 :       return TypeError(MessageTemplate::kConstAssign, global, name);
    1423             :     }
    1424             : 
    1425             :     Handle<Object> previous_value(script_context->get(lookup_result.slot_index),
    1426          50 :                                   isolate());
    1427             : 
    1428          50 :     if (previous_value->IsTheHole(isolate())) {
    1429             :       // Do not install stubs and stay pre-monomorphic for
    1430             :       // uninitialized accesses.
    1431          15 :       return ReferenceError(name);
    1432             :     }
    1433             : 
    1434          35 :     bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
    1435          35 :     if (use_ic) {
    1436          70 :       if (nexus()->ConfigureLexicalVarMode(
    1437             :               lookup_result.context_index, lookup_result.slot_index,
    1438          35 :               lookup_result.mode == VariableMode::kConst)) {
    1439          35 :         TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_StoreScriptContextField);
    1440             :       } else {
    1441             :         // Given combination of indices can't be encoded, so use slow stub.
    1442           0 :         TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_SlowStub);
    1443           0 :         PatchCache(name, slow_stub());
    1444             :       }
    1445          35 :       TraceIC("StoreGlobalIC", name);
    1446             :     }
    1447             : 
    1448          35 :     script_context->set(lookup_result.slot_index, *value);
    1449          35 :     return value;
    1450             :   }
    1451             : 
    1452     1708090 :   return StoreIC::Store(global, name, value);
    1453             : }
    1454             : 
    1455     3427827 : MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
    1456             :                                    Handle<Object> value,
    1457             :                                    StoreOrigin store_origin) {
    1458             :   // TODO(verwaest): Let SetProperty do the migration, since storing a property
    1459             :   // might deprecate the current map again, if value does not fit.
    1460     3427827 :   if (MigrateDeprecated(object)) {
    1461             :     Handle<Object> result;
    1462         144 :     ASSIGN_RETURN_ON_EXCEPTION(
    1463             :         isolate(), result, Object::SetProperty(isolate(), object, name, value),
    1464             :         Object);
    1465          72 :     return result;
    1466             :   }
    1467             : 
    1468     3427755 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
    1469             :   // If the object is undefined or null it's illegal to try to set any
    1470             :   // properties on it; throw a TypeError in that case.
    1471     3427755 :   if (object->IsNullOrUndefined(isolate())) {
    1472          40 :     if (use_ic && state() != PREMONOMORPHIC) {
    1473             :       // Ensure the IC state progresses.
    1474          40 :       TRACE_HANDLER_STATS(isolate(), StoreIC_NonReceiver);
    1475          40 :       update_receiver_map(object);
    1476          40 :       PatchCache(name, slow_stub());
    1477          40 :       TraceIC("StoreIC", name);
    1478             :     }
    1479          40 :     return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name);
    1480             :   }
    1481             : 
    1482     3427715 :   if (state() != UNINITIALIZED) {
    1483     1169373 :     JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate());
    1484             :   }
    1485     3427725 :   LookupIterator it(isolate(), object, name);
    1486             : 
    1487     3427729 :   if (name->IsPrivate()) {
    1488        2026 :     if (name->IsPrivateName() && !it.IsFound()) {
    1489             :       Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
    1490             :                                  isolate());
    1491             :       return TypeError(MessageTemplate::kInvalidPrivateFieldWrite, object,
    1492         172 :                        name_string);
    1493             :     }
    1494             : 
    1495             :     // IC handling of private fields/symbols stores on JSProxy is not
    1496             :     // supported.
    1497        1854 :     if (object->IsJSProxy()) {
    1498             :       use_ic = false;
    1499             :     }
    1500             :   }
    1501     3427555 :   if (use_ic) UpdateCaches(&it, value, store_origin);
    1502             : 
    1503     6855113 :   MAYBE_RETURN_NULL(Object::SetProperty(&it, value, store_origin));
    1504     3413726 :   return value;
    1505             : }
    1506             : 
    1507     3427151 : void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
    1508             :                            StoreOrigin store_origin) {
    1509     5684974 :   if (state() == UNINITIALIZED && !IsStoreGlobalIC()) {
    1510             :     // This is the first time we execute this inline cache. Transition
    1511             :     // to premonomorphic state to delay setting the monomorphic state.
    1512      578075 :     TRACE_HANDLER_STATS(isolate(), StoreIC_Premonomorphic);
    1513      578075 :     ConfigureVectorState(receiver_map());
    1514      578081 :     TraceIC("StoreIC", lookup->name());
    1515     2822090 :     return;
    1516             :   }
    1517             : 
    1518             :   MaybeObjectHandle handler;
    1519     2849076 :   if (LookupForWrite(lookup, value, store_origin)) {
    1520     2830210 :     if (IsStoreGlobalIC()) {
    1521     3373330 :       if (lookup->state() == LookupIterator::DATA &&
    1522             :           lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
    1523             :         DCHECK(lookup->GetReceiver()->IsJSGlobalObject());
    1524             :         // Now update the cell in the feedback vector.
    1525     3331820 :         nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell());
    1526     1665910 :         TraceIC("StoreGlobalIC", lookup->name());
    1527     1665910 :         return;
    1528             :       }
    1529             :     }
    1530     1164300 :     handler = ComputeHandler(lookup);
    1531             :   } else {
    1532       19112 :     if (state() == UNINITIALIZED && IsStoreGlobalIC() &&
    1533             :         lookup->state() == LookupIterator::INTERCEPTOR) {
    1534             :       InterceptorInfo info =
    1535          89 :           lookup->GetHolder<JSObject>()->GetNamedInterceptor();
    1536         107 :       if (!lookup->HolderIsReceiverOrHiddenPrototype() &&
    1537             :           !info->getter()->IsUndefined(isolate())) {
    1538             :         // Utilize premonomorphic state for global store ics that run into
    1539             :         // an interceptor because the property doesn't exist yet.
    1540             :         // After we actually set the property, we'll have more information.
    1541             :         // Premonomorphism gives us a chance to find more information the
    1542             :         // second time.
    1543          18 :         TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_Premonomorphic);
    1544          18 :         ConfigureVectorState(receiver_map());
    1545          18 :         TraceIC("StoreGlobalIC", lookup->name());
    1546          18 :         return;
    1547             :       }
    1548             :     }
    1549             : 
    1550             :     set_slow_stub_reason("LookupForWrite said 'false'");
    1551             :     // TODO(marja): change slow_stub to return MaybeObjectHandle.
    1552       18841 :     handler = MaybeObjectHandle(slow_stub());
    1553             :   }
    1554             : 
    1555     1183142 :   PatchCache(lookup->name(), handler);
    1556     1183155 :   TraceIC("StoreIC", lookup->name());
    1557             : }
    1558             : 
    1559     1164301 : MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) {
    1560     1164301 :   switch (lookup->state()) {
    1561             :     case LookupIterator::TRANSITION: {
    1562      491039 :       Handle<JSObject> store_target = lookup->GetStoreTarget<JSObject>();
    1563      491040 :       if (store_target->IsJSGlobalObject()) {
    1564       42086 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransitionDH);
    1565             : 
    1566       42086 :         if (receiver_map()->IsJSGlobalObject()) {
    1567             :           DCHECK(IsStoreGlobalIC());
    1568             : #ifdef DEBUG
    1569             :           Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1570             :           DCHECK_EQ(*lookup->GetReceiver(), *holder);
    1571             :           DCHECK_EQ(*store_target, *holder);
    1572             : #endif
    1573           0 :           return StoreHandler::StoreGlobal(lookup->transition_cell());
    1574             :         }
    1575             : 
    1576       42086 :         Handle<Smi> smi_handler = StoreHandler::StoreGlobalProxy(isolate());
    1577             :         Handle<Object> handler = StoreHandler::StoreThroughPrototype(
    1578             :             isolate(), receiver_map(), store_target, smi_handler,
    1579       42086 :             MaybeObjectHandle::Weak(lookup->transition_cell()));
    1580       42086 :         return MaybeObjectHandle(handler);
    1581             :       }
    1582             :       // Dictionary-to-fast transitions are not expected and not supported.
    1583             :       DCHECK_IMPLIES(!lookup->transition_map()->is_dictionary_map(),
    1584             :                      !receiver_map()->is_dictionary_map());
    1585             : 
    1586             :       DCHECK(lookup->IsCacheableTransition());
    1587             : 
    1588      448954 :       return StoreHandler::StoreTransition(isolate(), lookup->transition_map());
    1589             :     }
    1590             : 
    1591             :     case LookupIterator::INTERCEPTOR: {
    1592             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1593             :       USE(holder);
    1594             : 
    1595             :       DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate()));
    1596             :       // TODO(jgruber): Update counter name.
    1597         170 :       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
    1598         170 :       return MaybeObjectHandle(BUILTIN_CODE(isolate(), StoreInterceptorIC));
    1599             :     }
    1600             : 
    1601             :     case LookupIterator::ACCESSOR: {
    1602             :       // This is currently guaranteed by checks in StoreIC::Store.
    1603             :       Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
    1604             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1605             :       DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
    1606             : 
    1607      228711 :       if (!holder->HasFastProperties()) {
    1608             :         set_slow_stub_reason("accessor on slow map");
    1609         506 :         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1610         506 :         return MaybeObjectHandle(slow_stub());
    1611             :       }
    1612      228205 :       Handle<Object> accessors = lookup->GetAccessors();
    1613      228205 :       if (accessors->IsAccessorInfo()) {
    1614             :         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
    1615       91221 :         if (v8::ToCData<Address>(info->setter()) == kNullAddress) {
    1616             :           set_slow_stub_reason("setter == kNullAddress");
    1617           0 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1618           0 :           return MaybeObjectHandle(slow_stub());
    1619             :         }
    1620      182348 :         if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
    1621       91127 :             !lookup->HolderIsReceiverOrHiddenPrototype()) {
    1622             :           set_slow_stub_reason("special data property in prototype chain");
    1623          27 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1624          27 :           return MaybeObjectHandle(slow_stub());
    1625             :         }
    1626       91194 :         if (!AccessorInfo::IsCompatibleReceiverMap(info, receiver_map())) {
    1627             :           set_slow_stub_reason("incompatible receiver type");
    1628          12 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1629          12 :           return MaybeObjectHandle(slow_stub());
    1630             :         }
    1631             : 
    1632             :         Handle<Smi> smi_handler = StoreHandler::StoreNativeDataProperty(
    1633       91182 :             isolate(), lookup->GetAccessorIndex());
    1634       91182 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNativeDataPropertyDH);
    1635       91182 :         if (receiver.is_identical_to(holder)) {
    1636       91144 :           return MaybeObjectHandle(smi_handler);
    1637             :         }
    1638          38 :         TRACE_HANDLER_STATS(isolate(),
    1639             :                             StoreIC_StoreNativeDataPropertyOnPrototypeDH);
    1640             :         return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1641          38 :             isolate(), receiver_map(), holder, smi_handler));
    1642             : 
    1643      136984 :       } else if (accessors->IsAccessorPair()) {
    1644             :         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
    1645             :                               isolate());
    1646      146128 :         if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) {
    1647             :           set_slow_stub_reason("setter not a function");
    1648        8898 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1649        8898 :           return MaybeObjectHandle(slow_stub());
    1650             :         }
    1651             : 
    1652      256418 :         if (setter->IsFunctionTemplateInfo() &&
    1653      128332 :             FunctionTemplateInfo::cast(*setter)->BreakAtEntry()) {
    1654             :           // Do not install an IC if the api function has a breakpoint.
    1655          10 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1656          10 :           return MaybeObjectHandle(slow_stub());
    1657             :         }
    1658             : 
    1659      128076 :         CallOptimization call_optimization(isolate(), setter);
    1660      128076 :         if (call_optimization.is_simple_api_call()) {
    1661         399 :           if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
    1662             :             CallOptimization::HolderLookup holder_lookup;
    1663             :             call_optimization.LookupHolderOfExpectedType(receiver_map(),
    1664         351 :                                                          &holder_lookup);
    1665             : 
    1666             :             Handle<Smi> smi_handler = StoreHandler::StoreApiSetter(
    1667             :                 isolate(),
    1668         351 :                 holder_lookup == CallOptimization::kHolderIsReceiver);
    1669             : 
    1670             :             Handle<Context> context(
    1671         351 :                 call_optimization.GetAccessorContext(holder->map()), isolate());
    1672         351 :             TRACE_HANDLER_STATS(isolate(), StoreIC_StoreApiSetterOnPrototypeDH);
    1673             :             return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1674             :                 isolate(), receiver_map(), holder, smi_handler,
    1675             :                 MaybeObjectHandle::Weak(call_optimization.api_call_info()),
    1676         351 :                 MaybeObjectHandle::Weak(context)));
    1677             :           }
    1678             :           set_slow_stub_reason("incompatible receiver");
    1679          48 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1680          48 :           return MaybeObjectHandle(slow_stub());
    1681      127677 :         } else if (setter->IsFunctionTemplateInfo()) {
    1682             :           set_slow_stub_reason("setter non-simple template");
    1683           0 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1684           0 :           return MaybeObjectHandle(slow_stub());
    1685             :         }
    1686             : 
    1687             :         Handle<Smi> smi_handler =
    1688      127677 :             StoreHandler::StoreAccessor(isolate(), lookup->GetAccessorIndex());
    1689             : 
    1690      127677 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorDH);
    1691      127677 :         if (receiver.is_identical_to(holder)) {
    1692         491 :           return MaybeObjectHandle(smi_handler);
    1693             :         }
    1694      127186 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorOnPrototypeDH);
    1695             : 
    1696             :         return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1697      127186 :             isolate(), receiver_map(), holder, smi_handler));
    1698             :       }
    1699           0 :       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1700           0 :       return MaybeObjectHandle(slow_stub());
    1701             :     }
    1702             : 
    1703             :     case LookupIterator::DATA: {
    1704             :       // This is currently guaranteed by checks in StoreIC::Store.
    1705             :       Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
    1706             :       USE(receiver);
    1707             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1708             :       DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
    1709             : 
    1710             :       DCHECK_EQ(kData, lookup->property_details().kind());
    1711      444010 :       if (lookup->is_dictionary_holder()) {
    1712        5086 :         if (holder->IsJSGlobalObject()) {
    1713         599 :           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalDH);
    1714             :           return MaybeObjectHandle(
    1715         599 :               StoreHandler::StoreGlobal(lookup->GetPropertyCell()));
    1716             :         }
    1717        4487 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormalDH);
    1718             :         DCHECK(holder.is_identical_to(receiver));
    1719        4487 :         return MaybeObjectHandle(StoreHandler::StoreNormal(isolate()));
    1720             :       }
    1721             : 
    1722             :       // -------------- Fields --------------
    1723      438924 :       if (lookup->property_details().location() == kField) {
    1724      438924 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH);
    1725      438924 :         int descriptor = lookup->GetFieldDescriptorIndex();
    1726      438924 :         FieldIndex index = lookup->GetFieldIndex();
    1727             :         PropertyConstness constness = lookup->constness();
    1728      438925 :         if (constness == PropertyConstness::kConst &&
    1729             :             IsStoreOwnICKind(nexus()->kind())) {
    1730             :           // StoreOwnICs are used for initializing object literals therefore
    1731             :           // we must store the value unconditionally even to
    1732             :           // VariableMode::kConst fields.
    1733             :           constness = PropertyConstness::kMutable;
    1734             :         }
    1735             :         return MaybeObjectHandle(StoreHandler::StoreField(
    1736      438924 :             isolate(), descriptor, index, constness, lookup->representation()));
    1737             :       }
    1738             : 
    1739             :       // -------------- Constant properties --------------
    1740             :       DCHECK_EQ(kDescriptor, lookup->property_details().location());
    1741             :       set_slow_stub_reason("constant property");
    1742           0 :       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1743           0 :       return MaybeObjectHandle(slow_stub());
    1744             :     }
    1745             :     case LookupIterator::JSPROXY: {
    1746             :       Handle<JSReceiver> receiver =
    1747         371 :           Handle<JSReceiver>::cast(lookup->GetReceiver());
    1748         371 :       Handle<JSProxy> holder = lookup->GetHolder<JSProxy>();
    1749             :       return MaybeObjectHandle(StoreHandler::StoreProxy(
    1750         371 :           isolate(), receiver_map(), holder, receiver));
    1751             :     }
    1752             : 
    1753             :     case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1754             :     case LookupIterator::ACCESS_CHECK:
    1755             :     case LookupIterator::NOT_FOUND:
    1756           0 :       UNREACHABLE();
    1757             :   }
    1758           0 :   return MaybeObjectHandle();
    1759             : }
    1760             : 
    1761      230287 : void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
    1762             :                                       KeyedAccessStoreMode store_mode,
    1763             :                                       bool receiver_was_cow) {
    1764             :   MapHandles target_receiver_maps;
    1765      230287 :   TargetMaps(&target_receiver_maps);
    1766      230287 :   if (target_receiver_maps.empty()) {
    1767             :     Handle<Map> monomorphic_map =
    1768      218640 :         ComputeTransitionedMap(receiver_map, store_mode);
    1769             :     store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1770      218640 :     Handle<Object> handler = StoreElementHandler(monomorphic_map, store_mode);
    1771             :     return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
    1772             :   }
    1773             : 
    1774       28084 :   for (Handle<Map> map : target_receiver_maps) {
    1775       32892 :     if (!map.is_null() && map->instance_type() == JS_VALUE_TYPE) {
    1776             :       DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1777             :       set_slow_stub_reason("JSValue");
    1778             :       return;
    1779             :     }
    1780             :   }
    1781             : 
    1782             :   // There are several special cases where an IC that is MONOMORPHIC can still
    1783             :   // transition to a different GetNonTransitioningStoreMode IC that handles a
    1784             :   // superset of the original IC. Handle those here if the receiver map hasn't
    1785             :   // changed or it has transitioned to a more general kind.
    1786             :   KeyedAccessStoreMode old_store_mode;
    1787             :   old_store_mode = GetKeyedAccessStoreMode();
    1788       11638 :   Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
    1789       11638 :   if (state() == MONOMORPHIC) {
    1790             :     Handle<Map> transitioned_receiver_map = receiver_map;
    1791        9018 :     if (IsTransitionStoreMode(store_mode)) {
    1792             :       transitioned_receiver_map =
    1793        2679 :           ComputeTransitionedMap(receiver_map, store_mode);
    1794             :     }
    1795       11506 :     if ((receiver_map.is_identical_to(previous_receiver_map) &&
    1796       16516 :          IsTransitionStoreMode(store_mode)) ||
    1797        7498 :         IsTransitionOfMonomorphicTarget(*previous_receiver_map,
    1798             :                                         *transitioned_receiver_map)) {
    1799             :       // If the "old" and "new" maps are in the same elements map family, or
    1800             :       // if they at least come from the same origin for a transitioning store,
    1801             :       // stay MONOMORPHIC and use the map for the most generic ElementsKind.
    1802             :       store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1803             :       Handle<Object> handler =
    1804        4976 :           StoreElementHandler(transitioned_receiver_map, store_mode);
    1805             :       ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler);
    1806             :       return;
    1807             :     }
    1808        5010 :     if (receiver_map.is_identical_to(previous_receiver_map) &&
    1809        4876 :         old_store_mode == STANDARD_STORE &&
    1810        1668 :         (store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1811        1192 :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1812             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
    1813             :       // A "normal" IC that handles stores can switch to a version that can
    1814             :       // grow at the end of the array, handle OOB accesses or copy COW arrays
    1815             :       // and still stay MONOMORPHIC.
    1816         485 :       Handle<Object> handler = StoreElementHandler(receiver_map, store_mode);
    1817             :       return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1818             :     }
    1819             :   }
    1820             : 
    1821             :   DCHECK(state() != GENERIC);
    1822             : 
    1823             :   bool map_added =
    1824        6177 :       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
    1825             : 
    1826        6177 :   if (IsTransitionStoreMode(store_mode)) {
    1827             :     Handle<Map> transitioned_receiver_map =
    1828        1248 :         ComputeTransitionedMap(receiver_map, store_mode);
    1829             :     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
    1830        1248 :                                             transitioned_receiver_map);
    1831             :   }
    1832             : 
    1833        6177 :   if (!map_added) {
    1834             :     // If the miss wasn't due to an unseen map, a polymorphic stub
    1835             :     // won't help, use the megamorphic stub which can handle everything.
    1836             :     set_slow_stub_reason("same map added twice");
    1837             :     return;
    1838             :   }
    1839             : 
    1840             :   // If the maximum number of receiver maps has been exceeded, use the
    1841             :   // megamorphic version of the IC.
    1842        5551 :   if (target_receiver_maps.size() > kMaxKeyedPolymorphism) return;
    1843             : 
    1844             :   // Make sure all polymorphic handlers have the same store mode, otherwise the
    1845             :   // megamorphic stub must be used.
    1846             :   store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1847        4818 :   if (old_store_mode != STANDARD_STORE) {
    1848         752 :     if (store_mode == STANDARD_STORE) {
    1849             :       store_mode = old_store_mode;
    1850         488 :     } else if (store_mode != old_store_mode) {
    1851             :       set_slow_stub_reason("store mode mismatch");
    1852             :       return;
    1853             :     }
    1854             :   }
    1855             : 
    1856             :   // If the store mode isn't the standard mode, make sure that all polymorphic
    1857             :   // receivers are either external arrays, or all "normal" arrays. Otherwise,
    1858             :   // use the megamorphic stub.
    1859        4791 :   if (store_mode != STANDARD_STORE) {
    1860             :     size_t external_arrays = 0;
    1861        2957 :     for (Handle<Map> map : target_receiver_maps) {
    1862        2068 :       if (map->has_fixed_typed_array_elements()) {
    1863             :         DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1864         306 :         external_arrays++;
    1865             :       }
    1866             :     }
    1867         889 :     if (external_arrays != 0 &&
    1868             :         external_arrays != target_receiver_maps.size()) {
    1869             :       DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1870             :       set_slow_stub_reason(
    1871             :           "unsupported combination of external and normal arrays");
    1872             :       return;
    1873             :     }
    1874             :   }
    1875             : 
    1876             :   MaybeObjectHandles handlers;
    1877        4764 :   handlers.reserve(target_receiver_maps.size());
    1878        4764 :   StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode);
    1879        4764 :   if (target_receiver_maps.size() == 0) {
    1880             :     // Transition to PREMONOMORPHIC state here and remember a weak-reference
    1881             :     // to the {receiver_map} in case TurboFan sees this function before the
    1882             :     // IC can transition further.
    1883           9 :     ConfigureVectorState(receiver_map);
    1884        4755 :   } else if (target_receiver_maps.size() == 1) {
    1885          18 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]);
    1886             :   } else {
    1887        4737 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
    1888             :   }
    1889             : }
    1890             : 
    1891      222567 : Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
    1892             :     Handle<Map> map, KeyedAccessStoreMode store_mode) {
    1893             :   switch (store_mode) {
    1894             :     case STORE_TRANSITION_TO_OBJECT:
    1895             :     case STORE_AND_GROW_TRANSITION_TO_OBJECT: {
    1896             :       ElementsKind kind = IsHoleyElementsKind(map->elements_kind())
    1897             :                               ? HOLEY_ELEMENTS
    1898       18519 :                               : PACKED_ELEMENTS;
    1899       18519 :       return Map::TransitionElementsTo(isolate(), map, kind);
    1900             :     }
    1901             :     case STORE_TRANSITION_TO_DOUBLE:
    1902             :     case STORE_AND_GROW_TRANSITION_TO_DOUBLE: {
    1903             :       ElementsKind kind = IsHoleyElementsKind(map->elements_kind())
    1904             :                               ? HOLEY_DOUBLE_ELEMENTS
    1905        3696 :                               : PACKED_DOUBLE_ELEMENTS;
    1906        3696 :       return Map::TransitionElementsTo(isolate(), map, kind);
    1907             :     }
    1908             :     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
    1909             :       DCHECK(map->has_fixed_typed_array_elements());
    1910             :       V8_FALLTHROUGH;
    1911             :     case STORE_NO_TRANSITION_HANDLE_COW:
    1912             :     case STANDARD_STORE:
    1913             :     case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
    1914      200352 :       return map;
    1915             :   }
    1916           0 :   UNREACHABLE();
    1917             : }
    1918             : 
    1919      234441 : Handle<Object> KeyedStoreIC::StoreElementHandler(
    1920             :     Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
    1921             :   DCHECK(store_mode == STANDARD_STORE ||
    1922             :          store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1923             :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1924             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
    1925             :   DCHECK_IMPLIES(
    1926             :       receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()),
    1927             :       IsStoreInArrayLiteralICKind(kind()));
    1928             : 
    1929      234441 :   if (receiver_map->IsJSProxyMap()) {
    1930          72 :     return StoreHandler::StoreProxy(isolate());
    1931             :   }
    1932             : 
    1933             :   // TODO(ishell): move to StoreHandler::StoreElement().
    1934             :   Handle<Code> code;
    1935      234369 :   if (receiver_map->has_sloppy_arguments_elements()) {
    1936             :     // TODO(jgruber): Update counter name.
    1937           0 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
    1938             :     code =
    1939           0 :         CodeFactory::KeyedStoreIC_SloppyArguments(isolate(), store_mode).code();
    1940      259128 :   } else if (receiver_map->has_fast_elements() ||
    1941             :              receiver_map->has_fixed_typed_array_elements()) {
    1942      232966 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
    1943      465932 :     code = CodeFactory::StoreFastElementIC(isolate(), store_mode).code();
    1944      232966 :     if (receiver_map->has_fixed_typed_array_elements()) return code;
    1945        1403 :   } else if (IsStoreInArrayLiteralICKind(kind())) {
    1946             :     // TODO(jgruber): Update counter name.
    1947          36 :     TRACE_HANDLER_STATS(isolate(), StoreInArrayLiteralIC_SlowStub);
    1948             :     code =
    1949          72 :         CodeFactory::StoreInArrayLiteralIC_Slow(isolate(), store_mode).code();
    1950             :   } else {
    1951             :     // TODO(jgruber): Update counter name.
    1952        1367 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
    1953             :     DCHECK_EQ(DICTIONARY_ELEMENTS, receiver_map->elements_kind());
    1954        2734 :     code = CodeFactory::KeyedStoreIC_Slow(isolate(), store_mode).code();
    1955             :   }
    1956             : 
    1957      211013 :   if (IsStoreInArrayLiteralICKind(kind())) return code;
    1958             : 
    1959             :   Handle<Object> validity_cell =
    1960       26537 :       Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
    1961       26537 :   if (validity_cell->IsSmi()) {
    1962             :     // There's no prototype validity cell to check, so we can just use the stub.
    1963          51 :     return code;
    1964             :   }
    1965       26486 :   Handle<StoreHandler> handler = isolate()->factory()->NewStoreHandler(0);
    1966       26486 :   handler->set_validity_cell(*validity_cell);
    1967       52972 :   handler->set_smi_handler(*code);
    1968       26486 :   return handler;
    1969             : }
    1970             : 
    1971        4764 : void KeyedStoreIC::StoreElementPolymorphicHandlers(
    1972             :     MapHandles* receiver_maps, MaybeObjectHandles* handlers,
    1973             :     KeyedAccessStoreMode store_mode) {
    1974             :   DCHECK(store_mode == STANDARD_STORE ||
    1975             :          store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1976             :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1977             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
    1978             : 
    1979             :   // Filter out deprecated maps to ensure their instances get migrated.
    1980             :   receiver_maps->erase(
    1981             :       std::remove_if(
    1982             :           receiver_maps->begin(), receiver_maps->end(),
    1983             :           [](const Handle<Map>& map) { return map->is_deprecated(); }),
    1984             :       receiver_maps->end());
    1985             : 
    1986       16841 :   for (Handle<Map> receiver_map : *receiver_maps) {
    1987             :     Handle<Object> handler;
    1988             :     Handle<Map> transition;
    1989             : 
    1990       36231 :     if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE ||
    1991       24154 :         receiver_map->DictionaryElementsInPrototypeChainOnly(isolate())) {
    1992             :       // TODO(mvstanton): Consider embedding store_mode in the state of the slow
    1993             :       // keyed store ic for uniformity.
    1994          45 :       TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
    1995          45 :       handler = slow_stub();
    1996             : 
    1997             :     } else {
    1998             :       {
    1999             :         Map tmap = receiver_map->FindElementsKindTransitionedMap(
    2000       12032 :             isolate(), *receiver_maps);
    2001       12032 :         if (!tmap.is_null()) {
    2002        1692 :           if (receiver_map->is_stable()) {
    2003          36 :             receiver_map->NotifyLeafMapLayoutChange(isolate());
    2004             :           }
    2005             :           transition = handle(tmap, isolate());
    2006             :         }
    2007             :       }
    2008             : 
    2009             :       // TODO(mvstanton): The code below is doing pessimistic elements
    2010             :       // transitions. I would like to stop doing that and rely on Allocation
    2011             :       // Site Tracking to do a better job of ensuring the data types are what
    2012             :       // they need to be. Not all the elements are in place yet, pessimistic
    2013             :       // elements transitions are still important for performance.
    2014       12032 :       if (!transition.is_null()) {
    2015        1692 :         TRACE_HANDLER_STATS(isolate(),
    2016             :                             KeyedStoreIC_ElementsTransitionAndStoreStub);
    2017             :         handler = StoreHandler::StoreElementTransition(isolate(), receiver_map,
    2018        1692 :                                                        transition, store_mode);
    2019             :       } else {
    2020       10340 :         handler = StoreElementHandler(receiver_map, store_mode);
    2021             :       }
    2022             :     }
    2023             :     DCHECK(!handler.is_null());
    2024       12077 :     handlers->push_back(MaybeObjectHandle(handler));
    2025             :   }
    2026        4764 : }
    2027             : 
    2028      238591 : static KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
    2029             :                                          uint32_t index, Handle<Object> value) {
    2030      238591 :   bool oob_access = IsOutOfBoundsAccess(receiver, index);
    2031             :   // Don't consider this a growing store if the store would send the receiver to
    2032             :   // dictionary mode.
    2033      250521 :   bool allow_growth = receiver->IsJSArray() && oob_access &&
    2034      250521 :                       !receiver->WouldConvertToSlowElements(index);
    2035      238591 :   if (allow_growth) {
    2036             :     // Handle growing array in stub if necessary.
    2037       22272 :     if (receiver->HasSmiElements()) {
    2038        7631 :       if (value->IsHeapNumber()) {
    2039             :         return STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    2040             :       }
    2041        7191 :       if (value->IsHeapObject()) {
    2042             :         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
    2043             :       }
    2044        7010 :     } else if (receiver->HasDoubleElements()) {
    2045        1006 :       if (!value->IsSmi() && !value->IsHeapNumber()) {
    2046             :         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
    2047             :       }
    2048             :     }
    2049             :     return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    2050             :   } else {
    2051             :     // Handle only in-bounds elements accesses.
    2052      454910 :     if (receiver->HasSmiElements()) {
    2053      181661 :       if (value->IsHeapNumber()) {
    2054             :         return STORE_TRANSITION_TO_DOUBLE;
    2055      178783 :       } else if (value->IsHeapObject()) {
    2056             :         return STORE_TRANSITION_TO_OBJECT;
    2057             :       }
    2058       91588 :     } else if (receiver->HasDoubleElements()) {
    2059        7934 :       if (!value->IsSmi() && !value->IsHeapNumber()) {
    2060             :         return STORE_TRANSITION_TO_OBJECT;
    2061             :       }
    2062             :     }
    2063      615084 :     if (!FLAG_trace_external_array_abuse &&
    2064      224869 :         receiver->map()->has_fixed_typed_array_elements() && oob_access) {
    2065             :       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
    2066             :     }
    2067      408534 :     return receiver->elements()->IsCowArray() ? STORE_NO_TRANSITION_HANDLE_COW
    2068      204267 :                                               : STANDARD_STORE;
    2069             :   }
    2070             : }
    2071             : 
    2072      163242 : MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
    2073             :                                         Handle<Object> key,
    2074             :                                         Handle<Object> value) {
    2075             :   // TODO(verwaest): Let SetProperty do the migration, since storing a property
    2076             :   // might deprecate the current map again, if value does not fit.
    2077      163242 :   if (MigrateDeprecated(object)) {
    2078             :     Handle<Object> result;
    2079          54 :     ASSIGN_RETURN_ON_EXCEPTION(
    2080             :         isolate(), result,
    2081             :         Runtime::SetObjectProperty(isolate(), object, key, value,
    2082             :                                    StoreOrigin::kMaybeKeyed),
    2083             :         Object);
    2084          27 :     return result;
    2085             :   }
    2086             : 
    2087             :   // Check for non-string values that can be converted into an
    2088             :   // internalized string directly or is representable as a smi.
    2089      163215 :   key = TryConvertKey(key, isolate());
    2090             : 
    2091             :   Handle<Object> store_handle;
    2092             : 
    2093             :   uint32_t index;
    2094      171650 :   if ((key->IsInternalizedString() &&
    2095      327352 :        !String::cast(*key)->AsArrayIndex(&index)) ||
    2096             :       key->IsSymbol()) {
    2097       24288 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle,
    2098             :                                StoreIC::Store(object, Handle<Name>::cast(key),
    2099             :                                               value, StoreOrigin::kMaybeKeyed),
    2100             :                                Object);
    2101       11575 :     if (vector_needs_update()) {
    2102          18 :       if (ConfigureVectorState(MEGAMORPHIC, key)) {
    2103             :         set_slow_stub_reason("unhandled internalized string key");
    2104          18 :         TraceIC("StoreIC", key);
    2105             :       }
    2106             :     }
    2107       11575 :     return store_handle;
    2108             :   }
    2109             : 
    2110      151071 :   JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate());
    2111             : 
    2112      302142 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic &&
    2113      452688 :                 !object->IsStringWrapper() && !object->IsAccessCheckNeeded() &&
    2114             :                 !object->IsJSGlobalProxy();
    2115      301736 :   if (use_ic && !object->IsSmi()) {
    2116             :     // Don't use ICs for maps of the objects in Array's prototype chain. We
    2117             :     // expect to be able to trap element sets to objects with those maps in
    2118             :     // the runtime to enable optimization of element hole access.
    2119             :     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
    2120      150250 :     if (heap_object->map()->IsMapInArrayPrototypeChain(isolate())) {
    2121             :       set_slow_stub_reason("map in array prototype");
    2122             :       use_ic = false;
    2123             :     }
    2124             :   }
    2125             : 
    2126             :   Handle<Map> old_receiver_map;
    2127             :   bool is_arguments = false;
    2128             :   bool key_is_valid_index = false;
    2129             :   KeyedAccessStoreMode store_mode = STANDARD_STORE;
    2130      300896 :   if (use_ic && object->IsJSReceiver()) {
    2131             :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
    2132             :     old_receiver_map = handle(receiver->map(), isolate());
    2133             :     is_arguments = receiver->IsJSArgumentsObject();
    2134             :     bool is_proxy = receiver->IsJSProxy();
    2135             :     // For JSTypedArray {object}s we can handle negative indices as OOB
    2136             :     // accesses, since integer indexed properties are never looked up
    2137             :     // on the prototype chain. For this we simply map the negative {key}s
    2138             :     // to the [2**31,2**32-1] range, which is safe since JSTypedArray::length
    2139             :     // is always an unsigned Smi.
    2140             :     key_is_valid_index =
    2141      205587 :         key->IsSmi() && (Smi::ToInt(*key) >= 0 || object->IsJSTypedArray());
    2142      149171 :     if (!is_arguments && !is_proxy) {
    2143      147490 :       if (key_is_valid_index) {
    2144       54133 :         uint32_t index = static_cast<uint32_t>(Smi::ToInt(*key));
    2145       54133 :         Handle<JSObject> receiver_object = Handle<JSObject>::cast(object);
    2146       54133 :         store_mode = GetStoreMode(receiver_object, index, value);
    2147             :       }
    2148             :     }
    2149             :   }
    2150             : 
    2151             :   DCHECK(store_handle.is_null());
    2152             :   bool receiver_was_cow =
    2153      268096 :       object->IsJSArray() &&
    2154      268096 :       Handle<JSArray>::cast(object)->elements()->IsCowArray();
    2155      302142 :   ASSIGN_RETURN_ON_EXCEPTION(
    2156             :       isolate(), store_handle,
    2157             :       Runtime::SetObjectProperty(isolate(), object, key, value,
    2158             :                                  StoreOrigin::kMaybeKeyed),
    2159             :       Object);
    2160             : 
    2161       56594 :   if (use_ic) {
    2162       55368 :     if (!old_receiver_map.is_null()) {
    2163       54831 :       if (is_arguments) {
    2164             :         set_slow_stub_reason("arguments receiver");
    2165       53677 :       } else if (key_is_valid_index) {
    2166       50869 :         if (old_receiver_map->is_abandoned_prototype_map()) {
    2167             :           set_slow_stub_reason("receiver with prototype map");
    2168       50860 :         } else if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly(
    2169             :                        isolate())) {
    2170             :           // We should go generic if receiver isn't a dictionary, but our
    2171             :           // prototype chain does have dictionary elements. This ensures that
    2172             :           // other non-dictionary receivers in the polymorphic case benefit
    2173             :           // from fast path keyed stores.
    2174       45829 :           UpdateStoreElement(old_receiver_map, store_mode, receiver_was_cow);
    2175             :         } else {
    2176             :           set_slow_stub_reason("dictionary or proxy prototype");
    2177             :         }
    2178             :       } else {
    2179             :         set_slow_stub_reason("non-smi-like key");
    2180             :       }
    2181             :     } else {
    2182             :       set_slow_stub_reason("non-JSObject receiver");
    2183             :     }
    2184             :   }
    2185             : 
    2186       56594 :   if (vector_needs_update()) {
    2187       12187 :     ConfigureVectorState(MEGAMORPHIC, key);
    2188             :   }
    2189       56594 :   TraceIC("StoreIC", key);
    2190             : 
    2191       56594 :   return store_handle;
    2192             : }
    2193             : 
    2194             : namespace {
    2195      184580 : void StoreOwnElement(Isolate* isolate, Handle<JSArray> array,
    2196             :                      Handle<Object> index, Handle<Object> value) {
    2197             :   DCHECK(index->IsNumber());
    2198      184580 :   bool success = false;
    2199             :   LookupIterator it = LookupIterator::PropertyOrElement(
    2200      184580 :       isolate, array, index, &success, LookupIterator::OWN);
    2201             :   DCHECK(success);
    2202             : 
    2203      369160 :   CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(
    2204             :             &it, value, NONE, Just(ShouldThrow::kThrowOnError))
    2205             :             .FromJust());
    2206      184580 : }
    2207             : }  // namespace
    2208             : 
    2209      184458 : void StoreInArrayLiteralIC::Store(Handle<JSArray> array, Handle<Object> index,
    2210             :                                   Handle<Object> value) {
    2211             :   DCHECK(!array->map()->IsMapInArrayPrototypeChain(isolate()));
    2212             :   DCHECK(index->IsNumber());
    2213             : 
    2214      368916 :   if (!FLAG_use_ic || state() == NO_FEEDBACK || MigrateDeprecated(array)) {
    2215           0 :     StoreOwnElement(isolate(), array, index, value);
    2216           0 :     TraceIC("StoreInArrayLiteralIC", index);
    2217           0 :     return;
    2218             :   }
    2219             : 
    2220             :   // TODO(neis): Convert HeapNumber to Smi if possible?
    2221             : 
    2222             :   KeyedAccessStoreMode store_mode = STANDARD_STORE;
    2223      184458 :   if (index->IsSmi()) {
    2224             :     DCHECK_GE(Smi::ToInt(*index), 0);
    2225      184458 :     uint32_t index32 = static_cast<uint32_t>(Smi::ToInt(*index));
    2226      184458 :     store_mode = GetStoreMode(array, index32, value);
    2227             :   }
    2228             : 
    2229             :   Handle<Map> old_array_map(array->map(), isolate());
    2230      184458 :   bool array_was_cow = array->elements()->IsCowArray();
    2231      184458 :   StoreOwnElement(isolate(), array, index, value);
    2232             : 
    2233      184458 :   if (index->IsSmi()) {
    2234             :     DCHECK(!old_array_map->is_abandoned_prototype_map());
    2235      184458 :     UpdateStoreElement(old_array_map, store_mode, array_was_cow);
    2236             :   } else {
    2237             :     set_slow_stub_reason("index out of Smi range");
    2238             :   }
    2239             : 
    2240      184458 :   if (vector_needs_update()) {
    2241           0 :     ConfigureVectorState(MEGAMORPHIC, index);
    2242             :   }
    2243      184458 :   TraceIC("StoreInArrayLiteralIC", index);
    2244             : }
    2245             : 
    2246             : // ----------------------------------------------------------------------------
    2247             : // Static IC stub generators.
    2248             : //
    2249             : //
    2250     2714858 : RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
    2251             :   HandleScope scope(isolate);
    2252             :   DCHECK_EQ(4, args.length());
    2253             :   // Runtime functions don't follow the IC's calling convention.
    2254             :   Handle<Object> receiver = args.at(0);
    2255             :   Handle<Name> key = args.at<Name>(1);
    2256             :   Handle<Smi> slot = args.at<Smi>(2);
    2257             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2258             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2259             : 
    2260             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2261     1357404 :   if (!maybe_vector->IsUndefined()) {
    2262             :     DCHECK(maybe_vector->IsFeedbackVector());
    2263             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2264             :   }
    2265             :   // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
    2266             :   // LoadIC miss handler if the handler misses. Since the vector Nexus is
    2267             :   // set up outside the IC, handle that here.
    2268             :   // The only case where we call without a vector is from the LoadNamedProperty
    2269             :   // bytecode handler. Also, when there is no feedback vector, there is no
    2270             :   // difference between LoadProperty or LoadKeyed kind.
    2271             :   FeedbackSlotKind kind = FeedbackSlotKind::kLoadProperty;
    2272     1357404 :   if (!vector.is_null()) {
    2273     1357404 :     kind = vector->GetKind(vector_slot);
    2274             :   }
    2275     1357407 :   if (IsLoadICKind(kind)) {
    2276     2714794 :     LoadIC ic(isolate, vector, vector_slot, kind);
    2277     1357392 :     ic.UpdateState(receiver, key);
    2278     2714782 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2279             : 
    2280           0 :   } else if (IsLoadGlobalICKind(kind)) {
    2281             :     DCHECK_EQ(isolate->native_context()->global_proxy(), *receiver);
    2282           0 :     receiver = isolate->global_object();
    2283           0 :     LoadGlobalIC ic(isolate, vector, vector_slot, kind);
    2284           0 :     ic.UpdateState(receiver, key);
    2285           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key));
    2286             : 
    2287             :   } else {
    2288             :     DCHECK(IsKeyedLoadICKind(kind));
    2289           0 :     KeyedLoadIC ic(isolate, vector, vector_slot, kind);
    2290           0 :     ic.UpdateState(receiver, key);
    2291           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2292             :   }
    2293             : }
    2294             : 
    2295     4530034 : RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) {
    2296             :   HandleScope scope(isolate);
    2297             :   DCHECK_EQ(4, args.length());
    2298             :   // Runtime functions don't follow the IC's calling convention.
    2299     2264992 :   Handle<JSGlobalObject> global = isolate->global_object();
    2300             :   Handle<String> name = args.at<String>(0);
    2301             :   Handle<Smi> slot = args.at<Smi>(1);
    2302             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2303     4529980 :   CONVERT_INT32_ARG_CHECKED(typeof_value, 3);
    2304     2264987 :   TypeofMode typeof_mode = static_cast<TypeofMode>(typeof_value);
    2305             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2306             : 
    2307             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2308     2264987 :   if (!maybe_vector->IsUndefined()) {
    2309             :     DCHECK(maybe_vector->IsFeedbackVector());
    2310             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2311             :   }
    2312             : 
    2313             :   FeedbackSlotKind kind = (typeof_mode == TypeofMode::INSIDE_TYPEOF)
    2314             :                               ? FeedbackSlotKind::kLoadGlobalInsideTypeof
    2315     2264987 :                               : FeedbackSlotKind::kLoadGlobalNotInsideTypeof;
    2316     4529975 :   LoadGlobalIC ic(isolate, vector, vector_slot, kind);
    2317     2264989 :   ic.UpdateState(global, name);
    2318             : 
    2319             :   Handle<Object> result;
    2320     4529983 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(name));
    2321             :   return *result;
    2322             : }
    2323             : 
    2324        1568 : RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) {
    2325             :   HandleScope scope(isolate);
    2326             :   DCHECK_EQ(3, args.length());
    2327         784 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    2328             : 
    2329         784 :   Handle<Context> native_context = isolate->native_context();
    2330             :   Handle<ScriptContextTable> script_contexts(
    2331        1568 :       native_context->script_context_table(), isolate);
    2332             : 
    2333             :   ScriptContextTable::LookupResult lookup_result;
    2334         784 :   if (ScriptContextTable::Lookup(isolate, *script_contexts, *name,
    2335             :                                  &lookup_result)) {
    2336             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    2337           0 :         isolate, script_contexts, lookup_result.context_index);
    2338             :     Handle<Object> result(script_context->get(lookup_result.slot_index),
    2339           0 :                           isolate);
    2340           0 :     if (*result == ReadOnlyRoots(isolate).the_hole_value()) {
    2341           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2342             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2343             :     }
    2344             :     return *result;
    2345             :   }
    2346             : 
    2347        1568 :   Handle<JSGlobalObject> global(native_context->global_object(), isolate);
    2348             :   Handle<Object> result;
    2349         784 :   bool is_found = false;
    2350        1568 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    2351             :       isolate, result,
    2352             :       Runtime::GetObjectProperty(isolate, global, name, &is_found));
    2353         784 :   if (!is_found) {
    2354             :     Handle<Smi> slot = args.at<Smi>(1);
    2355           0 :     Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2356             :     FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2357           0 :     FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2358             :     // It is actually a LoadGlobalICs here but the predicate handles this case
    2359             :     // properly.
    2360           0 :     if (LoadIC::ShouldThrowReferenceError(kind)) {
    2361           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2362             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2363             :     }
    2364             :   }
    2365             :   return *result;
    2366             : }
    2367             : 
    2368      418270 : RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) {
    2369             :   HandleScope scope(isolate);
    2370             :   DCHECK_EQ(4, args.length());
    2371             :   // Runtime functions don't follow the IC's calling convention.
    2372             :   Handle<Object> receiver = args.at(0);
    2373             :   Handle<Object> key = args.at(1);
    2374             :   Handle<Smi> slot = args.at<Smi>(2);
    2375             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2376             : 
    2377             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2378      209135 :   if (!maybe_vector->IsUndefined()) {
    2379             :     DCHECK(maybe_vector->IsFeedbackVector());
    2380             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2381             :   }
    2382             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2383      418270 :   KeyedLoadIC ic(isolate, vector, vector_slot, FeedbackSlotKind::kLoadKeyed);
    2384      209135 :   ic.UpdateState(receiver, key);
    2385      418270 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2386             : }
    2387             : 
    2388     3415204 : RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
    2389             :   HandleScope scope(isolate);
    2390             :   DCHECK_EQ(5, args.length());
    2391             :   // Runtime functions don't follow the IC's calling convention.
    2392             :   Handle<Object> value = args.at(0);
    2393             :   Handle<Smi> slot = args.at<Smi>(1);
    2394             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2395             :   Handle<Object> receiver = args.at(3);
    2396             :   Handle<Name> key = args.at<Name>(4);
    2397             : 
    2398             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2399             : 
    2400             :   // When there is no feedback vector it is OK to use the StoreNamedStrict as
    2401             :   // the feedback slot kind. We only need if it is StoreOwnICKind when
    2402             :   // installing the handler for storing const properties. This will happen only
    2403             :   // when feedback vector is available.
    2404             :   FeedbackSlotKind kind = FeedbackSlotKind::kStoreNamedStrict;
    2405             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2406     1707602 :   if (!maybe_vector->IsUndefined()) {
    2407             :     DCHECK(maybe_vector->IsFeedbackVector());
    2408             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2409     1707605 :     kind = vector->GetKind(vector_slot);
    2410             :   }
    2411             : 
    2412             :   DCHECK(IsStoreICKind(kind) || IsStoreOwnICKind(kind));
    2413     3415195 :   StoreIC ic(isolate, vector, vector_slot, kind);
    2414     1707601 :   ic.UpdateState(receiver, key);
    2415     3415188 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2416             : }
    2417             : 
    2418     3416320 : RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Miss) {
    2419             :   HandleScope scope(isolate);
    2420             :   DCHECK_EQ(4, args.length());
    2421             :   // Runtime functions don't follow the IC's calling convention.
    2422             :   Handle<Object> value = args.at(0);
    2423             :   Handle<Smi> slot = args.at<Smi>(1);
    2424     1708160 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2425             :   Handle<Name> key = args.at<Name>(3);
    2426             : 
    2427             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2428     1708160 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2429     3416320 :   StoreGlobalIC ic(isolate, vector, vector_slot, kind);
    2430     1708160 :   Handle<JSGlobalObject> global = isolate->global_object();
    2431     1708160 :   ic.UpdateState(global, key);
    2432     3416320 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value));
    2433             : }
    2434             : 
    2435           0 : RUNTIME_FUNCTION(Runtime_StoreGlobalICNoFeedback_Miss) {
    2436             :   HandleScope scope(isolate);
    2437             :   DCHECK_EQ(2, args.length());
    2438             :   // Runtime functions don't follow the IC's calling convention.
    2439             :   Handle<Object> value = args.at(0);
    2440           0 :   Handle<Name> key = args.at<Name>(1);
    2441             : 
    2442             :   // TODO(mythria): Replace StoreGlobalStrict/Sloppy with StoreNamed.
    2443             :   StoreGlobalIC ic(isolate, Handle<FeedbackVector>(), FeedbackSlot(),
    2444           0 :                    FeedbackSlotKind::kStoreGlobalStrict);
    2445           0 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value));
    2446             : }
    2447             : 
    2448             : // TODO(mythria): Remove Feedback vector and slot. Since they are not used apart
    2449             : // from the DCHECK.
    2450       15780 : RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) {
    2451             :   HandleScope scope(isolate);
    2452             :   DCHECK_EQ(5, args.length());
    2453             :   // Runtime functions don't follow the IC's calling convention.
    2454             :   Handle<Object> value = args.at(0);
    2455        7890 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 4);
    2456             : 
    2457             : #ifdef DEBUG
    2458             :   {
    2459             :     Handle<Smi> slot = args.at<Smi>(1);
    2460             :     Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2461             :     FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2462             :     FeedbackSlotKind slot_kind = vector->GetKind(vector_slot);
    2463             :     DCHECK(IsStoreGlobalICKind(slot_kind));
    2464             :     Handle<Object> receiver = args.at(3);
    2465             :     DCHECK(receiver->IsJSGlobalProxy());
    2466             :   }
    2467             : #endif
    2468             : 
    2469        7890 :   Handle<JSGlobalObject> global = isolate->global_object();
    2470        7890 :   Handle<Context> native_context = isolate->native_context();
    2471             :   Handle<ScriptContextTable> script_contexts(
    2472       15780 :       native_context->script_context_table(), isolate);
    2473             : 
    2474             :   ScriptContextTable::LookupResult lookup_result;
    2475        7890 :   if (ScriptContextTable::Lookup(isolate, *script_contexts, *name,
    2476             :                                  &lookup_result)) {
    2477             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    2478          18 :         isolate, script_contexts, lookup_result.context_index);
    2479          18 :     if (lookup_result.mode == VariableMode::kConst) {
    2480          18 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2481             :           isolate, NewTypeError(MessageTemplate::kConstAssign, global, name));
    2482             :     }
    2483             : 
    2484             :     Handle<Object> previous_value(script_context->get(lookup_result.slot_index),
    2485           9 :                                   isolate);
    2486             : 
    2487           9 :     if (previous_value->IsTheHole(isolate)) {
    2488           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2489             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2490             :     }
    2491             : 
    2492           9 :     script_context->set(lookup_result.slot_index, *value);
    2493             :     return *value;
    2494             :   }
    2495             : 
    2496       15744 :   RETURN_RESULT_OR_FAILURE(
    2497             :       isolate, Runtime::SetObjectProperty(isolate, global, name, value,
    2498             :                                           StoreOrigin::kMaybeKeyed));
    2499             : }
    2500             : 
    2501      329454 : RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
    2502             :   HandleScope scope(isolate);
    2503             :   DCHECK_EQ(5, args.length());
    2504             :   // Runtime functions don't follow the IC's calling convention.
    2505             :   Handle<Object> value = args.at(0);
    2506             :   Handle<Smi> slot = args.at<Smi>(1);
    2507             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2508             :   Handle<Object> receiver = args.at(3);
    2509             :   Handle<Object> key = args.at(4);
    2510             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2511             : 
    2512             :   // When the feedback vector is not valid the slot can only be of type
    2513             :   // StoreKeyed. Storing in array literals falls back to
    2514             :   // StoreInArrayLiterIC_Miss. This function is also used from store handlers
    2515             :   // installed in feedback vectors. In such cases, we need to get the kind from
    2516             :   // feedback vector slot since the handlers are used for both for StoreKeyed
    2517             :   // and StoreInArrayLiteral kinds.
    2518             :   FeedbackSlotKind kind = FeedbackSlotKind::kStoreKeyedStrict;
    2519             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2520      164727 :   if (!maybe_vector->IsUndefined()) {
    2521             :     DCHECK(maybe_vector->IsFeedbackVector());
    2522             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2523      164727 :     kind = vector->GetKind(vector_slot);
    2524             :   }
    2525             : 
    2526             :   // The elements store stubs miss into this function, but they are shared by
    2527             :   // different ICs.
    2528      164727 :   if (IsKeyedStoreICKind(kind)) {
    2529      326484 :     KeyedStoreIC ic(isolate, vector, vector_slot, kind);
    2530      163242 :     ic.UpdateState(receiver, key);
    2531      326484 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2532             :   } else {
    2533             :     DCHECK(IsStoreInArrayLiteralICKind(kind));
    2534             :     DCHECK(receiver->IsJSArray());
    2535             :     DCHECK(key->IsNumber());
    2536        2970 :     StoreInArrayLiteralIC ic(isolate, vector, vector_slot);
    2537        1485 :     ic.UpdateState(receiver, key);
    2538        1485 :     ic.Store(Handle<JSArray>::cast(receiver), key, value);
    2539             :     return *value;
    2540             :   }
    2541             : }
    2542             : 
    2543      365946 : RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Miss) {
    2544             :   HandleScope scope(isolate);
    2545             :   DCHECK_EQ(5, args.length());
    2546             :   // Runtime functions don't follow the IC's calling convention.
    2547             :   Handle<Object> value = args.at(0);
    2548             :   Handle<Smi> slot = args.at<Smi>(1);
    2549             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2550             :   Handle<Object> receiver = args.at(3);
    2551             :   Handle<Object> key = args.at(4);
    2552             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2553      182973 :   if (!maybe_vector->IsUndefined()) {
    2554             :     DCHECK(maybe_vector->IsFeedbackVector());
    2555             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2556             :   }
    2557             :   DCHECK(receiver->IsJSArray());
    2558             :   DCHECK(key->IsNumber());
    2559             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2560      365946 :   StoreInArrayLiteralIC ic(isolate, vector, vector_slot);
    2561      182973 :   ic.Store(Handle<JSArray>::cast(receiver), key, value);
    2562             :   return *value;
    2563             : }
    2564             : 
    2565      633222 : RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
    2566             :   HandleScope scope(isolate);
    2567             :   DCHECK_EQ(3, args.length());
    2568             :   // Runtime functions don't follow the IC's calling convention.
    2569             :   Handle<Object> value = args.at(0);
    2570             :   Handle<Object> object = args.at(1);
    2571             :   Handle<Object> key = args.at(2);
    2572      633222 :   RETURN_RESULT_OR_FAILURE(
    2573             :       isolate, Runtime::SetObjectProperty(isolate, object, key, value,
    2574             :                                           StoreOrigin::kMaybeKeyed));
    2575             : }
    2576             : 
    2577          94 : RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
    2578             :   HandleScope scope(isolate);
    2579             :   DCHECK_EQ(3, args.length());
    2580             :   // Runtime functions don't follow the IC's calling convention.
    2581             :   Handle<Object> value = args.at(0);
    2582             :   Handle<Object> array = args.at(1);
    2583             :   Handle<Object> index = args.at(2);
    2584          47 :   StoreOwnElement(isolate, Handle<JSArray>::cast(array), index, value);
    2585             :   return *value;
    2586             : }
    2587             : 
    2588         430 : RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
    2589             :   HandleScope scope(isolate);
    2590             :   DCHECK_EQ(6, args.length());
    2591             :   // Runtime functions don't follow the IC's calling convention.
    2592             :   Handle<Object> object = args.at(0);
    2593             :   Handle<Object> key = args.at(1);
    2594             :   Handle<Object> value = args.at(2);
    2595             :   Handle<Map> map = args.at<Map>(3);
    2596             :   Handle<Smi> slot = args.at<Smi>(4);
    2597         215 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(5);
    2598             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2599         215 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2600             : 
    2601         215 :   if (object->IsJSObject()) {
    2602         215 :     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
    2603         215 :                                      map->elements_kind());
    2604             :   }
    2605             : 
    2606         215 :   if (IsStoreInArrayLiteralICKind(kind)) {
    2607          75 :     StoreOwnElement(isolate, Handle<JSArray>::cast(object), key, value);
    2608             :     return *value;
    2609             :   } else {
    2610             :     DCHECK(IsKeyedStoreICKind(kind) || IsStoreICKind(kind));
    2611         280 :     RETURN_RESULT_OR_FAILURE(
    2612             :         isolate, Runtime::SetObjectProperty(isolate, object, key, value,
    2613             :                                             StoreOrigin::kMaybeKeyed));
    2614             :   }
    2615             : }
    2616             : 
    2617         567 : static bool CanFastCloneObject(Handle<Map> map) {
    2618             :   DisallowHeapAllocation no_gc;
    2619         567 :   if (map->IsNullOrUndefinedMap()) return true;
    2620        1017 :   if (!map->IsJSObjectMap() ||
    2621         999 :       !IsSmiOrObjectElementsKind(map->elements_kind()) ||
    2622         999 :       !map->OnlyHasSimpleProperties()) {
    2623             :     return false;
    2624             :   }
    2625             : 
    2626         441 :   DescriptorArray descriptors = map->instance_descriptors();
    2627        1539 :   for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    2628         576 :     PropertyDetails details = descriptors->GetDetails(i);
    2629         576 :     Name key = descriptors->GetKey(i);
    2630        1683 :     if (details.kind() != kData || !details.IsEnumerable() ||
    2631         549 :         key->IsPrivateName()) {
    2632          27 :       return false;
    2633             :     }
    2634             :   }
    2635             : 
    2636             :   return true;
    2637             : }
    2638             : 
    2639         441 : static Handle<Map> FastCloneObjectMap(Isolate* isolate,
    2640             :                                       Handle<HeapObject> source, int flags) {
    2641             :   Handle<Map> source_map(source->map(), isolate);
    2642             :   SLOW_DCHECK(source->IsNullOrUndefined() || CanFastCloneObject(source_map));
    2643        1323 :   Handle<JSFunction> constructor(isolate->native_context()->object_function(),
    2644         441 :                                  isolate);
    2645             :   DCHECK(constructor->has_initial_map());
    2646             :   Handle<Map> initial_map(constructor->initial_map(), isolate);
    2647             :   Handle<Map> map = initial_map;
    2648             : 
    2649        1296 :   if (source_map->IsJSObjectMap() && source_map->GetInObjectProperties() !=
    2650         855 :                                          initial_map->GetInObjectProperties()) {
    2651         360 :     int inobject_properties = source_map->GetInObjectProperties();
    2652             :     int instance_size =
    2653         360 :         JSObject::kHeaderSize + kTaggedSize * inobject_properties;
    2654         360 :     int unused = source_map->UnusedInObjectProperties();
    2655             :     DCHECK(instance_size <= JSObject::kMaxInstanceSize);
    2656             :     map = Map::CopyInitialMap(isolate, map, instance_size, inobject_properties,
    2657         360 :                               unused);
    2658             :   }
    2659             : 
    2660         441 :   if (flags & ObjectLiteral::kHasNullPrototype) {
    2661           0 :     if (map.is_identical_to(initial_map)) {
    2662           0 :       map = Map::Copy(isolate, map, "ObjectWithNullProto");
    2663             :     }
    2664           0 :     Map::SetPrototype(isolate, map, isolate->factory()->null_value());
    2665             :   }
    2666             : 
    2667         855 :   if (source->IsNullOrUndefined() || !source_map->NumberOfOwnDescriptors()) {
    2668         126 :     return map;
    2669             :   }
    2670             : 
    2671         315 :   if (map.is_identical_to(initial_map)) {
    2672          18 :     map = Map::Copy(isolate, map, "InitializeClonedDescriptors");
    2673             :   }
    2674             : 
    2675             :   Handle<DescriptorArray> source_descriptors(source_map->instance_descriptors(),
    2676             :                                              isolate);
    2677             :   int size = source_map->NumberOfOwnDescriptors();
    2678             :   int slack = 0;
    2679             :   Handle<DescriptorArray> descriptors = DescriptorArray::CopyForFastObjectClone(
    2680         315 :       isolate, source_descriptors, size, slack);
    2681             :   Handle<LayoutDescriptor> layout =
    2682         315 :       LayoutDescriptor::New(isolate, map, descriptors, size);
    2683         315 :   map->InitializeDescriptors(isolate, *descriptors, *layout);
    2684         315 :   map->CopyUnusedPropertyFieldsAdjustedForInstanceSize(*source_map);
    2685             : 
    2686             :   // Update bitfields
    2687         945 :   map->set_may_have_interesting_symbols(
    2688         315 :       source_map->may_have_interesting_symbols());
    2689             : 
    2690         315 :   return map;
    2691             : }
    2692             : 
    2693         126 : static MaybeHandle<JSObject> CloneObjectSlowPath(Isolate* isolate,
    2694             :                                                  Handle<HeapObject> source,
    2695             :                                                  int flags) {
    2696             :   Handle<JSObject> new_object;
    2697         126 :   if (flags & ObjectLiteral::kHasNullPrototype) {
    2698           0 :     new_object = isolate->factory()->NewJSObjectWithNullProto();
    2699             :   } else {
    2700         378 :     Handle<JSFunction> constructor(isolate->native_context()->object_function(),
    2701         126 :                                    isolate);
    2702         126 :     new_object = isolate->factory()->NewJSObject(constructor);
    2703             :   }
    2704             : 
    2705         126 :   if (source->IsNullOrUndefined()) {
    2706           0 :     return new_object;
    2707             :   }
    2708             : 
    2709         252 :   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, new_object, source,
    2710             :                                                    nullptr, false),
    2711             :                MaybeHandle<JSObject>());
    2712          90 :   return new_object;
    2713             : }
    2714             : 
    2715        1134 : RUNTIME_FUNCTION(Runtime_CloneObjectIC_Miss) {
    2716             :   HandleScope scope(isolate);
    2717             :   DCHECK_EQ(4, args.length());
    2718             :   Handle<HeapObject> source = args.at<HeapObject>(0);
    2719             :   int flags = args.smi_at(1);
    2720             : 
    2721         567 :   MigrateDeprecated(source);
    2722             : 
    2723             :   FeedbackSlot slot = FeedbackVector::ToSlot(args.smi_at(2));
    2724             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2725         567 :   if (maybe_vector->IsUndefined()) {
    2726           0 :     RETURN_RESULT_OR_FAILURE(isolate,
    2727             :                              CloneObjectSlowPath(isolate, source, flags));
    2728             :   }
    2729             : 
    2730             :   DCHECK(maybe_vector->IsFeedbackVector());
    2731         567 :   Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
    2732             : 
    2733             :   FeedbackNexus nexus(vector, slot);
    2734             :   Handle<Map> source_map(source->map(), isolate);
    2735             : 
    2736        1008 :   if (!CanFastCloneObject(source_map) || nexus.IsMegamorphic()) {
    2737             :     // Migrate to slow mode if needed.
    2738         126 :     nexus.ConfigureMegamorphic();
    2739         252 :     RETURN_RESULT_OR_FAILURE(isolate,
    2740             :                              CloneObjectSlowPath(isolate, source, flags));
    2741             :   }
    2742             : 
    2743         441 :   Handle<Map> result_map = FastCloneObjectMap(isolate, source, flags);
    2744         441 :   nexus.ConfigureCloneObject(source_map, result_map);
    2745             : 
    2746             :   return *result_map;
    2747             : }
    2748             : 
    2749      960296 : RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
    2750             :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2751             :   Handle<JSObject> holder = args.at<JSObject>(1);
    2752             :   Handle<AccessorInfo> info = args.at<AccessorInfo>(2);
    2753             :   Handle<Name> name = args.at<Name>(3);
    2754             :   Handle<Object> value = args.at(4);
    2755             :   HandleScope scope(isolate);
    2756             : 
    2757      480148 :   if (V8_UNLIKELY(TracingFlags::is_runtime_stats_enabled())) {
    2758           0 :     RETURN_RESULT_OR_FAILURE(
    2759             :         isolate, Runtime::SetObjectProperty(isolate, receiver, name, value,
    2760             :                                             StoreOrigin::kMaybeKeyed));
    2761             :   }
    2762             : 
    2763             :   DCHECK(info->IsCompatibleReceiver(*receiver));
    2764             : 
    2765             :   PropertyCallbackArguments arguments(isolate, info->data(), *receiver, *holder,
    2766      960296 :                                       Nothing<ShouldThrow>());
    2767      480148 :   arguments.CallAccessorSetter(info, name, value);
    2768      480148 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2769             :   return *value;
    2770             : }
    2771             : 
    2772        7322 : RUNTIME_FUNCTION(Runtime_LoadCallbackProperty) {
    2773             :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2774             :   Handle<JSObject> holder = args.at<JSObject>(1);
    2775             :   Handle<AccessorInfo> info = args.at<AccessorInfo>(2);
    2776             :   Handle<Name> name = args.at<Name>(3);
    2777             :   HandleScope scope(isolate);
    2778             : 
    2779             :   DCHECK(info->IsCompatibleReceiver(*receiver));
    2780             : 
    2781             :   PropertyCallbackArguments custom_args(isolate, info->data(), *receiver,
    2782        2092 :                                         *holder, Just(kThrowOnError));
    2783        1046 :   Handle<Object> result = custom_args.CallAccessorGetter(info, name);
    2784        1046 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2785        1046 :   if (result.is_null()) return ReadOnlyRoots(isolate).undefined_value();
    2786             :   return *result;
    2787             : }
    2788             : 
    2789       28035 : RUNTIME_FUNCTION(Runtime_LoadAccessorProperty) {
    2790             :   HandleScope scope(isolate);
    2791             :   DCHECK_EQ(args.length(), 3);
    2792        4005 :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2793             :   int handler_kind = args.smi_at(1);
    2794        4005 :   Handle<CallHandlerInfo> call_handler_info = args.at<CallHandlerInfo>(2);
    2795             : 
    2796        4005 :   Object holder = *receiver;
    2797        4005 :   if (handler_kind == LoadHandler::kApiGetterHolderIsPrototype) {
    2798           0 :     holder = receiver->map()->prototype();
    2799             :   } else {
    2800             :     DCHECK_EQ(handler_kind, LoadHandler::kApiGetter);
    2801             :   }
    2802             : 
    2803             :   // Call the accessor without additional arguments.
    2804             :   FunctionCallbackArguments custom(isolate, call_handler_info->data(),
    2805        8010 :                                    *receiver, holder, HeapObject(), nullptr, 0);
    2806        4005 :   Handle<Object> result_handle = custom.Call(*call_handler_info);
    2807        4005 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2808        4005 :   if (result_handle.is_null()) return ReadOnlyRoots(isolate).undefined_value();
    2809             :   return *result_handle;
    2810             : }
    2811             : 
    2812             : /**
    2813             :  * Loads a property with an interceptor performing post interceptor
    2814             :  * lookup if interceptor failed.
    2815             :  */
    2816      260742 : RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) {
    2817             :   HandleScope scope(isolate);
    2818             :   DCHECK_EQ(5, args.length());
    2819             :   Handle<Name> name = args.at<Name>(0);
    2820             :   Handle<Object> receiver = args.at(1);
    2821             :   Handle<JSObject> holder = args.at<JSObject>(2);
    2822             : 
    2823      130371 :   if (!receiver->IsJSReceiver()) {
    2824          10 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    2825             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver));
    2826             :   }
    2827             : 
    2828      260742 :   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor(), isolate);
    2829             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2830      130371 :                                       *holder, Just(kDontThrow));
    2831      130371 :   Handle<Object> result = arguments.CallNamedGetter(interceptor, name);
    2832             : 
    2833      130371 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2834             : 
    2835      130359 :   if (!result.is_null()) return *result;
    2836             : 
    2837             :   LookupIterator it(receiver, name, holder);
    2838             :   // Skip any lookup work until we hit the (possibly non-masking) interceptor.
    2839      103086 :   while (it.state() != LookupIterator::INTERCEPTOR ||
    2840             :          !it.GetHolder<JSObject>().is_identical_to(holder)) {
    2841             :     DCHECK(it.state() != LookupIterator::ACCESS_CHECK || it.HasAccess());
    2842           0 :     it.Next();
    2843             :   }
    2844             :   // Skip past the interceptor.
    2845       51543 :   it.Next();
    2846      103086 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
    2847             : 
    2848       51531 :   if (it.IsFound()) return *result;
    2849             : 
    2850             :   Handle<Smi> slot = args.at<Smi>(3);
    2851        6437 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(4);
    2852             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2853        6437 :   FeedbackSlotKind slot_kind = vector->GetKind(vector_slot);
    2854             :   // It could actually be any kind of load IC slot here but the predicate
    2855             :   // handles all the cases properly.
    2856        6437 :   if (!LoadIC::ShouldThrowReferenceError(slot_kind)) {
    2857             :     return ReadOnlyRoots(isolate).undefined_value();
    2858             :   }
    2859             : 
    2860             :   // Throw a reference error.
    2861         264 :   THROW_NEW_ERROR_RETURN_FAILURE(
    2862             :       isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
    2863             : }
    2864             : 
    2865     1092692 : RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
    2866             :   HandleScope scope(isolate);
    2867             :   DCHECK_EQ(5, args.length());
    2868             :   // Runtime functions don't follow the IC's calling convention.
    2869             :   Handle<Object> value = args.at(0);
    2870             :   Handle<Smi> slot = args.at<Smi>(1);
    2871      546346 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2872             :   Handle<JSObject> receiver = args.at<JSObject>(3);
    2873             :   Handle<Name> name = args.at<Name>(4);
    2874             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2875             : 
    2876             :   // TODO(ishell): Cache interceptor_holder in the store handler like we do
    2877             :   // for LoadHandler::kInterceptor case.
    2878             :   Handle<JSObject> interceptor_holder = receiver;
    2879      546346 :   if (receiver->IsJSGlobalProxy()) {
    2880         294 :     FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2881         294 :     if (IsStoreGlobalICKind(kind)) {
    2882         294 :       interceptor_holder = Handle<JSObject>::cast(isolate->global_object());
    2883             :     }
    2884             :   }
    2885             :   DCHECK(interceptor_holder->HasNamedInterceptor());
    2886             :   Handle<InterceptorInfo> interceptor(interceptor_holder->GetNamedInterceptor(),
    2887     1092692 :                                       isolate);
    2888             : 
    2889             :   DCHECK(!interceptor->non_masking());
    2890             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2891     1092692 :                                       *receiver, Just(kDontThrow));
    2892             : 
    2893      546346 :   Handle<Object> result = arguments.CallNamedSetter(interceptor, name, value);
    2894      546346 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2895      546340 :   if (!result.is_null()) return *value;
    2896             : 
    2897             :   LookupIterator it(receiver, name, receiver);
    2898             :   // Skip past any access check on the receiver.
    2899      300294 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    2900             :     DCHECK(it.HasAccess());
    2901         288 :     it.Next();
    2902             :   }
    2903             :   // Skip past the interceptor on the receiver.
    2904             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
    2905      300294 :   it.Next();
    2906             : 
    2907      600588 :   MAYBE_RETURN(Object::SetProperty(&it, value, StoreOrigin::kNamed),
    2908             :                ReadOnlyRoots(isolate).exception());
    2909             :   return *value;
    2910             : }
    2911             : 
    2912        4476 : RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) {
    2913             :   // TODO(verwaest): This should probably get the holder and receiver as input.
    2914             :   HandleScope scope(isolate);
    2915             :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2916             :   DCHECK_GE(args.smi_at(1), 0);
    2917        2238 :   uint32_t index = args.smi_at(1);
    2918             : 
    2919             :   Handle<InterceptorInfo> interceptor(receiver->GetIndexedInterceptor(),
    2920        4476 :                                       isolate);
    2921             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2922        4476 :                                       *receiver, Just(kDontThrow));
    2923        2238 :   Handle<Object> result = arguments.CallIndexedGetter(interceptor, index);
    2924             : 
    2925        2238 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2926             : 
    2927        2238 :   if (result.is_null()) {
    2928             :     LookupIterator it(isolate, receiver, index, receiver);
    2929             :     DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
    2930           0 :     it.Next();
    2931           0 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    2932             :                                        Object::GetProperty(&it));
    2933             :   }
    2934             : 
    2935             :   return *result;
    2936             : }
    2937             : 
    2938       10934 : RUNTIME_FUNCTION(Runtime_KeyedHasIC_Miss) {
    2939             :   HandleScope scope(isolate);
    2940             :   DCHECK_EQ(4, args.length());
    2941             :   // Runtime functions don't follow the IC's calling convention.
    2942             :   Handle<Object> receiver = args.at(0);
    2943             :   Handle<Object> key = args.at(1);
    2944             :   Handle<Smi> slot = args.at<Smi>(2);
    2945             :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2946             : 
    2947             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2948        5467 :   if (!maybe_vector->IsUndefined()) {
    2949             :     DCHECK(maybe_vector->IsFeedbackVector());
    2950             :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2951             :   }
    2952             :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2953       10934 :   KeyedLoadIC ic(isolate, vector, vector_slot, FeedbackSlotKind::kHasKeyed);
    2954        5467 :   ic.UpdateState(receiver, key);
    2955       10934 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2956             : }
    2957             : 
    2958       59940 : RUNTIME_FUNCTION(Runtime_HasElementWithInterceptor) {
    2959             :   HandleScope scope(isolate);
    2960             :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2961             :   DCHECK_GE(args.smi_at(1), 0);
    2962       29970 :   uint32_t index = args.smi_at(1);
    2963             : 
    2964             :   Handle<InterceptorInfo> interceptor(receiver->GetIndexedInterceptor(),
    2965       59940 :                                       isolate);
    2966             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2967       59940 :                                       *receiver, Just(kDontThrow));
    2968             : 
    2969       29970 :   if (!interceptor->query()->IsUndefined(isolate)) {
    2970       24975 :     Handle<Object> result = arguments.CallIndexedQuery(interceptor, index);
    2971       24975 :     if (!result.is_null()) {
    2972             :       int32_t value;
    2973       19980 :       CHECK(result->ToInt32(&value));
    2974       19980 :       return value == ABSENT ? ReadOnlyRoots(isolate).false_value()
    2975       19980 :                              : ReadOnlyRoots(isolate).true_value();
    2976             :     }
    2977        4995 :   } else if (!interceptor->getter()->IsUndefined(isolate)) {
    2978        4995 :     Handle<Object> result = arguments.CallIndexedGetter(interceptor, index);
    2979        4995 :     if (!result.is_null()) {
    2980             :       return ReadOnlyRoots(isolate).true_value();
    2981             :     }
    2982             :   }
    2983             : 
    2984             :   LookupIterator it(isolate, receiver, index, receiver);
    2985             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
    2986        4995 :   it.Next();
    2987        4995 :   Maybe<bool> maybe = JSReceiver::HasProperty(&it);
    2988        4995 :   if (maybe.IsNothing()) return ReadOnlyRoots(isolate).exception();
    2989             :   return maybe.FromJust() ? ReadOnlyRoots(isolate).true_value()
    2990        4995 :                           : ReadOnlyRoots(isolate).false_value();
    2991             : }
    2992             : 
    2993             : }  // namespace internal
    2994      120216 : }  // namespace v8

Generated by: LCOV version 1.10