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

Generated by: LCOV version 1.10