LCOV - code coverage report
Current view: top level - src/ic - ic.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1122 1278 87.8 %
Date: 2019-01-20 Functions: 79 107 73.8 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/ic/ic.h"
       6             : 
       7             : #include "src/accessors.h"
       8             : #include "src/api-arguments-inl.h"
       9             : #include "src/api.h"
      10             : #include "src/arguments-inl.h"
      11             : #include "src/ast/ast.h"
      12             : #include "src/base/bits.h"
      13             : #include "src/code-factory.h"
      14             : #include "src/conversions.h"
      15             : #include "src/execution.h"
      16             : #include "src/field-type.h"
      17             : #include "src/frames-inl.h"
      18             : #include "src/handles-inl.h"
      19             : #include "src/ic/call-optimization.h"
      20             : #include "src/ic/handler-configuration-inl.h"
      21             : #include "src/ic/ic-inl.h"
      22             : #include "src/ic/ic-stats.h"
      23             : #include "src/ic/stub-cache.h"
      24             : #include "src/isolate-inl.h"
      25             : #include "src/objects/api-callbacks.h"
      26             : #include "src/objects/data-handler-inl.h"
      27             : #include "src/objects/hash-table-inl.h"
      28             : #include "src/objects/heap-number-inl.h"
      29             : #include "src/objects/js-array-inl.h"
      30             : #include "src/objects/module-inl.h"
      31             : #include "src/objects/struct-inl.h"
      32             : #include "src/prototype.h"
      33             : #include "src/runtime-profiler.h"
      34             : #include "src/runtime/runtime-utils.h"
      35             : #include "src/runtime/runtime.h"
      36             : #include "src/tracing/trace-event.h"
      37             : #include "src/tracing/tracing-category-observer.h"
      38             : 
      39             : namespace v8 {
      40             : namespace internal {
      41             : 
      42           0 : char IC::TransitionMarkFromState(IC::State state) {
      43           0 :   switch (state) {
      44             :     case NO_FEEDBACK:
      45           0 :       UNREACHABLE();
      46             :     case UNINITIALIZED:
      47             :       return '0';
      48             :     case PREMONOMORPHIC:
      49           0 :       return '.';
      50             :     case MONOMORPHIC:
      51           0 :       return '1';
      52             :     case RECOMPUTE_HANDLER:
      53           0 :       return '^';
      54             :     case POLYMORPHIC:
      55           0 :       return 'P';
      56             :     case MEGAMORPHIC:
      57           0 :       return 'N';
      58             :     case GENERIC:
      59           0 :       return 'G';
      60             :   }
      61           0 :   UNREACHABLE();
      62             : }
      63             : 
      64             : namespace {
      65             : 
      66             : const char* GetModifier(KeyedAccessLoadMode mode) {
      67           0 :   if (mode == LOAD_IGNORE_OUT_OF_BOUNDS) return ".IGNORE_OOB";
      68             :   return "";
      69             : }
      70             : 
      71             : const char* GetModifier(KeyedAccessStoreMode mode) {
      72           0 :   switch (mode) {
      73             :     case STORE_NO_TRANSITION_HANDLE_COW:
      74             :       return ".COW";
      75             :     case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
      76             :       return ".STORE+COW";
      77             :     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
      78             :       return ".IGNORE_OOB";
      79             :     default:
      80             :       break;
      81             :   }
      82             :   DCHECK(!IsCOWHandlingStoreMode(mode));
      83           0 :   return IsGrowStoreMode(mode) ? ".GROW" : "";
      84             : }
      85             : 
      86             : }  // namespace
      87             : 
      88     6584845 : void IC::TraceIC(const char* type, Handle<Object> name) {
      89     6584845 :   if (FLAG_ic_stats) {
      90     6584845 :     if (AddressIsDeoptimizedCode()) return;
      91           0 :     State new_state = nexus()->StateFromFeedback();
      92           0 :     TraceIC(type, name, state(), new_state);
      93             :   }
      94             : }
      95             : 
      96           0 : void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
      97           0 :                  State new_state) {
      98           0 :   if (V8_LIKELY(!FLAG_ic_stats)) return;
      99             : 
     100           0 :   Map map;
     101           0 :   if (!receiver_map().is_null()) {
     102           0 :     map = *receiver_map();
     103             :   }
     104             : 
     105             :   const char* modifier = "";
     106           0 :   if (IsKeyedLoadIC()) {
     107           0 :     KeyedAccessLoadMode mode = nexus()->GetKeyedAccessLoadMode();
     108             :     modifier = GetModifier(mode);
     109           0 :   } else if (IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind())) {
     110           0 :     KeyedAccessStoreMode mode = nexus()->GetKeyedAccessStoreMode();
     111             :     modifier = GetModifier(mode);
     112             :   }
     113             : 
     114           0 :   bool keyed_prefix = is_keyed() && !IsStoreInArrayLiteralICKind(kind());
     115             : 
     116           0 :   if (!(FLAG_ic_stats &
     117             :         v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING)) {
     118           0 :     LOG(isolate(), ICEvent(type, keyed_prefix, map, *name,
     119             :                            TransitionMarkFromState(old_state),
     120             :                            TransitionMarkFromState(new_state), modifier,
     121             :                            slow_stub_reason_));
     122             :     return;
     123             :   }
     124             : 
     125           0 :   ICStats::instance()->Begin();
     126             :   ICInfo& ic_info = ICStats::instance()->Current();
     127           0 :   ic_info.type = keyed_prefix ? "Keyed" : "";
     128             :   ic_info.type += type;
     129             : 
     130             :   Object maybe_function =
     131           0 :       Object(Memory<Address>(fp_ + JavaScriptFrameConstants::kFunctionOffset));
     132             :   DCHECK(maybe_function->IsJSFunction());
     133           0 :   JSFunction function = JSFunction::cast(maybe_function);
     134             :   int code_offset = 0;
     135           0 :   if (function->IsInterpreted()) {
     136           0 :     code_offset = InterpretedFrame::GetBytecodeOffset(fp());
     137             :   } else {
     138           0 :     code_offset = static_cast<int>(pc() - function->code()->InstructionStart());
     139             :   }
     140             :   JavaScriptFrame::CollectFunctionAndOffsetForICStats(
     141           0 :       function, function->abstract_code(), code_offset);
     142             : 
     143             :   // Reserve enough space for IC transition state, the longest length is 17.
     144           0 :   ic_info.state.reserve(17);
     145             :   ic_info.state = "(";
     146           0 :   ic_info.state += TransitionMarkFromState(old_state);
     147             :   ic_info.state += "->";
     148           0 :   ic_info.state += TransitionMarkFromState(new_state);
     149             :   ic_info.state += modifier;
     150             :   ic_info.state += ")";
     151           0 :   ic_info.map = reinterpret_cast<void*>(map.ptr());
     152           0 :   if (!map.is_null()) {
     153           0 :     ic_info.is_dictionary_map = map->is_dictionary_map();
     154           0 :     ic_info.number_of_own_descriptors = map->NumberOfOwnDescriptors();
     155           0 :     ic_info.instance_type = std::to_string(map->instance_type());
     156             :   }
     157             :   // TODO(lpy) Add name as key field in ICStats.
     158           0 :   ICStats::instance()->End();
     159             : }
     160             : 
     161     6853607 : IC::IC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot,
     162             :        FeedbackSlotKind kind)
     163             :     : isolate_(isolate),
     164             :       vector_set_(false),
     165             :       kind_(kind),
     166             :       target_maps_set_(false),
     167             :       slow_stub_reason_(nullptr),
     168    13707214 :       nexus_(vector, slot) {
     169             :   // To improve the performance of the (much used) IC code, we unfold a few
     170             :   // levels of the stack frame iteration code. This yields a ~35% speedup when
     171             :   // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
     172     6853648 :   const Address entry = Isolate::c_entry_fp(isolate->thread_local_top());
     173             :   Address* constant_pool = nullptr;
     174             :   if (FLAG_enable_embedded_constant_pool) {
     175             :     constant_pool = reinterpret_cast<Address*>(
     176             :         entry + ExitFrameConstants::kConstantPoolOffset);
     177             :   }
     178             :   Address* pc_address =
     179     6853648 :       reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
     180     6853648 :   Address fp = Memory<Address>(entry + ExitFrameConstants::kCallerFPOffset);
     181             : #ifdef DEBUG
     182             :   StackFrameIterator it(isolate);
     183             :   for (int i = 0; i < 1; i++) it.Advance();
     184             :   StackFrame* frame = it.frame();
     185             :   DCHECK(fp == frame->fp() && pc_address == frame->pc_address());
     186             : #endif
     187             :   // For interpreted functions, some bytecode handlers construct a
     188             :   // frame. We have to skip the constructed frame to find the interpreted
     189             :   // function's frame. Check if the there is an additional frame, and if there
     190             :   // is skip this frame. However, the pc should not be updated. The call to
     191             :   // ICs happen from bytecode handlers.
     192             :   intptr_t frame_marker =
     193    13707296 :       Memory<intptr_t>(fp + TypedFrameConstants::kFrameTypeOffset);
     194     6853648 :   if (frame_marker == StackFrame::TypeToMarker(StackFrame::STUB)) {
     195     6161433 :     fp = Memory<Address>(fp + TypedFrameConstants::kCallerFPOffset);
     196             :   }
     197     6853648 :   fp_ = fp;
     198             :   if (FLAG_enable_embedded_constant_pool) {
     199             :     constant_pool_address_ = constant_pool;
     200             :   }
     201     6853648 :   pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
     202             :   DCHECK_IMPLIES(!vector.is_null(), kind_ == nexus_.kind());
     203     6853648 :   state_ = (vector.is_null()) ? NO_FEEDBACK : nexus_.StateFromFeedback();
     204     6853613 :   old_state_ = state_;
     205     6853613 : }
     206             : 
     207     9522033 : JSFunction IC::GetHostFunction() const {
     208             :   // Compute the JavaScript frame for the frame pointer of this IC
     209             :   // structure. We need this to be able to find the function
     210             :   // corresponding to the frame.
     211     2450144 :   StackFrameIterator it(isolate());
     212     9522041 :   while (it.frame()->fp() != this->fp()) it.Advance();
     213             :   JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
     214             :   // Find the function on the stack and both the active code for the
     215             :   // function and the original code.
     216     4900379 :   return frame->function();
     217             : }
     218             : 
     219     6739621 : static void LookupForRead(Isolate* isolate, LookupIterator* it) {
     220     6763911 :   for (; it->IsFound(); it->Next()) {
     221     3133004 :     switch (it->state()) {
     222             :       case LookupIterator::NOT_FOUND:
     223             :       case LookupIterator::TRANSITION:
     224           0 :         UNREACHABLE();
     225             :       case LookupIterator::JSPROXY:
     226             :         return;
     227             :       case LookupIterator::INTERCEPTOR: {
     228             :         // If there is a getter, return; otherwise loop to perform the lookup.
     229             :         Handle<JSObject> holder = it->GetHolder<JSObject>();
     230        2708 :         if (!holder->GetNamedInterceptor()->getter()->IsUndefined(isolate)) {
     231             :           return;
     232             :         }
     233             :         break;
     234             :       }
     235             :       case LookupIterator::ACCESS_CHECK:
     236             :         // ICs know how to perform access checks on global proxies.
     237       48700 :         if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && it->HasAccess()) {
     238             :           break;
     239             :         }
     240             :         return;
     241             :       case LookupIterator::ACCESSOR:
     242             :       case LookupIterator::INTEGER_INDEXED_EXOTIC:
     243             :       case LookupIterator::DATA:
     244             :         return;
     245             :     }
     246             :   }
     247             : }
     248             : 
     249      616553 : bool IC::ShouldRecomputeHandler(Handle<String> name) {
     250      387972 :   if (!RecomputeHandlerForName(name)) return false;
     251             : 
     252             :   // This is a contextual access, always just update the handler and stay
     253             :   // monomorphic.
     254      379857 :   if (IsGlobalIC()) return true;
     255             : 
     256      350519 :   maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
     257             : 
     258             :   // The current map wasn't handled yet. There's no reason to stay monomorphic,
     259             :   // *unless* we're moving from a deprecated map to its replacement, or
     260             :   // to a more general elements kind.
     261             :   // TODO(verwaest): Check if the current map is actually what the old map
     262             :   // would transition to.
     263      350518 :   if (maybe_handler_.is_null()) {
     264      337232 :     if (!receiver_map()->IsJSObjectMap()) return false;
     265      329281 :     Map first_map = FirstTargetMap();
     266      329282 :     if (first_map.is_null()) return false;
     267             :     Handle<Map> old_map(first_map, isolate());
     268      228580 :     if (old_map->is_deprecated()) return true;
     269             :     return IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
     270      444418 :                                                receiver_map()->elements_kind());
     271             :   }
     272             : 
     273             :   return true;
     274             : }
     275             : 
     276      387973 : bool IC::RecomputeHandlerForName(Handle<Object> name) {
     277      387973 :   if (is_keyed()) {
     278             :     // Determine whether the failure is due to a name failure.
     279       27841 :     if (!name->IsName()) return false;
     280        9863 :     Name stub_name = nexus()->FindFirstName();
     281        9863 :     if (*name != stub_name) return false;
     282             :   }
     283             : 
     284             :   return true;
     285             : }
     286             : 
     287             : 
     288    13400378 : void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
     289     6684306 :   if (state() == NO_FEEDBACK) return;
     290     6684313 :   update_receiver_map(receiver);
     291    13368700 :   if (!name->IsString()) return;
     292     6327980 :   if (state() != MONOMORPHIC && state() != POLYMORPHIC) return;
     293      776182 :   if (receiver->IsNullOrUndefined(isolate())) return;
     294             : 
     295             :   // Remove the target from the code cache if it became invalid
     296             :   // because of changes in the prototype chain to avoid hitting it
     297             :   // again.
     298      387971 :   if (ShouldRecomputeHandler(Handle<String>::cast(name))) {
     299             :     MarkRecomputeHandler(name);
     300             :   }
     301             : }
     302             : 
     303        1383 : MaybeHandle<Object> IC::TypeError(MessageTemplate index, Handle<Object> object,
     304        2766 :                                   Handle<Object> key) {
     305             :   HandleScope scope(isolate());
     306        2766 :   THROW_NEW_ERROR(isolate(), NewTypeError(index, key, object), Object);
     307             : }
     308             : 
     309             : 
     310      344664 : MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) {
     311             :   HandleScope scope(isolate());
     312      344664 :   THROW_NEW_ERROR(
     313             :       isolate(), NewReferenceError(MessageTemplate::kNotDefined, name), Object);
     314             : }
     315             : 
     316             : // static
     317     2450185 : void IC::OnFeedbackChanged(Isolate* isolate, FeedbackNexus* nexus,
     318             :                            JSFunction host_function, const char* reason) {
     319     2450185 :   FeedbackVector vector = nexus->vector();
     320     2450185 :   FeedbackSlot slot = nexus->slot();
     321     2450185 :   OnFeedbackChanged(isolate, vector, slot, host_function, reason);
     322     2450182 : }
     323             : 
     324             : // static
     325     4955316 : void IC::OnFeedbackChanged(Isolate* isolate, FeedbackVector vector,
     326             :                            FeedbackSlot slot, JSFunction host_function,
     327             :                            const char* reason) {
     328     2477658 :   if (FLAG_trace_opt_verbose) {
     329             :     // TODO(leszeks): The host function is only needed for this print, we could
     330             :     // remove it as a parameter if we're of with removing this trace (or only
     331             :     // tracing the feedback vector, not the function name).
     332           0 :     if (vector->profiler_ticks() != 0) {
     333           0 :       PrintF("[resetting ticks for ");
     334           0 :       host_function->ShortPrint();
     335             :       PrintF(" due from %d due to IC change: %s]\n", vector->profiler_ticks(),
     336           0 :              reason);
     337             :     }
     338             :   }
     339             :   vector->set_profiler_ticks(0);
     340             : 
     341             : #ifdef V8_TRACE_FEEDBACK_UPDATES
     342             :   if (FLAG_trace_feedback_updates) {
     343             :     int slot_count = vector->metadata()->slot_count();
     344             : 
     345             :     StdoutStream os;
     346             :     if (slot.IsInvalid()) {
     347             :       os << "[Feedback slots in ";
     348             :     } else {
     349             :       os << "[Feedback slot " << slot.ToInt() << "/" << slot_count << " in ";
     350             :     }
     351             :     vector->shared_function_info()->ShortPrint(os);
     352             :     if (slot.IsInvalid()) {
     353             :       os << " updated - ";
     354             :     } else {
     355             :       os << " updated to ";
     356             :       vector->FeedbackSlotPrint(os, slot);
     357             :       os << " - ";
     358             :     }
     359             :     os << reason << "]" << std::endl;
     360             :   }
     361             : #endif
     362             : 
     363             :   isolate->runtime_profiler()->NotifyICChanged();
     364             :   // TODO(2029): When an optimized function is patched, it would
     365             :   // be nice to propagate the corresponding type information to its
     366             :   // unoptimized version for the benefit of later inlining.
     367     2477658 : }
     368             : 
     369     6859192 : static bool MigrateDeprecated(Handle<Object> object) {
     370    13718437 :   if (!object->IsJSObject()) return false;
     371     6754369 :   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
     372     6754367 :   if (!receiver->map()->is_deprecated()) return false;
     373        1599 :   JSObject::MigrateInstance(Handle<JSObject>::cast(object));
     374        1599 :   return true;
     375             : }
     376             : 
     377       93378 : bool IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
     378             :   DCHECK_EQ(MEGAMORPHIC, new_state);
     379             :   DCHECK_IMPLIES(!is_keyed(), key->IsName());
     380             :   // Even though we don't change the feedback data, we still want to reset the
     381             :   // profiler ticks. Real-world observations suggest that optimizing these
     382             :   // functions doesn't improve performance.
     383             :   bool changed =
     384       93378 :       nexus()->ConfigureMegamorphic(key->IsName() ? PROPERTY : ELEMENT);
     385       46689 :   vector_set_ = true;
     386       93378 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Megamorphic");
     387       46689 :   return changed;
     388             : }
     389             : 
     390     1116527 : void IC::ConfigureVectorState(Handle<Map> map) {
     391      558254 :   nexus()->ConfigurePremonomorphic(map);
     392      558273 :   vector_set_ = true;
     393     1116546 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Premonomorphic");
     394      558272 : }
     395             : 
     396           0 : void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
     397             :                               Handle<Object> handler) {
     398      329798 :   ConfigureVectorState(name, map, MaybeObjectHandle(handler));
     399           0 : }
     400             : 
     401     1613347 : void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
     402     3226736 :                               const MaybeObjectHandle& handler) {
     403     1613347 :   if (IsGlobalIC()) {
     404       44756 :     nexus()->ConfigureHandlerMode(handler);
     405             :   } else {
     406             :     // Non-keyed ICs don't track the name explicitly.
     407     1568591 :     if (!is_keyed()) name = Handle<Name>::null();
     408     1568591 :     nexus()->ConfigureMonomorphic(name, map, handler);
     409             :   }
     410             : 
     411     1613364 :   vector_set_ = true;
     412             :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(),
     413     3226736 :                     IsLoadGlobalIC() ? "LoadGlobal" : "Monomorphic");
     414     1613370 : }
     415             : 
     416      231848 : void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
     417      231853 :                               MaybeObjectHandles* handlers) {
     418             :   DCHECK(!IsGlobalIC());
     419             :   // Non-keyed ICs don't track the name explicitly.
     420      231848 :   if (!is_keyed()) name = Handle<Name>::null();
     421      231848 :   nexus()->ConfigurePolymorphic(name, maps, handlers);
     422             : 
     423      231854 :   vector_set_ = true;
     424      463707 :   OnFeedbackChanged(isolate(), nexus(), GetHostFunction(), "Polymorphic");
     425      231854 : }
     426             : 
     427     3358695 : MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
     428    14771895 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
     429             : 
     430             :   // If the object is undefined or null it's illegal to try to get any
     431             :   // of its properties; throw a TypeError in that case.
     432     6717406 :   if (object->IsNullOrUndefined(isolate())) {
     433        2052 :     if (use_ic && state() != PREMONOMORPHIC) {
     434             :       // Ensure the IC state progresses.
     435         963 :       TRACE_HANDLER_STATS(isolate(), LoadIC_NonReceiver);
     436         963 :       update_receiver_map(object);
     437         963 :       PatchCache(name, slow_stub());
     438         963 :       TraceIC("LoadIC", name);
     439             :     }
     440             : 
     441        1026 :     if (*name == ReadOnlyRoots(isolate()).iterator_symbol()) {
     442         167 :       return Runtime::ThrowIteratorError(isolate(), object);
     443             :     }
     444         859 :     return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name);
     445             :   }
     446             : 
     447     3357677 :   if (MigrateDeprecated(object)) use_ic = false;
     448             : 
     449     3357680 :   if (state() != UNINITIALIZED) {
     450     1260584 :     JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate());
     451     1260572 :     update_receiver_map(object);
     452             :   }
     453             :   // Named lookup in the object.
     454     3357672 :   LookupIterator it(isolate(), object, name);
     455     3357675 :   LookupForRead(isolate(), &it);
     456             : 
     457     3357669 :   if (name->IsPrivate()) {
     458       15467 :     if (name->IsPrivateName() && !it.IsFound()) {
     459             :       Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
     460         594 :                                  isolate());
     461             :       return TypeError(MessageTemplate::kInvalidPrivateFieldRead, object,
     462         297 :                        name_string);
     463             :     }
     464             : 
     465             :     // IC handling of private symbols/fields lookup on JSProxy is not
     466             :     // supported.
     467       30340 :     if (object->IsJSProxy()) {
     468             :       use_ic = false;
     469             :     }
     470             :   }
     471             : 
     472     3606015 :   if (it.IsFound() || !ShouldThrowReferenceError()) {
     473             :     // Update inline cache and stub cache.
     474     3185675 :     if (use_ic) UpdateCaches(&it);
     475             : 
     476             :     // Get the property.
     477             :     Handle<Object> result;
     478             : 
     479     6371390 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
     480             :                                Object);
     481     3184585 :     if (it.IsFound()) {
     482     3107399 :       return result;
     483       77186 :     } else if (!ShouldThrowReferenceError()) {
     484       77073 :       LOG(isolate(), SuspectReadEvent(*name, *object));
     485       77073 :       return result;
     486             :     }
     487             :   }
     488      171802 :   return ReferenceError(name);
     489             : }
     490             : 
     491     2072876 : MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) {
     492     6517537 :   Handle<JSGlobalObject> global = isolate()->global_object();
     493             : 
     494     4145735 :   if (name->IsString()) {
     495             :     // Look up in script context table.
     496     2072869 :     Handle<String> str_name = Handle<String>::cast(name);
     497             :     Handle<ScriptContextTable> script_contexts(
     498     4145738 :         global->native_context()->script_context_table(), isolate());
     499             : 
     500             :     ScriptContextTable::LookupResult lookup_result;
     501     2072871 :     if (ScriptContextTable::Lookup(isolate(), script_contexts, str_name,
     502             :                                    &lookup_result)) {
     503             :       Handle<Context> script_context = ScriptContextTable::GetContext(
     504      149718 :           isolate(), script_contexts, lookup_result.context_index);
     505             : 
     506             :       Handle<Object> result(script_context->get(lookup_result.slot_index),
     507      224576 :                             isolate());
     508             : 
     509      149719 :       if (result->IsTheHole(isolate())) {
     510             :         // Do not install stubs and stay pre-monomorphic for
     511             :         // uninitialized accesses.
     512         515 :         return ReferenceError(name);
     513             :       }
     514             : 
     515       74346 :       bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
     516       74346 :       if (use_ic) {
     517       74345 :         if (nexus()->ConfigureLexicalVarMode(lookup_result.context_index,
     518       74345 :                                              lookup_result.slot_index)) {
     519       74344 :           TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_LoadScriptContextField);
     520             :         } else {
     521             :           // Given combination of indices can't be encoded, so use slow stub.
     522           0 :           TRACE_HANDLER_STATS(isolate(), LoadGlobalIC_SlowStub);
     523           0 :           PatchCache(name, slow_stub());
     524             :         }
     525       74344 :         TraceIC("LoadGlobalIC", name);
     526             :       }
     527       74342 :       return result;
     528             :     }
     529             :   }
     530     1998013 :   return LoadIC::Load(global, name);
     531             : }
     532             : 
     533       23533 : static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
     534             :                                        Handle<Map> new_receiver_map) {
     535             :   DCHECK(!new_receiver_map.is_null());
     536       82923 :   for (Handle<Map> map : *receiver_maps) {
     537       80124 :     if (!map.is_null() && map.is_identical_to(new_receiver_map)) {
     538             :       return false;
     539             :     }
     540             :   }
     541       19328 :   receiver_maps->push_back(new_receiver_map);
     542       19328 :   return true;
     543             : }
     544             : 
     545      363003 : bool IC::UpdatePolymorphicIC(Handle<Name> name,
     546      114132 :                              const MaybeObjectHandle& handler) {
     547             :   DCHECK(IsHandler(*handler));
     548      376073 :   if (is_keyed() && state() != RECOMPUTE_HANDLER) {
     549       25828 :     if (nexus()->FindFirstName() != *name) return false;
     550             :   }
     551      354555 :   Handle<Map> map = receiver_map();
     552             :   MapHandles maps;
     553             :   MaybeObjectHandles handlers;
     554             : 
     555      354555 :   TargetMaps(&maps);
     556      709140 :   int number_of_maps = static_cast<int>(maps.size());
     557             :   int deprecated_maps = 0;
     558             :   int handler_to_overwrite = -1;
     559      354570 :   if (!nexus()->FindHandlers(&handlers, number_of_maps)) return false;
     560             : 
     561      405369 :   for (int i = 0; i < number_of_maps; i++) {
     562      810799 :     Handle<Map> current_map = maps.at(i);
     563      405404 :     if (current_map->is_deprecated()) {
     564             :       // Filter out deprecated maps to ensure their instances get migrated.
     565        8285 :       ++deprecated_maps;
     566      397119 :     } else if (map.is_identical_to(current_map)) {
     567             :       // If both map and handler stayed the same (and the name is also the
     568             :       // same as checked above, for keyed accesses), we're not progressing
     569             :       // in the lattice and need to go MEGAMORPHIC instead. There's one
     570             :       // exception to this rule, which is when we're in RECOMPUTE_HANDLER
     571             :       // state, there we allow to migrate to a new handler.
     572       25723 :       if (handler.is_identical_to(handlers[i]) &&
     573             :           state() != RECOMPUTE_HANDLER) {
     574             :         return false;
     575             :       }
     576             :       // If the receiver type is already in the polymorphic IC, this indicates
     577             :       // there was a prototoype chain failure. In that case, just overwrite the
     578             :       // handler.
     579             :       handler_to_overwrite = i;
     580      768100 :     } else if (handler_to_overwrite == -1 &&
     581      383663 :                IsTransitionOfMonomorphicTarget(*current_map, *map)) {
     582             :       handler_to_overwrite = i;
     583             :     }
     584             :   }
     585             : 
     586             :   int number_of_valid_maps =
     587      354213 :       number_of_maps - deprecated_maps - (handler_to_overwrite != -1);
     588             : 
     589      354213 :   if (number_of_valid_maps >= kMaxPolymorphicMapCount) return false;
     590      441660 :   if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
     591             :     return false;
     592             :   }
     593             : 
     594             :   number_of_valid_maps++;
     595      340955 :   if (number_of_valid_maps == 1) {
     596      125765 :     ConfigureVectorState(name, receiver_map(), handler);
     597             :   } else {
     598      222462 :     if (is_keyed() && nexus()->FindFirstName() != *name) return false;
     599      215185 :     if (handler_to_overwrite >= 0) {
     600        3018 :       handlers[handler_to_overwrite] = handler;
     601        1509 :       if (!map.is_identical_to(maps.at(handler_to_overwrite))) {
     602        1127 :         maps[handler_to_overwrite] = map;
     603             :       }
     604             :     } else {
     605      213676 :       maps.push_back(map);
     606      213679 :       handlers.push_back(handler);
     607             :     }
     608             : 
     609      215190 :     ConfigureVectorState(name, maps, &handlers);
     610             :   }
     611             : 
     612             :   return true;
     613             : }
     614             : 
     615           0 : void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler,
     616             :                              Handle<Name> name) {
     617             :   DCHECK(IsHandler(*handler));
     618     1157247 :   ConfigureVectorState(name, receiver_map(), handler);
     619           0 : }
     620             : 
     621             : 
     622       12845 : void IC::CopyICToMegamorphicCache(Handle<Name> name) {
     623             :   MapHandles maps;
     624             :   MaybeObjectHandles handlers;
     625       12845 :   TargetMaps(&maps);
     626       38535 :   if (!nexus()->FindHandlers(&handlers, static_cast<int>(maps.size()))) return;
     627      113152 :   for (int i = 0; i < static_cast<int>(maps.size()); i++) {
     628      100621 :     UpdateMegamorphicCache(maps.at(i), name, handlers.at(i));
     629             :   }
     630             : }
     631             : 
     632      406334 : bool IC::IsTransitionOfMonomorphicTarget(Map source_map, Map target_map) {
     633      391224 :   if (source_map.is_null()) return true;
     634      391227 :   if (target_map.is_null()) return false;
     635      391231 :   if (source_map->is_abandoned_prototype_map()) return false;
     636             :   ElementsKind target_elements_kind = target_map->elements_kind();
     637             :   bool more_general_transition = IsMoreGeneralElementsKindTransition(
     638      779574 :       source_map->elements_kind(), target_elements_kind);
     639             :   Map transitioned_map;
     640      389785 :   if (more_general_transition) {
     641             :     MapHandles map_list;
     642       45330 :     map_list.push_back(handle(target_map, isolate_));
     643             :     transitioned_map =
     644       15110 :         source_map->FindElementsKindTransitionedMap(isolate(), map_list);
     645             :   }
     646      389784 :   return transitioned_map == target_map;
     647             : }
     648             : 
     649           0 : void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
     650     1262859 :   PatchCache(name, MaybeObjectHandle(handler));
     651           0 : }
     652             : 
     653     2162844 : void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) {
     654             :   DCHECK(IsHandler(*handler));
     655             :   // Currently only load and store ICs support non-code handlers.
     656             :   DCHECK(IsAnyLoad() || IsAnyStore());
     657     2153630 :   switch (state()) {
     658             :     case NO_FEEDBACK:
     659             :       break;
     660             :     case UNINITIALIZED:
     661             :     case PREMONOMORPHIC:
     662             :       UpdateMonomorphicIC(handler, name);
     663             :       break;
     664             :     case RECOMPUTE_HANDLER:
     665             :     case MONOMORPHIC:
     666      240027 :       if (IsGlobalIC()) {
     667             :         UpdateMonomorphicIC(handler, name);
     668             :         break;
     669             :       }
     670             :       V8_FALLTHROUGH;
     671             :     case POLYMORPHIC:
     672      363004 :       if (UpdatePolymorphicIC(name, handler)) break;
     673       31273 :       if (!is_keyed() || state() == RECOMPUTE_HANDLER) {
     674       12845 :         CopyICToMegamorphicCache(name);
     675             :       }
     676       22059 :       ConfigureVectorState(MEGAMORPHIC, name);
     677             :       V8_FALLTHROUGH;
     678             :     case MEGAMORPHIC:
     679      655449 :       UpdateMegamorphicCache(receiver_map(), name, handler);
     680             :       // Indicate that we've handled this case.
     681      655449 :       vector_set_ = true;
     682      655449 :       break;
     683             :     case GENERIC:
     684           0 :       UNREACHABLE();
     685             :       break;
     686             :   }
     687     2153672 : }
     688             : 
     689     8094643 : void LoadIC::UpdateCaches(LookupIterator* lookup) {
     690     8268941 :   if (state() == UNINITIALIZED && !IsLoadGlobalIC()) {
     691             :     // This is the first time we execute this inline cache. Set the target to
     692             :     // the pre monomorphic stub to delay setting the monomorphic state.
     693       99012 :     TRACE_HANDLER_STATS(isolate(), LoadIC_Premonomorphic);
     694       99004 :     ConfigureVectorState(receiver_map());
     695       99004 :     TraceIC("LoadIC", lookup->name());
     696       99004 :     return;
     697             :   }
     698             : 
     699             :   Handle<Object> code;
     700     3085127 :   if (lookup->state() == LookupIterator::ACCESS_CHECK) {
     701          35 :     code = slow_stub();
     702     3085092 :   } else if (!lookup->IsFound()) {
     703       74972 :     TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonexistentDH);
     704       74972 :     Handle<Smi> smi_handler = LoadHandler::LoadNonExistent(isolate());
     705             :     code = LoadHandler::LoadFullChain(
     706             :         isolate(), receiver_map(),
     707       74971 :         MaybeObjectHandle(isolate()->factory()->null_value()), smi_handler);
     708             :   } else {
     709     3010120 :     if (IsLoadGlobalIC()) {
     710     1825385 :       if (lookup->TryLookupCachedProperty()) {
     711             :         DCHECK_EQ(LookupIterator::DATA, lookup->state());
     712             :       }
     713     3649084 :       if (lookup->state() == LookupIterator::DATA &&
     714             :           lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
     715             :         DCHECK(lookup->GetReceiver()->IsJSGlobalObject());
     716             :         // Now update the cell in the feedback vector.
     717     1823269 :         nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell());
     718     1823272 :         TraceIC("LoadGlobalIC", lookup->name());
     719     1823271 :         return;
     720             :       }
     721             :     }
     722     1186854 :     code = ComputeHandler(lookup);
     723             :   }
     724             : 
     725     1261851 :   PatchCache(lookup->name(), code);
     726     1261887 :   TraceIC("LoadIC", lookup->name());
     727             : }
     728             : 
     729      705759 : StubCache* IC::stub_cache() {
     730      705759 :   if (IsAnyLoad()) {
     731      319721 :     return isolate()->load_stub_cache();
     732             :   } else {
     733             :     DCHECK(IsAnyStore());
     734      386038 :     return isolate()->store_stub_cache();
     735             :   }
     736             : }
     737             : 
     738      705760 : void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
     739             :                                 const MaybeObjectHandle& handler) {
     740     1411519 :   stub_cache()->Set(*name, *map, *handler);
     741      705760 : }
     742             : 
     743           0 : void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) {
     744             :   DCHECK_EQ(LookupIterator::ACCESSOR, lookup->state());
     745           0 :   if (V8_LIKELY(!FLAG_runtime_stats)) return;
     746           0 :   if (IsAnyLoad()) {
     747           0 :     TRACE_HANDLER_STATS(isolate(), LoadIC_HandlerCacheHit_Accessor);
     748             :   } else {
     749             :     DCHECK(IsAnyStore());
     750           0 :     TRACE_HANDLER_STATS(isolate(), StoreIC_HandlerCacheHit_Accessor);
     751             :   }
     752             : }
     753             : 
     754     3517006 : Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
     755             :   Handle<Object> receiver = lookup->GetReceiver();
     756     3059823 :   ReadOnlyRoots roots(isolate());
     757     2411344 :   if (receiver->IsString() && *lookup->name() == roots.length_string()) {
     758        9682 :     TRACE_HANDLER_STATS(isolate(), LoadIC_StringLength);
     759        9682 :     return BUILTIN_CODE(isolate(), LoadIC_StringLength);
     760             :   }
     761             : 
     762     2356422 :   if (receiver->IsStringWrapper() && *lookup->name() == roots.length_string()) {
     763          81 :     TRACE_HANDLER_STATS(isolate(), LoadIC_StringWrapperLength);
     764          81 :     return BUILTIN_CODE(isolate(), LoadIC_StringWrapperLength);
     765             :   }
     766             : 
     767             :   // Use specialized code for getting prototype of functions.
     768     3612629 :   if (receiver->IsJSFunction() && *lookup->name() == roots.prototype_string() &&
     769     1190377 :       !JSFunction::cast(*receiver)->PrototypeRequiresRuntimeLookup()) {
     770             :     Handle<Code> stub;
     771       12036 :     TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
     772       12036 :     return BUILTIN_CODE(isolate(), LoadIC_FunctionPrototype);
     773             :   }
     774             : 
     775     1165072 :   Handle<Map> map = receiver_map();
     776             :   Handle<JSObject> holder;
     777             :   bool receiver_is_holder;
     778     1165072 :   if (lookup->state() != LookupIterator::JSPROXY) {
     779             :     holder = lookup->GetHolder<JSObject>();
     780             :     receiver_is_holder = receiver.is_identical_to(holder);
     781             :   }
     782             : 
     783     1165069 :   switch (lookup->state()) {
     784             :     case LookupIterator::INTERCEPTOR: {
     785         857 :       Handle<Smi> smi_handler = LoadHandler::LoadInterceptor(isolate());
     786             : 
     787         857 :       if (holder->GetNamedInterceptor()->non_masking()) {
     788             :         MaybeObjectHandle holder_ref(isolate()->factory()->null_value());
     789          72 :         if (!receiver_is_holder || IsLoadGlobalIC()) {
     790          24 :           holder_ref = MaybeObjectHandle::Weak(holder);
     791             :         }
     792          48 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNonMaskingInterceptorDH);
     793             :         return LoadHandler::LoadFullChain(isolate(), map, holder_ref,
     794          48 :                                           smi_handler);
     795             :       }
     796             : 
     797         809 :       if (receiver_is_holder) {
     798             :         DCHECK(map->has_named_interceptor());
     799         636 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptorDH);
     800         636 :         return smi_handler;
     801             :       }
     802             : 
     803         173 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptorFromPrototypeDH);
     804             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     805         173 :                                             smi_handler);
     806             :     }
     807             : 
     808             :     case LookupIterator::ACCESSOR: {
     809             :       // Use simple field loads for some well-known callback properties.
     810             :       // The method will only return true for absolute truths based on the
     811             :       // receiver maps.
     812             :       FieldIndex index;
     813      155216 :       if (Accessors::IsJSObjectFieldAccessor(isolate(), map, lookup->name(),
     814             :                                              &index)) {
     815       59978 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
     816       59978 :         return LoadHandler::LoadField(isolate(), index);
     817             :       }
     818      190476 :       if (holder->IsJSModuleNamespace()) {
     819             :         Handle<ObjectHashTable> exports(
     820       59547 :             Handle<JSModuleNamespace>::cast(holder)->module()->exports(),
     821       39698 :             isolate());
     822       39698 :         int entry = exports->FindEntry(roots, lookup->name(),
     823       59547 :                                        Smi::ToInt(lookup->name()->GetHash()));
     824             :         // We found the accessor, so the entry must exist.
     825             :         DCHECK_NE(entry, ObjectHashTable::kNotFound);
     826             :         int index = ObjectHashTable::EntryToValueIndex(entry);
     827       19849 :         return LoadHandler::LoadModuleExport(isolate(), index);
     828             :       }
     829             : 
     830       75389 :       Handle<Object> accessors = lookup->GetAccessors();
     831      150778 :       if (accessors->IsAccessorPair()) {
     832       69247 :         if (lookup->TryLookupCachedProperty()) {
     833             :           DCHECK_EQ(LookupIterator::DATA, lookup->state());
     834          19 :           return ComputeHandler(lookup);
     835             :         }
     836             : 
     837             :         Handle<Object> getter(AccessorPair::cast(*accessors)->getter(),
     838      138456 :                               isolate());
     839      139512 :         if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) {
     840         270 :           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     841         270 :           return slow_stub();
     842             :         }
     843             : 
     844      207132 :         if (getter->IsFunctionTemplateInfo() &&
     845       69216 :             FunctionTemplateInfo::cast(*getter)->BreakAtEntry()) {
     846             :           // Do not install an IC if the api function has a breakpoint.
     847          10 :           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     848          10 :           return slow_stub();
     849             :         }
     850             : 
     851             :         Handle<Smi> smi_handler;
     852             : 
     853       68948 :         CallOptimization call_optimization(isolate(), getter);
     854       68948 :         if (call_optimization.is_simple_api_call()) {
     855       12000 :           if (!call_optimization.IsCompatibleReceiverMap(map, holder) ||
     856       11894 :               !holder->HasFastProperties()) {
     857          69 :             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     858          69 :             return slow_stub();
     859             :           }
     860             : 
     861             :           CallOptimization::HolderLookup holder_lookup;
     862        3931 :           call_optimization.LookupHolderOfExpectedType(map, &holder_lookup);
     863             : 
     864             :           smi_handler = LoadHandler::LoadApiGetter(
     865        7862 :               isolate(), holder_lookup == CallOptimization::kHolderIsReceiver);
     866             : 
     867             :           Handle<Context> context(
     868        3931 :               call_optimization.GetAccessorContext(holder->map()), isolate());
     869             : 
     870        3935 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterFromPrototypeDH);
     871             :           return LoadHandler::LoadFromPrototype(
     872             :               isolate(), map, holder, smi_handler,
     873             :               MaybeObjectHandle::Weak(call_optimization.api_call_info()),
     874        3931 :               MaybeObjectHandle::Weak(context));
     875             :         }
     876             : 
     877       64948 :         if (holder->HasFastProperties()) {
     878             :           smi_handler =
     879      119468 :               LoadHandler::LoadAccessor(isolate(), lookup->GetAccessorIndex());
     880             : 
     881       59734 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadAccessorDH);
     882       59734 :           if (receiver_is_holder) return smi_handler;
     883       44702 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadAccessorFromPrototypeDH);
     884       10428 :         } else if (holder->IsJSGlobalObject()) {
     885         937 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobalFromPrototypeDH);
     886         937 :           smi_handler = LoadHandler::LoadGlobal(isolate());
     887             :           return LoadHandler::LoadFromPrototype(
     888             :               isolate(), map, holder, smi_handler,
     889        1874 :               MaybeObjectHandle::Weak(lookup->GetPropertyCell()));
     890             :         } else {
     891        4277 :           smi_handler = LoadHandler::LoadNormal(isolate());
     892             : 
     893        4277 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH);
     894        4277 :           if (receiver_is_holder) return smi_handler;
     895          63 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH);
     896             :         }
     897             : 
     898             :         return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     899       44765 :                                               smi_handler);
     900             :       }
     901             : 
     902        6142 :       Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
     903             : 
     904       18426 :       if (v8::ToCData<Address>(info->getter()) == kNullAddress ||
     905       12272 :           !AccessorInfo::IsCompatibleReceiverMap(info, map) ||
     906       23968 :           !holder->HasFastProperties() ||
     907        6234 :           (info->is_sloppy() && !receiver->IsJSReceiver())) {
     908         588 :         TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
     909         588 :         return slow_stub();
     910             :       }
     911             : 
     912             :       Handle<Smi> smi_handler = LoadHandler::LoadNativeDataProperty(
     913       11108 :           isolate(), lookup->GetAccessorIndex());
     914        5558 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNativeDataPropertyDH);
     915        5554 :       if (receiver_is_holder) return smi_handler;
     916         303 :       TRACE_HANDLER_STATS(isolate(),
     917             :                           LoadIC_LoadNativeDataPropertyFromPrototypeDH);
     918             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     919         303 :                                             smi_handler);
     920             :     }
     921             : 
     922             :     case LookupIterator::DATA: {
     923             :       DCHECK_EQ(kData, lookup->property_details().kind());
     924             :       Handle<Smi> smi_handler;
     925     1003700 :       if (lookup->is_dictionary_holder()) {
     926       38546 :         if (holder->IsJSGlobalObject()) {
     927             :           // TODO(verwaest): Also supporting the global object as receiver is a
     928             :           // workaround for code that leaks the global object.
     929       11721 :           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobalDH);
     930       11721 :           smi_handler = LoadHandler::LoadGlobal(isolate());
     931             :           return LoadHandler::LoadFromPrototype(
     932             :               isolate(), map, holder, smi_handler,
     933       23442 :               MaybeObjectHandle::Weak(lookup->GetPropertyCell()));
     934             :         }
     935             : 
     936        7552 :         smi_handler = LoadHandler::LoadNormal(isolate());
     937        7552 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalDH);
     938        7552 :         if (receiver_is_holder) return smi_handler;
     939        3715 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormalFromPrototypeDH);
     940             : 
     941      984433 :       } else if (lookup->property_details().location() == kField) {
     942      563152 :         FieldIndex field = lookup->GetFieldIndex();
     943      563154 :         smi_handler = LoadHandler::LoadField(isolate(), field);
     944      563152 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldDH);
     945      563151 :         if (receiver_is_holder) return smi_handler;
     946       16665 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldFromPrototypeDH);
     947             :       } else {
     948             :         DCHECK_EQ(kDescriptor, lookup->property_details().location());
     949             :         smi_handler =
     950      842553 :             LoadHandler::LoadConstant(isolate(), lookup->GetConstantIndex());
     951      421278 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantDH);
     952      421277 :         if (receiver_is_holder) return smi_handler;
     953      286758 :         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantFromPrototypeDH);
     954             :       }
     955             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder,
     956      307138 :                                             smi_handler);
     957             :     }
     958             :     case LookupIterator::INTEGER_INDEXED_EXOTIC:
     959          45 :       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadIntegerIndexedExoticDH);
     960          45 :       return LoadHandler::LoadNonExistent(isolate());
     961             :     case LookupIterator::JSPROXY: {
     962             :       Handle<JSProxy> holder_proxy = lookup->GetHolder<JSProxy>();
     963             :       bool receiver_is_holder_proxy = receiver.is_identical_to(holder_proxy);
     964        5251 :       Handle<Smi> smi_handler = LoadHandler::LoadProxy(isolate());
     965        5251 :       if (receiver_is_holder_proxy) {
     966        4476 :         return smi_handler;
     967             :       }
     968             :       return LoadHandler::LoadFromPrototype(isolate(), map, holder_proxy,
     969         775 :                                             smi_handler);
     970             :     }
     971             :     case LookupIterator::ACCESS_CHECK:
     972             :     case LookupIterator::NOT_FOUND:
     973             :     case LookupIterator::TRANSITION:
     974           0 :       UNREACHABLE();
     975             :   }
     976             : 
     977           0 :   return Handle<Code>::null();
     978             : }
     979             : 
     980      375579 : static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
     981             :   // This helper implements a few common fast cases for converting
     982             :   // non-smi keys of keyed loads/stores to a smi or a string.
     983      751158 :   if (key->IsHeapNumber()) {
     984        3908 :     double value = Handle<HeapNumber>::cast(key)->value();
     985        1954 :     if (std::isnan(value)) {
     986             :       key = isolate->factory()->NaN_string();
     987             :     } else {
     988             :       // Check bounds first to avoid undefined behavior in the conversion
     989             :       // to int.
     990        1693 :       if (value <= Smi::kMaxValue && value >= Smi::kMinValue) {
     991             :         int int_value = FastD2I(value);
     992         779 :         if (value == int_value) {
     993             :           key = handle(Smi::FromInt(int_value), isolate);
     994             :         }
     995             :       }
     996             :     }
     997      747250 :   } else if (key->IsString()) {
     998       44533 :     key = isolate->factory()->InternalizeString(Handle<String>::cast(key));
     999             :   }
    1000      375579 :   return key;
    1001             : }
    1002             : 
    1003         520 : bool KeyedLoadIC::CanChangeToAllowOutOfBounds(Handle<Map> receiver_map) {
    1004         520 :   const MaybeObjectHandle& handler = nexus()->FindHandlerForMap(receiver_map);
    1005         520 :   if (handler.is_null()) return false;
    1006         520 :   return LoadHandler::GetKeyedAccessLoadMode(*handler) == STANDARD_LOAD;
    1007             : }
    1008             : 
    1009      137110 : void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver,
    1010             :                                     KeyedAccessLoadMode load_mode) {
    1011      155745 :   Handle<Map> receiver_map(receiver->map(), isolate());
    1012             :   DCHECK(receiver_map->instance_type() != JS_VALUE_TYPE);  // Checked by caller.
    1013             :   MapHandles target_receiver_maps;
    1014      137110 :   TargetMaps(&target_receiver_maps);
    1015             : 
    1016      137110 :   if (target_receiver_maps.empty()) {
    1017      118412 :     Handle<Object> handler = LoadElementHandler(receiver_map, load_mode);
    1018             :     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1019             :   }
    1020             : 
    1021       79375 :   for (Handle<Map> map : target_receiver_maps) {
    1022       30370 :     if (map.is_null()) continue;
    1023       30370 :     if (map->instance_type() == JS_VALUE_TYPE) {
    1024             :       set_slow_stub_reason("JSValue");
    1025             :       return;
    1026             :     }
    1027       30361 :     if (map->instance_type() == JS_PROXY_TYPE) {
    1028             :       set_slow_stub_reason("JSProxy");
    1029             :       return;
    1030             :     }
    1031             :   }
    1032             : 
    1033             :   // The first time a receiver is seen that is a transitioned version of the
    1034             :   // previous monomorphic receiver type, assume the new ElementsKind is the
    1035             :   // monomorphic type. This benefits global arrays that only transition
    1036             :   // once, and all call sites accessing them are faster if they remain
    1037             :   // monomorphic. If this optimistic assumption is not true, the IC will
    1038             :   // miss again and it will become polymorphic and support both the
    1039             :   // untransitioned and transitioned maps.
    1040       55172 :   if (state() == MONOMORPHIC && !receiver->IsString() &&
    1041       61384 :       !receiver->IsJSProxy() &&
    1042             :       IsMoreGeneralElementsKindTransition(
    1043             :           target_receiver_maps.at(0)->elements_kind(),
    1044       54806 :           Handle<JSObject>::cast(receiver)->GetElementsKind())) {
    1045        2578 :     Handle<Object> handler = LoadElementHandler(receiver_map, load_mode);
    1046             :     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1047             :   }
    1048             : 
    1049             :   DCHECK(state() != GENERIC);
    1050             : 
    1051             :   // Determine the list of receiver maps that this call site has seen,
    1052             :   // adding the map that was just encountered.
    1053       16057 :   if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
    1054             :     // If the {receiver_map} previously had a handler that didn't handle
    1055             :     // out-of-bounds access, but can generally handle it, we can just go
    1056             :     // on and update the handler appropriately below.
    1057        2971 :     if (load_mode != LOAD_IGNORE_OUT_OF_BOUNDS ||
    1058         520 :         !CanChangeToAllowOutOfBounds(receiver_map)) {
    1059             :       // If the miss wasn't due to an unseen map, a polymorphic stub
    1060             :       // won't help, use the generic stub.
    1061             :       set_slow_stub_reason("same map added twice");
    1062             :       return;
    1063             :     }
    1064             :   }
    1065             : 
    1066             :   // If the maximum number of receiver maps has been exceeded, use the generic
    1067             :   // version of the IC.
    1068       28226 :   if (target_receiver_maps.size() > kMaxKeyedPolymorphism) {
    1069             :     set_slow_stub_reason("max polymorph exceeded");
    1070             :     return;
    1071             :   }
    1072             : 
    1073             :   MaybeObjectHandles handlers;
    1074       12408 :   handlers.reserve(target_receiver_maps.size());
    1075       12408 :   LoadElementPolymorphicHandlers(&target_receiver_maps, &handlers, load_mode);
    1076             :   DCHECK_LE(1, target_receiver_maps.size());
    1077       24816 :   if (target_receiver_maps.size() == 1) {
    1078        1018 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]);
    1079             :   } else {
    1080       11899 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
    1081             :   }
    1082             : }
    1083             : 
    1084      151313 : Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
    1085             :                                                KeyedAccessLoadMode load_mode) {
    1086      151421 :   if (receiver_map->has_indexed_interceptor() &&
    1087      151421 :       !receiver_map->GetIndexedInterceptor()->getter()->IsUndefined(
    1088      466654 :           isolate()) &&
    1089      151397 :       !receiver_map->GetIndexedInterceptor()->non_masking()) {
    1090             :     // TODO(jgruber): Update counter name.
    1091          84 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedInterceptorStub);
    1092          84 :     return BUILTIN_CODE(isolate(), LoadIndexedInterceptorIC);
    1093             :   }
    1094             :   InstanceType instance_type = receiver_map->instance_type();
    1095      151230 :   if (instance_type < FIRST_NONSTRING_TYPE) {
    1096        1227 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadIndexedStringDH);
    1097        1227 :     return LoadHandler::LoadIndexedString(isolate(), load_mode);
    1098             :   }
    1099      150003 :   if (instance_type < FIRST_JS_RECEIVER_TYPE) {
    1100           0 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_SlowStub);
    1101           0 :     return BUILTIN_CODE(isolate(), KeyedLoadIC_Slow);
    1102             :   }
    1103      150003 :   if (instance_type == JS_PROXY_TYPE) {
    1104         144 :     return LoadHandler::LoadProxy(isolate());
    1105             :   }
    1106             : 
    1107             :   ElementsKind elements_kind = receiver_map->elements_kind();
    1108      149858 :   if (IsSloppyArgumentsElementsKind(elements_kind)) {
    1109             :     // TODO(jgruber): Update counter name.
    1110        1754 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_KeyedLoadSloppyArgumentsStub);
    1111        1754 :     return BUILTIN_CODE(isolate(), KeyedLoadIC_SloppyArguments);
    1112             :   }
    1113      148104 :   bool is_js_array = instance_type == JS_ARRAY_TYPE;
    1114      148104 :   if (elements_kind == DICTIONARY_ELEMENTS) {
    1115        4306 :     TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadElementDH);
    1116             :     return LoadHandler::LoadElement(isolate(), elements_kind, false,
    1117        8612 :                                     is_js_array, load_mode);
    1118             :   }
    1119             :   DCHECK(IsFastElementsKind(elements_kind) ||
    1120             :          IsFixedTypedArrayElementsKind(elements_kind));
    1121             :   // TODO(jkummerow): Use IsHoleyOrDictionaryElementsKind(elements_kind).
    1122             :   bool convert_hole_to_undefined =
    1123      156321 :       is_js_array && elements_kind == HOLEY_ELEMENTS &&
    1124      156321 :       *receiver_map ==
    1125      168844 :           isolate()->raw_native_context()->GetInitialJSArrayMap(elements_kind);
    1126      143798 :   TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_LoadElementDH);
    1127             :   return LoadHandler::LoadElement(isolate(), elements_kind,
    1128             :                                   convert_hole_to_undefined, is_js_array,
    1129      287596 :                                   load_mode);
    1130             : }
    1131             : 
    1132       12408 : void KeyedLoadIC::LoadElementPolymorphicHandlers(
    1133             :     MapHandles* receiver_maps, MaybeObjectHandles* handlers,
    1134             :     KeyedAccessLoadMode load_mode) {
    1135             :   // Filter out deprecated maps to ensure their instances get migrated.
    1136             :   receiver_maps->erase(
    1137             :       std::remove_if(
    1138             :           receiver_maps->begin(), receiver_maps->end(),
    1139       60716 :           [](const Handle<Map>& map) { return map->is_deprecated(); }),
    1140       12408 :       receiver_maps->end());
    1141             : 
    1142       55138 :   for (Handle<Map> receiver_map : *receiver_maps) {
    1143             :     // Mark all stable receiver maps that have elements kind transition map
    1144             :     // among receiver_maps as unstable because the optimizing compilers may
    1145             :     // generate an elements kind transition for this kind of receivers.
    1146       30323 :     if (receiver_map->is_stable()) {
    1147             :       Map tmap = receiver_map->FindElementsKindTransitionedMap(isolate(),
    1148       37675 :                                                                *receiver_maps);
    1149       18828 :       if (!tmap.is_null()) {
    1150          18 :         receiver_map->NotifyLeafMapLayoutChange(isolate());
    1151             :       }
    1152             :     }
    1153             :     handlers->push_back(
    1154       60647 :         MaybeObjectHandle(LoadElementHandler(receiver_map, load_mode)));
    1155             :   }
    1156       12408 : }
    1157             : 
    1158             : namespace {
    1159             : 
    1160      146227 : bool ConvertKeyToIndex(Handle<Object> receiver, Handle<Object> key,
    1161             :                        uint32_t* index, InlineCacheState state) {
    1162      146227 :   if (!FLAG_use_ic || state == NO_FEEDBACK) return false;
    1163      584685 :   if (receiver->IsAccessCheckNeeded() || receiver->IsJSValue()) return false;
    1164             : 
    1165             :   // For regular JSReceiver or String receivers, the {key} must be a positive
    1166             :   // array index.
    1167      297542 :   if (receiver->IsJSReceiver() || receiver->IsString()) {
    1168      287676 :     if (key->ToArrayIndex(index)) return true;
    1169             :   }
    1170             :   // For JSTypedArray receivers, we can also support negative keys, which we
    1171             :   // just map into the [2**31, 2**32 - 1] range via a bit_cast. This is valid
    1172             :   // because JSTypedArray::length is always a Smi, so such keys will always
    1173             :   // be detected as OOB.
    1174       17440 :   if (receiver->IsJSTypedArray()) {
    1175             :     int32_t signed_index;
    1176         369 :     if (key->ToInt32(&signed_index)) {
    1177         198 :       *index = bit_cast<uint32_t>(signed_index);
    1178         198 :       return true;
    1179             :     }
    1180             :   }
    1181             :   return false;
    1182             : }
    1183             : 
    1184      449688 : bool IsOutOfBoundsAccess(Handle<Object> receiver, uint32_t index) {
    1185      449688 :   uint32_t length = 0;
    1186      899380 :   if (receiver->IsJSArray()) {
    1187      781013 :     JSArray::cast(*receiver)->length()->ToArrayLength(&length);
    1188      118366 :   } else if (receiver->IsString()) {
    1189        1165 :     length = String::cast(*receiver)->length();
    1190      116036 :   } else if (receiver->IsJSObject()) {
    1191      115658 :     length = JSObject::cast(*receiver)->elements()->length();
    1192             :   } else {
    1193             :     return false;
    1194             :   }
    1195      449499 :   return index >= length;
    1196             : }
    1197             : 
    1198      137109 : KeyedAccessLoadMode GetLoadMode(Isolate* isolate, Handle<Object> receiver,
    1199             :                                 uint32_t index) {
    1200      137109 :   if (IsOutOfBoundsAccess(receiver, index)) {
    1201        9270 :     if (receiver->IsJSTypedArray()) {
    1202             :       // For JSTypedArray we never lookup elements in the prototype chain.
    1203             :       return LOAD_IGNORE_OUT_OF_BOUNDS;
    1204             :     }
    1205             : 
    1206             :     // For other {receiver}s we need to check the "no elements" protector.
    1207        3694 :     if (isolate->IsNoElementsProtectorIntact()) {
    1208        6902 :       if (receiver->IsString()) {
    1209             :         // ToObject(receiver) will have the initial String.prototype.
    1210             :         return LOAD_IGNORE_OUT_OF_BOUNDS;
    1211             :       }
    1212        6616 :       if (receiver->IsJSObject()) {
    1213             :         // For other JSObjects (including JSArrays) we can only continue if
    1214             :         // the {receiver}s prototype is either the initial Object.prototype
    1215             :         // or the initial Array.prototype, which are both guarded by the
    1216             :         // "no elements" protector checked above.
    1217             :         Handle<Object> receiver_prototype(
    1218             :             JSObject::cast(*receiver)->map()->prototype(), isolate);
    1219        3308 :         if (isolate->IsInAnyContext(*receiver_prototype,
    1220        5485 :                                     Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ||
    1221             :             isolate->IsInAnyContext(*receiver_prototype,
    1222        2177 :                                     Context::INITIAL_OBJECT_PROTOTYPE_INDEX)) {
    1223             :           return LOAD_IGNORE_OUT_OF_BOUNDS;
    1224             :         }
    1225             :       }
    1226             :     }
    1227             :   }
    1228             :   return STANDARD_LOAD;
    1229             : }
    1230             : 
    1231             : }  // namespace
    1232             : 
    1233      215089 : MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
    1234             :                                       Handle<Object> key) {
    1235      215089 :   if (MigrateDeprecated(object)) {
    1236             :     Handle<Object> result;
    1237      781902 :     ASSIGN_RETURN_ON_EXCEPTION(
    1238             :         isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
    1239             :         Object);
    1240         139 :     return result;
    1241             :   }
    1242             : 
    1243             :   Handle<Object> load_handle;
    1244             : 
    1245             :   // Check for non-string values that can be converted into an
    1246             :   // internalized string directly or is representable as a smi.
    1247      214950 :   key = TryConvertKey(key, isolate());
    1248             : 
    1249             :   uint32_t index;
    1250      466121 :   if ((key->IsInternalizedString() &&
    1251      649330 :        !String::cast(*key)->AsArrayIndex(&index)) ||
    1252      398159 :       key->IsSymbol()) {
    1253      137446 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle,
    1254             :                                LoadIC::Load(object, Handle<Name>::cast(key)),
    1255             :                                Object);
    1256      146227 :   } else if (ConvertKeyToIndex(object, key, &index, state())) {
    1257      274218 :     KeyedAccessLoadMode load_mode = GetLoadMode(isolate(), object, index);
    1258      137109 :     UpdateLoadElement(Handle<HeapObject>::cast(object), load_mode);
    1259      137110 :     if (is_vector_set()) {
    1260      133398 :       TraceIC("LoadIC", key);
    1261             :     }
    1262             :   }
    1263             : 
    1264      214339 :   if (vector_needs_update()) {
    1265       12857 :     ConfigureVectorState(MEGAMORPHIC, key);
    1266       12857 :     TraceIC("LoadIC", key);
    1267             :   }
    1268             : 
    1269      214339 :   if (!load_handle.is_null()) return load_handle;
    1270             : 
    1271             :   Handle<Object> result;
    1272      292456 :   ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
    1273             :                              Runtime::GetObjectProperty(isolate(), object, key),
    1274             :                              Object);
    1275      145925 :   return result;
    1276             : }
    1277             : 
    1278     7484798 : bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
    1279             :                              StoreOrigin store_origin) {
    1280             :   // Disable ICs for non-JSObjects for now.
    1281             :   Handle<Object> object = it->GetReceiver();
    1282     4988847 :   if (object->IsJSProxy()) return true;
    1283     4988550 :   if (!object->IsJSObject()) return false;
    1284     2493938 :   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
    1285             :   DCHECK(!receiver->map()->is_deprecated());
    1286             : 
    1287     2493937 :   if (it->state() != LookupIterator::TRANSITION) {
    1288     2498942 :     for (; it->IsFound(); it->Next()) {
    1289     2025964 :       switch (it->state()) {
    1290             :         case LookupIterator::NOT_FOUND:
    1291             :         case LookupIterator::TRANSITION:
    1292           0 :           UNREACHABLE();
    1293             :         case LookupIterator::JSPROXY:
    1294             :           return true;
    1295             :         case LookupIterator::INTERCEPTOR: {
    1296             :           Handle<JSObject> holder = it->GetHolder<JSObject>();
    1297         283 :           InterceptorInfo info = holder->GetNamedInterceptor();
    1298         283 :           if (it->HolderIsReceiverOrHiddenPrototype()) {
    1299         741 :             return !info->non_masking() && receiver.is_identical_to(holder) &&
    1300        1125 :                    !info->setter()->IsUndefined(isolate());
    1301         108 :           } else if (!info->getter()->IsUndefined(isolate()) ||
    1302          36 :                      !info->query()->IsUndefined(isolate())) {
    1303             :             return false;
    1304             :           }
    1305           0 :           break;
    1306             :         }
    1307             :         case LookupIterator::ACCESS_CHECK:
    1308        5036 :           if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
    1309             :           break;
    1310             :         case LookupIterator::ACCESSOR:
    1311      228896 :           return !it->IsReadOnly();
    1312             :         case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1313          90 :           return false;
    1314             :         case LookupIterator::DATA: {
    1315     1793970 :           if (it->IsReadOnly()) return false;
    1316             :           Handle<JSObject> holder = it->GetHolder<JSObject>();
    1317     1780817 :           if (receiver.is_identical_to(holder)) {
    1318     1774913 :             it->PrepareForDataProperty(value);
    1319             :             // The previous receiver map might just have been deprecated,
    1320             :             // so reload it.
    1321     1774917 :             update_receiver_map(receiver);
    1322     1774919 :             return true;
    1323             :           }
    1324             : 
    1325             :           // Receiver != holder.
    1326       11808 :           if (receiver->IsJSGlobalProxy()) {
    1327         631 :             PrototypeIterator iter(isolate(), receiver);
    1328             :             return it->GetHolder<Object>().is_identical_to(
    1329             :                 PrototypeIterator::GetCurrent(iter));
    1330             :           }
    1331             : 
    1332        5273 :           if (it->HolderIsReceiverOrHiddenPrototype()) return false;
    1333             : 
    1334        5273 :           if (it->ExtendingNonExtensible(receiver)) return false;
    1335             :           it->PrepareTransitionToDataProperty(receiver, value, NONE,
    1336        5273 :                                               store_origin);
    1337        5273 :           return it->IsCacheableTransition();
    1338             :         }
    1339             :       }
    1340             :     }
    1341             :   }
    1342             : 
    1343      470475 :   receiver = it->GetStoreTarget<JSObject>();
    1344      470475 :   if (it->ExtendingNonExtensible(receiver)) return false;
    1345      470403 :   it->PrepareTransitionToDataProperty(receiver, value, NONE, store_origin);
    1346      470402 :   return it->IsCacheableTransition();
    1347             : }
    1348             : 
    1349     1645920 : MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name,
    1350             :                                          Handle<Object> value) {
    1351             :   DCHECK(name->IsString());
    1352             : 
    1353             :   // Look up in script context table.
    1354     1645920 :   Handle<String> str_name = Handle<String>::cast(name);
    1355     3292025 :   Handle<JSGlobalObject> global = isolate()->global_object();
    1356             :   Handle<ScriptContextTable> script_contexts(
    1357     3291840 :       global->native_context()->script_context_table(), isolate());
    1358             : 
    1359             :   ScriptContextTable::LookupResult lookup_result;
    1360     1645920 :   if (ScriptContextTable::Lookup(isolate(), script_contexts, str_name,
    1361             :                                  &lookup_result)) {
    1362             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    1363         130 :         isolate(), script_contexts, lookup_result.context_index);
    1364          65 :     if (lookup_result.mode == VariableMode::kConst) {
    1365          20 :       return TypeError(MessageTemplate::kConstAssign, global, name);
    1366             :     }
    1367             : 
    1368             :     Handle<Object> previous_value(script_context->get(lookup_result.slot_index),
    1369         135 :                                   isolate());
    1370             : 
    1371          90 :     if (previous_value->IsTheHole(isolate())) {
    1372             :       // Do not install stubs and stay pre-monomorphic for
    1373             :       // uninitialized accesses.
    1374          15 :       return ReferenceError(name);
    1375             :     }
    1376             : 
    1377          30 :     bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
    1378          30 :     if (use_ic) {
    1379          30 :       if (nexus()->ConfigureLexicalVarMode(lookup_result.context_index,
    1380          30 :                                            lookup_result.slot_index)) {
    1381          30 :         TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_StoreScriptContextField);
    1382             :       } else {
    1383             :         // Given combination of indices can't be encoded, so use slow stub.
    1384           0 :         TRACE_HANDLER_STATS(isolate(), StoreGlobalIC_SlowStub);
    1385           0 :         PatchCache(name, slow_stub());
    1386             :       }
    1387          30 :       TraceIC("StoreGlobalIC", name);
    1388             :     }
    1389             : 
    1390          90 :     script_context->set(lookup_result.slot_index, *value);
    1391          30 :     return value;
    1392             :   }
    1393             : 
    1394     1645855 :   return StoreIC::Store(global, name, value);
    1395             : }
    1396             : 
    1397     2954317 : MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
    1398             :                                    Handle<Object> value,
    1399     2954134 :                                    StoreOrigin store_origin) {
    1400             :   // TODO(verwaest): Let SetProperty do the migration, since storing a property
    1401             :   // might deprecate the current map again, if value does not fit.
    1402     2954317 :   if (MigrateDeprecated(object)) {
    1403             :     Handle<Object> result;
    1404    12694933 :     ASSIGN_RETURN_ON_EXCEPTION(
    1405             :         isolate(), result,
    1406             :         Object::SetProperty(isolate(), object, name, value, language_mode()),
    1407             :         Object);
    1408          54 :     return result;
    1409             :   }
    1410             : 
    1411     2954266 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic;
    1412             :   // If the object is undefined or null it's illegal to try to set any
    1413             :   // properties on it; throw a TypeError in that case.
    1414     5908535 :   if (object->IsNullOrUndefined(isolate())) {
    1415          90 :     if (use_ic && state() != PREMONOMORPHIC) {
    1416             :       // Ensure the IC state progresses.
    1417          45 :       TRACE_HANDLER_STATS(isolate(), StoreIC_NonReceiver);
    1418          45 :       update_receiver_map(object);
    1419          45 :       PatchCache(name, slow_stub());
    1420          45 :       TraceIC("StoreIC", name);
    1421             :     }
    1422          45 :     return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name);
    1423             :   }
    1424             : 
    1425     2954228 :   if (state() != UNINITIALIZED) {
    1426      877627 :     JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate());
    1427             :   }
    1428     2954231 :   LookupIterator it(isolate(), object, name);
    1429             : 
    1430     2954227 :   if (name->IsPrivate()) {
    1431        1920 :     if (name->IsPrivateName() && !it.IsFound()) {
    1432             :       Handle<String> name_string(String::cast(Symbol::cast(*name)->name()),
    1433         324 :                                  isolate());
    1434             :       return TypeError(MessageTemplate::kInvalidPrivateFieldWrite, object,
    1435         162 :                        name_string);
    1436             :     }
    1437             : 
    1438             :     // IC handling of private fields/symbols stores on JSProxy is not
    1439             :     // supported.
    1440        3516 :     if (object->IsJSProxy()) {
    1441             :       use_ic = false;
    1442             :     }
    1443             :   }
    1444     2954066 :   if (use_ic) UpdateCaches(&it, value, store_origin);
    1445             : 
    1446     2954080 :   MAYBE_RETURN_NULL(
    1447             :       Object::SetProperty(&it, value, language_mode(), store_origin));
    1448     2940242 :   return value;
    1449             : }
    1450             : 
    1451     4598874 : void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
    1452             :                            StoreOrigin store_origin) {
    1453     7505341 :   if (state() == UNINITIALIZED && !IsStoreGlobalIC()) {
    1454             :     // This is the first time we execute this inline cache. Transition
    1455             :     // to premonomorphic state to delay setting the monomorphic state.
    1456      459245 :     TRACE_HANDLER_STATS(isolate(), StoreIC_Premonomorphic);
    1457      459245 :     ConfigureVectorState(receiver_map());
    1458      459259 :     TraceIC("StoreIC", lookup->name());
    1459     2522156 :     return;
    1460             :   }
    1461             : 
    1462             :   MaybeObjectHandle handler;
    1463     2494423 :   if (LookupForWrite(lookup, value, store_origin)) {
    1464     2475581 :     if (IsStoreGlobalIC()) {
    1465     3248846 :       if (lookup->state() == LookupIterator::DATA &&
    1466             :           lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
    1467             :         DCHECK(lookup->GetReceiver()->IsJSGlobalObject());
    1468             :         // Now update the cell in the feedback vector.
    1469     1603640 :         nexus()->ConfigurePropertyCellMode(lookup->GetPropertyCell());
    1470     1603640 :         TraceIC("StoreGlobalIC", lookup->name());
    1471     1603640 :         return;
    1472             :       }
    1473             :     }
    1474      871941 :     handler = ComputeHandler(lookup);
    1475             :   } else {
    1476             :     set_slow_stub_reason("LookupForWrite said 'false'");
    1477             :     // TODO(marja): change slow_stub to return MaybeObjectHandle.
    1478       18841 :     handler = MaybeObjectHandle(slow_stub());
    1479             :   }
    1480             : 
    1481      890778 :   PatchCache(lookup->name(), handler);
    1482      890787 :   TraceIC("StoreIC", lookup->name());
    1483             : }
    1484             : 
    1485      871937 : MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) {
    1486      871937 :   switch (lookup->state()) {
    1487             :     case LookupIterator::TRANSITION: {
    1488      470738 :       Handle<JSObject> store_target = lookup->GetStoreTarget<JSObject>();
    1489      941478 :       if (store_target->IsJSGlobalObject()) {
    1490     1339279 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransitionDH);
    1491             : 
    1492       84284 :         if (receiver_map()->IsJSGlobalObject()) {
    1493             :           DCHECK(IsStoreGlobalIC());
    1494             : #ifdef DEBUG
    1495             :           Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1496             :           DCHECK_EQ(*lookup->GetReceiver(), *holder);
    1497             :           DCHECK_EQ(*store_target, *holder);
    1498             : #endif
    1499           0 :           return StoreHandler::StoreGlobal(lookup->transition_cell());
    1500             :         }
    1501             : 
    1502       42142 :         Handle<Smi> smi_handler = StoreHandler::StoreGlobalProxy(isolate());
    1503             :         Handle<Object> handler = StoreHandler::StoreThroughPrototype(
    1504             :             isolate(), receiver_map(), store_target, smi_handler,
    1505       42142 :             MaybeObjectHandle::Weak(lookup->transition_cell()));
    1506       42142 :         return MaybeObjectHandle(handler);
    1507             :       }
    1508             :       // Dictionary-to-fast transitions are not expected and not supported.
    1509             :       DCHECK_IMPLIES(!lookup->transition_map()->is_dictionary_map(),
    1510             :                      !receiver_map()->is_dictionary_map());
    1511             : 
    1512             :       DCHECK(lookup->IsCacheableTransition());
    1513             : 
    1514      428596 :       return StoreHandler::StoreTransition(isolate(), lookup->transition_map());
    1515             :     }
    1516             : 
    1517             :     case LookupIterator::INTERCEPTOR: {
    1518             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1519             :       USE(holder);
    1520             : 
    1521             :       DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate()));
    1522             :       // TODO(jgruber): Update counter name.
    1523         170 :       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
    1524         170 :       return MaybeObjectHandle(BUILTIN_CODE(isolate(), StoreInterceptorIC));
    1525             :     }
    1526             : 
    1527             :     case LookupIterator::ACCESSOR: {
    1528             :       // This is currently guaranteed by checks in StoreIC::Store.
    1529      228806 :       Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
    1530             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1531             :       DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
    1532             : 
    1533      228806 :       if (!holder->HasFastProperties()) {
    1534             :         set_slow_stub_reason("accessor on slow map");
    1535         498 :         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1536         498 :         return MaybeObjectHandle(slow_stub());
    1537             :       }
    1538      228308 :       Handle<Object> accessors = lookup->GetAccessors();
    1539      456616 :       if (accessors->IsAccessorInfo()) {
    1540       91261 :         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
    1541       91261 :         if (v8::ToCData<Address>(info->setter()) == kNullAddress) {
    1542             :           set_slow_stub_reason("setter == kNullAddress");
    1543           0 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1544           0 :           return MaybeObjectHandle(slow_stub());
    1545             :         }
    1546      182428 :         if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
    1547       91167 :             !lookup->HolderIsReceiverOrHiddenPrototype()) {
    1548             :           set_slow_stub_reason("special data property in prototype chain");
    1549          27 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1550          27 :           return MaybeObjectHandle(slow_stub());
    1551             :         }
    1552       91234 :         if (!AccessorInfo::IsCompatibleReceiverMap(info, receiver_map())) {
    1553             :           set_slow_stub_reason("incompatible receiver type");
    1554          12 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1555          12 :           return MaybeObjectHandle(slow_stub());
    1556             :         }
    1557             : 
    1558             :         Handle<Smi> smi_handler = StoreHandler::StoreNativeDataProperty(
    1559      182444 :             isolate(), lookup->GetAccessorIndex());
    1560       91222 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNativeDataPropertyDH);
    1561       91222 :         if (receiver.is_identical_to(holder)) {
    1562       91184 :           return MaybeObjectHandle(smi_handler);
    1563             :         }
    1564          38 :         TRACE_HANDLER_STATS(isolate(),
    1565             :                             StoreIC_StoreNativeDataPropertyOnPrototypeDH);
    1566             :         return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1567          38 :             isolate(), receiver_map(), holder, smi_handler));
    1568             : 
    1569      274094 :       } else if (accessors->IsAccessorPair()) {
    1570      274094 :         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
    1571      274094 :                               isolate());
    1572      292388 :         if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) {
    1573             :           set_slow_stub_reason("setter not a function");
    1574        8901 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1575        8901 :           return MaybeObjectHandle(slow_stub());
    1576             :         }
    1577             : 
    1578      384684 :         if (setter->IsFunctionTemplateInfo() &&
    1579      128392 :             FunctionTemplateInfo::cast(*setter)->BreakAtEntry()) {
    1580             :           // Do not install an IC if the api function has a breakpoint.
    1581          10 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1582          10 :           return MaybeObjectHandle(slow_stub());
    1583             :         }
    1584             : 
    1585      128136 :         CallOptimization call_optimization(isolate(), setter);
    1586      128136 :         if (call_optimization.is_simple_api_call()) {
    1587         408 :           if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
    1588             :             CallOptimization::HolderLookup holder_lookup;
    1589             :             call_optimization.LookupHolderOfExpectedType(receiver_map(),
    1590         360 :                                                          &holder_lookup);
    1591             : 
    1592             :             Handle<Smi> smi_handler = StoreHandler::StoreApiSetter(
    1593             :                 isolate(),
    1594         720 :                 holder_lookup == CallOptimization::kHolderIsReceiver);
    1595             : 
    1596             :             Handle<Context> context(
    1597         360 :                 call_optimization.GetAccessorContext(holder->map()), isolate());
    1598         360 :             TRACE_HANDLER_STATS(isolate(), StoreIC_StoreApiSetterOnPrototypeDH);
    1599             :             return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1600             :                 isolate(), receiver_map(), holder, smi_handler,
    1601             :                 MaybeObjectHandle::Weak(call_optimization.api_call_info()),
    1602         360 :                 MaybeObjectHandle::Weak(context)));
    1603             :           }
    1604             :           set_slow_stub_reason("incompatible receiver");
    1605          48 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1606          48 :           return MaybeObjectHandle(slow_stub());
    1607      255456 :         } else if (setter->IsFunctionTemplateInfo()) {
    1608             :           set_slow_stub_reason("setter non-simple template");
    1609           0 :           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1610           0 :           return MaybeObjectHandle(slow_stub());
    1611             :         }
    1612             : 
    1613             :         Handle<Smi> smi_handler =
    1614      255456 :             StoreHandler::StoreAccessor(isolate(), lookup->GetAccessorIndex());
    1615             : 
    1616      127728 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorDH);
    1617      127728 :         if (receiver.is_identical_to(holder)) {
    1618         491 :           return MaybeObjectHandle(smi_handler);
    1619             :         }
    1620      127237 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorOnPrototypeDH);
    1621             : 
    1622             :         return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
    1623      127237 :             isolate(), receiver_map(), holder, smi_handler));
    1624             :       }
    1625           0 :       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1626           0 :       return MaybeObjectHandle(slow_stub());
    1627             :     }
    1628             : 
    1629             :     case LookupIterator::DATA: {
    1630             :       // This is currently guaranteed by checks in StoreIC::Store.
    1631      171863 :       Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
    1632             :       USE(receiver);
    1633             :       Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    1634             :       DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
    1635             : 
    1636             :       DCHECK_EQ(kData, lookup->property_details().kind());
    1637      171863 :       if (lookup->is_dictionary_holder()) {
    1638       12274 :         if (holder->IsJSGlobalObject()) {
    1639         590 :           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalDH);
    1640             :           return MaybeObjectHandle(
    1641         590 :               StoreHandler::StoreGlobal(lookup->GetPropertyCell()));
    1642             :         }
    1643        5547 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormalDH);
    1644             :         DCHECK(holder.is_identical_to(receiver));
    1645        5547 :         return MaybeObjectHandle(StoreHandler::StoreNormal(isolate()));
    1646             :       }
    1647             : 
    1648             :       // -------------- Fields --------------
    1649      165726 :       if (lookup->property_details().location() == kField) {
    1650      165690 :         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH);
    1651      165690 :         int descriptor = lookup->GetFieldDescriptorIndex();
    1652      165690 :         FieldIndex index = lookup->GetFieldIndex();
    1653             :         PropertyConstness constness = lookup->constness();
    1654      165692 :         if (constness == PropertyConstness::kConst &&
    1655           0 :             IsStoreOwnICKind(nexus()->kind())) {
    1656             :           // StoreOwnICs are used for initializing object literals therefore
    1657             :           // we must store the value unconditionally even to
    1658             :           // VariableMode::kConst fields.
    1659             :           constness = PropertyConstness::kMutable;
    1660             :         }
    1661             :         return MaybeObjectHandle(StoreHandler::StoreField(
    1662      165692 :             isolate(), descriptor, index, constness, lookup->representation()));
    1663             :       }
    1664             : 
    1665             :       // -------------- Constant properties --------------
    1666             :       DCHECK_EQ(kDescriptor, lookup->property_details().location());
    1667             :       set_slow_stub_reason("constant property");
    1668          36 :       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
    1669          36 :       return MaybeObjectHandle(slow_stub());
    1670             :     }
    1671             :     case LookupIterator::JSPROXY: {
    1672             :       Handle<JSReceiver> receiver =
    1673         360 :           Handle<JSReceiver>::cast(lookup->GetReceiver());
    1674         360 :       Handle<JSProxy> holder = lookup->GetHolder<JSProxy>();
    1675             :       return MaybeObjectHandle(StoreHandler::StoreProxy(
    1676         360 :           isolate(), receiver_map(), holder, receiver));
    1677             :     }
    1678             : 
    1679             :     case LookupIterator::INTEGER_INDEXED_EXOTIC:
    1680             :     case LookupIterator::ACCESS_CHECK:
    1681             :     case LookupIterator::NOT_FOUND:
    1682           0 :       UNREACHABLE();
    1683             :   }
    1684           0 :   return MaybeObjectHandle();
    1685             : }
    1686             : 
    1687      215040 : void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
    1688             :                                       KeyedAccessStoreMode store_mode,
    1689             :                                       bool receiver_was_cow) {
    1690             :   MapHandles target_receiver_maps;
    1691      226893 :   TargetMaps(&target_receiver_maps);
    1692      215041 :   if (target_receiver_maps.empty()) {
    1693             :     Handle<Map> monomorphic_map =
    1694      203178 :         ComputeTransitionedMap(receiver_map, store_mode);
    1695             :     store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1696      203177 :     Handle<Object> handler = StoreElementHandler(monomorphic_map, store_mode);
    1697             :     return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
    1698             :   }
    1699             : 
    1700       45213 :   for (Handle<Map> map : target_receiver_maps) {
    1701       33360 :     if (!map.is_null() && map->instance_type() == JS_VALUE_TYPE) {
    1702             :       DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1703             :       set_slow_stub_reason("JSValue");
    1704             :       return;
    1705             :     }
    1706             :   }
    1707             : 
    1708             :   // There are several special cases where an IC that is MONOMORPHIC can still
    1709             :   // transition to a different GetNonTransitioningStoreMode IC that handles a
    1710             :   // superset of the original IC. Handle those here if the receiver map hasn't
    1711             :   // changed or it has transitioned to a more general kind.
    1712             :   KeyedAccessStoreMode old_store_mode;
    1713             :   old_store_mode = GetKeyedAccessStoreMode();
    1714       11853 :   Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
    1715       11853 :   if (state() == MONOMORPHIC) {
    1716             :     Handle<Map> transitioned_receiver_map = receiver_map;
    1717        9217 :     if (IsTransitionStoreMode(store_mode)) {
    1718             :       transitioned_receiver_map =
    1719        2817 :           ComputeTransitionedMap(receiver_map, store_mode);
    1720             :     }
    1721       11839 :     if ((receiver_map.is_identical_to(previous_receiver_map) &&
    1722       16785 :          IsTransitionStoreMode(store_mode)) ||
    1723             :         IsTransitionOfMonomorphicTarget(*previous_receiver_map,
    1724        7568 :                                         *transitioned_receiver_map)) {
    1725             :       // If the "old" and "new" maps are in the same elements map family, or
    1726             :       // if they at least come from the same origin for a transitioning store,
    1727             :       // stay MONOMORPHIC and use the map for the most generic ElementsKind.
    1728             :       store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1729             :       Handle<Object> handler =
    1730        5149 :           StoreElementHandler(transitioned_receiver_map, store_mode);
    1731             :       ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler);
    1732             :       return;
    1733             :     }
    1734        5041 :     if (receiver_map.is_identical_to(previous_receiver_map) &&
    1735        4912 :         old_store_mode == STANDARD_STORE &&
    1736        1688 :         (store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1737        1213 :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1738             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
    1739             :       // A "normal" IC that handles stores can switch to a version that can
    1740             :       // grow at the end of the array, handle OOB accesses or copy COW arrays
    1741             :       // and still stay MONOMORPHIC.
    1742         484 :       Handle<Object> handler = StoreElementHandler(receiver_map, store_mode);
    1743             :       return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
    1744             :     }
    1745             :   }
    1746             : 
    1747             :   DCHECK(state() != GENERIC);
    1748             : 
    1749             :   bool map_added =
    1750        6220 :       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
    1751             : 
    1752        6220 :   if (IsTransitionStoreMode(store_mode)) {
    1753             :     Handle<Map> transitioned_receiver_map =
    1754        1256 :         ComputeTransitionedMap(receiver_map, store_mode);
    1755             :     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
    1756        1256 :                                             transitioned_receiver_map);
    1757             :   }
    1758             : 
    1759        6220 :   if (!map_added) {
    1760             :     // If the miss wasn't due to an unseen map, a polymorphic stub
    1761             :     // won't help, use the megamorphic stub which can handle everything.
    1762             :     set_slow_stub_reason("same map added twice");
    1763             :     return;
    1764             :   }
    1765             : 
    1766             :   // If the maximum number of receiver maps has been exceeded, use the
    1767             :   // megamorphic version of the IC.
    1768       11156 :   if (target_receiver_maps.size() > kMaxKeyedPolymorphism) return;
    1769             : 
    1770             :   // Make sure all polymorphic handlers have the same store mode, otherwise the
    1771             :   // megamorphic stub must be used.
    1772             :   store_mode = GetNonTransitioningStoreMode(store_mode, receiver_was_cow);
    1773        4844 :   if (old_store_mode != STANDARD_STORE) {
    1774         744 :     if (store_mode == STANDARD_STORE) {
    1775             :       store_mode = old_store_mode;
    1776         479 :     } else if (store_mode != old_store_mode) {
    1777             :       set_slow_stub_reason("store mode mismatch");
    1778             :       return;
    1779             :     }
    1780             :   }
    1781             : 
    1782             :   // If the store mode isn't the standard mode, make sure that all polymorphic
    1783             :   // receivers are either external arrays, or all "normal" arrays. Otherwise,
    1784             :   // use the megamorphic stub.
    1785        4817 :   if (store_mode != STANDARD_STORE) {
    1786             :     size_t external_arrays = 0;
    1787        5035 :     for (Handle<Map> map : target_receiver_maps) {
    1788        2072 :       if (map->has_fixed_typed_array_elements()) {
    1789             :         DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1790         306 :         external_arrays++;
    1791             :       }
    1792             :     }
    1793        1017 :     if (external_arrays != 0 &&
    1794         126 :         external_arrays != target_receiver_maps.size()) {
    1795             :       DCHECK(!IsStoreInArrayLiteralICKind(kind()));
    1796             :       set_slow_stub_reason(
    1797             :           "unsupported combination of external and normal arrays");
    1798             :       return;
    1799             :     }
    1800             :   }
    1801             : 
    1802             :   MaybeObjectHandles handlers;
    1803        9580 :   handlers.reserve(target_receiver_maps.size());
    1804        4790 :   StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode);
    1805        9580 :   if (target_receiver_maps.size() == 0) {
    1806             :     // Transition to PREMONOMORPHIC state here and remember a weak-reference
    1807             :     // to the {receiver_map} in case TurboFan sees this function before the
    1808             :     // IC can transition further.
    1809           9 :     ConfigureVectorState(receiver_map);
    1810        4781 :   } else if (target_receiver_maps.size() == 1) {
    1811          36 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps[0], handlers[0]);
    1812             :   } else {
    1813        4763 :     ConfigureVectorState(Handle<Name>(), target_receiver_maps, &handlers);
    1814             :   }
    1815             : }
    1816             : 
    1817             : 
    1818      207250 : Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
    1819             :     Handle<Map> map, KeyedAccessStoreMode store_mode) {
    1820      207250 :   switch (store_mode) {
    1821             :     case STORE_TRANSITION_TO_OBJECT:
    1822             :     case STORE_AND_GROW_TRANSITION_TO_OBJECT: {
    1823             :       ElementsKind kind = IsHoleyElementsKind(map->elements_kind())
    1824             :                               ? HOLEY_ELEMENTS
    1825       18622 :                               : PACKED_ELEMENTS;
    1826       22387 :       return Map::TransitionElementsTo(isolate(), map, kind);
    1827             :     }
    1828             :     case STORE_TRANSITION_TO_DOUBLE:
    1829             :     case STORE_AND_GROW_TRANSITION_TO_DOUBLE: {
    1830             :       ElementsKind kind = IsHoleyElementsKind(map->elements_kind())
    1831             :                               ? HOLEY_DOUBLE_ELEMENTS
    1832        3765 :                               : PACKED_DOUBLE_ELEMENTS;
    1833        7530 :       return Map::TransitionElementsTo(isolate(), map, kind);
    1834             :     }
    1835             :     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
    1836             :       DCHECK(map->has_fixed_typed_array_elements());
    1837             :       V8_FALLTHROUGH;
    1838             :     case STORE_NO_TRANSITION_HANDLE_COW:
    1839             :     case STANDARD_STORE:
    1840             :     case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
    1841      184863 :       return map;
    1842             :   }
    1843           0 :   UNREACHABLE();
    1844             : }
    1845             : 
    1846      219194 : Handle<Object> KeyedStoreIC::StoreElementHandler(
    1847             :     Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) {
    1848             :   DCHECK(store_mode == STANDARD_STORE ||
    1849             :          store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1850             :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1851             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
    1852             :   DCHECK_IMPLIES(
    1853             :       receiver_map->DictionaryElementsInPrototypeChainOnly(isolate()),
    1854             :       IsStoreInArrayLiteralICKind(kind()));
    1855             : 
    1856      219194 :   if (receiver_map->IsJSProxyMap()) {
    1857      472528 :     return StoreHandler::StoreProxy(isolate());
    1858             :   }
    1859             : 
    1860             :   // TODO(ishell): move to StoreHandler::StoreElement().
    1861             :   Handle<Code> code;
    1862      219124 :   if (receiver_map->has_sloppy_arguments_elements()) {
    1863             :     // TODO(jgruber): Update counter name.
    1864           0 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_KeyedStoreSloppyArgumentsStub);
    1865             :     code =
    1866           0 :         CodeFactory::KeyedStoreIC_SloppyArguments(isolate(), store_mode).code();
    1867      241715 :   } else if (receiver_map->has_fast_elements() ||
    1868             :              receiver_map->has_fixed_typed_array_elements()) {
    1869      217693 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreFastElementStub);
    1870      435384 :     code = CodeFactory::StoreFastElementIC(isolate(), store_mode).code();
    1871      217691 :     if (receiver_map->has_fixed_typed_array_elements()) return code;
    1872        1431 :   } else if (IsStoreInArrayLiteralICKind(kind())) {
    1873             :     // TODO(jgruber): Update counter name.
    1874          36 :     TRACE_HANDLER_STATS(isolate(), StoreInArrayLiteralIC_SlowStub);
    1875             :     code =
    1876          72 :         CodeFactory::StoreInArrayLiteralIC_Slow(isolate(), store_mode).code();
    1877             :   } else {
    1878             :     // TODO(jgruber): Update counter name.
    1879        1395 :     TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_StoreElementStub);
    1880             :     DCHECK_EQ(DICTIONARY_ELEMENTS, receiver_map->elements_kind());
    1881        2790 :     code = CodeFactory::KeyedStoreIC_Slow(isolate(), store_mode).code();
    1882             :   }
    1883             : 
    1884      197962 :   if (IsStoreInArrayLiteralICKind(kind())) return code;
    1885             : 
    1886             :   Handle<Object> validity_cell =
    1887       26995 :       Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
    1888       53990 :   if (validity_cell->IsSmi()) {
    1889             :     // There's no prototype validity cell to check, so we can just use the stub.
    1890          51 :     return code;
    1891             :   }
    1892       26944 :   Handle<StoreHandler> handler = isolate()->factory()->NewStoreHandler(0);
    1893       26944 :   handler->set_validity_cell(*validity_cell);
    1894       53888 :   handler->set_smi_handler(*code);
    1895       26944 :   return handler;
    1896             : }
    1897             : 
    1898        4790 : void KeyedStoreIC::StoreElementPolymorphicHandlers(
    1899             :     MapHandles* receiver_maps, MaybeObjectHandles* handlers,
    1900             :     KeyedAccessStoreMode store_mode) {
    1901             :   DCHECK(store_mode == STANDARD_STORE ||
    1902             :          store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
    1903             :          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
    1904             :          store_mode == STORE_NO_TRANSITION_HANDLE_COW);
    1905             : 
    1906             :   // Filter out deprecated maps to ensure their instances get migrated.
    1907             :   receiver_maps->erase(
    1908             :       std::remove_if(
    1909             :           receiver_maps->begin(), receiver_maps->end(),
    1910       24414 :           [](const Handle<Map>& map) { return map->is_deprecated(); }),
    1911        4790 :       receiver_maps->end());
    1912             : 
    1913       21706 :   for (Handle<Map> receiver_map : *receiver_maps) {
    1914             :     Handle<Object> handler;
    1915             :     Handle<Map> transition;
    1916             : 
    1917       36378 :     if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE ||
    1918       51887 :         receiver_map->DictionaryElementsInPrototypeChainOnly(isolate())) {
    1919             :       // TODO(mvstanton): Consider embedding store_mode in the state of the slow
    1920             :       // keyed store ic for uniformity.
    1921          45 :       TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_SlowStub);
    1922          45 :       handler = slow_stub();
    1923             : 
    1924             :     } else {
    1925             :       {
    1926             :         Map tmap = receiver_map->FindElementsKindTransitionedMap(
    1927       12081 :             isolate(), *receiver_maps);
    1928       12081 :         if (!tmap.is_null()) {
    1929        1696 :           if (receiver_map->is_stable()) {
    1930          36 :             receiver_map->NotifyLeafMapLayoutChange(isolate());
    1931             :           }
    1932             :           transition = handle(tmap, isolate());
    1933             :         }
    1934             :       }
    1935             : 
    1936             :       // TODO(mvstanton): The code below is doing pessimistic elements
    1937             :       // transitions. I would like to stop doing that and rely on Allocation
    1938             :       // Site Tracking to do a better job of ensuring the data types are what
    1939             :       // they need to be. Not all the elements are in place yet, pessimistic
    1940             :       // elements transitions are still important for performance.
    1941       12081 :       if (!transition.is_null()) {
    1942        1696 :         TRACE_HANDLER_STATS(isolate(),
    1943             :                             KeyedStoreIC_ElementsTransitionAndStoreStub);
    1944             :         handler = StoreHandler::StoreElementTransition(isolate(), receiver_map,
    1945        1696 :                                                        transition, store_mode);
    1946             :       } else {
    1947       10385 :         handler = StoreElementHandler(receiver_map, store_mode);
    1948             :       }
    1949             :     }
    1950             :     DCHECK(!handler.is_null());
    1951       12126 :     handlers->push_back(MaybeObjectHandle(handler));
    1952             :   }
    1953        4790 : }
    1954             : 
    1955             : 
    1956      312578 : static KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
    1957             :                                          uint32_t index, Handle<Object> value) {
    1958      312578 :   bool oob_access = IsOutOfBoundsAccess(receiver, index);
    1959             :   // Don't consider this a growing store if the store would send the receiver to
    1960             :   // dictionary mode.
    1961     1040018 :   bool allow_growth = receiver->IsJSArray() && oob_access &&
    1962      414858 :                       !receiver->WouldConvertToSlowElements(index);
    1963      312580 :   if (allow_growth) {
    1964             :     // Handle growing array in stub if necessary.
    1965      202794 :     if (receiver->HasSmiElements()) {
    1966       15576 :       if (value->IsHeapNumber()) {
    1967             :         return STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    1968             :       }
    1969       14662 :       if (value->IsHeapObject()) {
    1970             :         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
    1971             :       }
    1972      187218 :     } else if (receiver->HasDoubleElements()) {
    1973        2094 :       if (!value->IsSmi() && !value->IsHeapNumber()) {
    1974             :         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
    1975             :       }
    1976             :     }
    1977             :     return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1978             :   } else {
    1979             :     // Handle only in-bounds elements accesses.
    1980      422366 :     if (receiver->HasSmiElements()) {
    1981      334850 :       if (value->IsHeapNumber()) {
    1982             :         return STORE_TRANSITION_TO_DOUBLE;
    1983      329009 :       } else if (value->IsHeapObject()) {
    1984             :         return STORE_TRANSITION_TO_OBJECT;
    1985             :       }
    1986       87518 :     } else if (receiver->HasDoubleElements()) {
    1987       16458 :       if (!value->IsSmi() && !value->IsHeapNumber()) {
    1988             :         return STORE_TRANSITION_TO_OBJECT;
    1989             :       }
    1990             :     }
    1991      567471 :     if (!FLAG_trace_external_array_abuse &&
    1992      206798 :         receiver->map()->has_fixed_typed_array_elements() && oob_access) {
    1993             :       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
    1994             :     }
    1995      376792 :     return receiver->elements()->IsCowArray() ? STORE_NO_TRANSITION_HANDLE_COW
    1996      188396 :                                               : STANDARD_STORE;
    1997             :   }
    1998             : }
    1999             : 
    2000             : 
    2001      160665 : MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
    2002             :                                         Handle<Object> key,
    2003             :                                         Handle<Object> value) {
    2004             :   // TODO(verwaest): Let SetProperty do the migration, since storing a property
    2005             :   // might deprecate the current map again, if value does not fit.
    2006      160665 :   if (MigrateDeprecated(object)) {
    2007             :     Handle<Object> result;
    2008      948654 :     ASSIGN_RETURN_ON_EXCEPTION(
    2009             :         isolate(), result,
    2010             :         Runtime::SetObjectProperty(isolate(), object, key, value,
    2011             :                                    language_mode(), StoreOrigin::kMaybeKeyed),
    2012             :         Object);
    2013          36 :     return result;
    2014             :   }
    2015             : 
    2016             :   // Check for non-string values that can be converted into an
    2017             :   // internalized string directly or is representable as a smi.
    2018      160629 :   key = TryConvertKey(key, isolate());
    2019             : 
    2020             :   Handle<Object> store_handle;
    2021             : 
    2022             :   uint32_t index;
    2023      329831 :   if ((key->IsInternalizedString() &&
    2024      482803 :        !String::cast(*key)->AsArrayIndex(&index)) ||
    2025      313601 :       key->IsSymbol()) {
    2026       24550 :     ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle,
    2027             :                                StoreIC::Store(object, Handle<Name>::cast(key),
    2028             :                                               value, StoreOrigin::kMaybeKeyed),
    2029             :                                Object);
    2030       11726 :     if (vector_needs_update()) {
    2031          18 :       if (ConfigureVectorState(MEGAMORPHIC, key)) {
    2032             :         set_slow_stub_reason("unhandled internalized string key");
    2033          18 :         TraceIC("StoreIC", key);
    2034             :       }
    2035             :     }
    2036       11726 :     return store_handle;
    2037             :   }
    2038             : 
    2039      148354 :   JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate());
    2040             : 
    2041      296708 :   bool use_ic = (state() != NO_FEEDBACK) && FLAG_use_ic &&
    2042     1037732 :                 !object->IsStringWrapper() && !object->IsAccessCheckNeeded() &&
    2043      296436 :                 !object->IsJSGlobalProxy();
    2044      444266 :   if (use_ic && !object->IsSmi()) {
    2045             :     // Don't use ICs for maps of the objects in Array's prototype chain. We
    2046             :     // expect to be able to trap element sets to objects with those maps in
    2047             :     // the runtime to enable optimization of element hole access.
    2048      147542 :     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
    2049      147542 :     if (heap_object->map()->IsMapInArrayPrototypeChain(isolate())) {
    2050             :       set_slow_stub_reason("map in array prototype");
    2051             :       use_ic = false;
    2052             :     }
    2053             :   }
    2054             : 
    2055             :   Handle<Map> old_receiver_map;
    2056             :   bool is_arguments = false;
    2057             :   bool key_is_valid_index = false;
    2058             :   KeyedAccessStoreMode store_mode = STANDARD_STORE;
    2059      442618 :   if (use_ic && object->IsJSReceiver()) {
    2060      146479 :     Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(object);
    2061             :     old_receiver_map = handle(receiver->map(), isolate());
    2062      292958 :     is_arguments = receiver->IsJSArgumentsObject();
    2063      292958 :     bool is_proxy = receiver->IsJSProxy();
    2064             :     // For JSTypedArray {object}s we can handle negative indices as OOB
    2065             :     // accesses, since integer indexed properties are never looked up
    2066             :     // on the prototype chain. For this we simply map the negative {key}s
    2067             :     // to the [2**31,2**32-1] range, which is safe since JSTypedArray::length
    2068             :     // is always an unsigned Smi.
    2069             :     key_is_valid_index =
    2070      437352 :         key->IsSmi() && (Smi::ToInt(*key) >= 0 || object->IsJSTypedArray());
    2071      146479 :     if (!is_arguments && !is_proxy) {
    2072      144826 :       if (key_is_valid_index) {
    2073      141629 :         uint32_t index = static_cast<uint32_t>(Smi::ToInt(*key));
    2074      141629 :         Handle<JSObject> receiver_object = Handle<JSObject>::cast(object);
    2075      141629 :         store_mode = GetStoreMode(receiver_object, index, value);
    2076             :       }
    2077             :     }
    2078             :   }
    2079             : 
    2080             :   DCHECK(store_handle.is_null());
    2081             :   bool receiver_was_cow =
    2082      561927 :       object->IsJSArray() &&
    2083      382084 :       Handle<JSArray>::cast(object)->elements()->IsCowArray();
    2084      296708 :   ASSIGN_RETURN_ON_EXCEPTION(
    2085             :       isolate(), store_handle,
    2086             :       Runtime::SetObjectProperty(isolate(), object, key, value, language_mode(),
    2087             :                                  StoreOrigin::kMaybeKeyed),
    2088             :       Object);
    2089             : 
    2090       54405 :   if (use_ic) {
    2091       53203 :     if (!old_receiver_map.is_null()) {
    2092       52667 :       if (is_arguments) {
    2093             :         set_slow_stub_reason("arguments receiver");
    2094       51536 :       } else if (key_is_valid_index) {
    2095       48888 :         if (old_receiver_map->is_abandoned_prototype_map()) {
    2096             :           set_slow_stub_reason("receiver with prototype map");
    2097       48870 :         } else if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly(
    2098       48870 :                        isolate())) {
    2099             :           // We should go generic if receiver isn't a dictionary, but our
    2100             :           // prototype chain does have dictionary elements. This ensures that
    2101             :           // other non-dictionary receivers in the polymorphic case benefit
    2102             :           // from fast path keyed stores.
    2103       44090 :           UpdateStoreElement(old_receiver_map, store_mode, receiver_was_cow);
    2104             :         } else {
    2105             :           set_slow_stub_reason("dictionary or proxy prototype");
    2106             :         }
    2107             :       } else {
    2108             :         set_slow_stub_reason("non-smi-like key");
    2109             :       }
    2110             :     } else {
    2111             :       set_slow_stub_reason("non-JSObject receiver");
    2112             :     }
    2113             :   }
    2114             : 
    2115       54405 :   if (vector_needs_update()) {
    2116       11755 :     ConfigureVectorState(MEGAMORPHIC, key);
    2117             :   }
    2118       54405 :   TraceIC("StoreIC", key);
    2119             : 
    2120       54405 :   return store_handle;
    2121             : }
    2122             : 
    2123             : namespace {
    2124      171076 : void StoreOwnElement(Isolate* isolate, Handle<JSArray> array,
    2125             :                      Handle<Object> index, Handle<Object> value) {
    2126             :   DCHECK(index->IsNumber());
    2127      171076 :   bool success = false;
    2128             :   LookupIterator it = LookupIterator::PropertyOrElement(
    2129      171076 :       isolate, array, index, &success, LookupIterator::OWN);
    2130             :   DCHECK(success);
    2131             : 
    2132      342158 :   CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE,
    2133             :                                                     kThrowOnError)
    2134             :             .FromJust());
    2135      171079 : }
    2136             : }  // namespace
    2137             : 
    2138      170949 : void StoreInArrayLiteralIC::Store(Handle<JSArray> array, Handle<Object> index,
    2139             :                                   Handle<Object> value) {
    2140             :   DCHECK(!array->map()->IsMapInArrayPrototypeChain(isolate()));
    2141             :   DCHECK(index->IsNumber());
    2142             : 
    2143      683802 :   if (!FLAG_use_ic || state() == NO_FEEDBACK || MigrateDeprecated(array)) {
    2144           0 :     StoreOwnElement(isolate(), array, index, value);
    2145           0 :     TraceIC("StoreInArrayLiteralIC", index);
    2146      170951 :     return;
    2147             :   }
    2148             : 
    2149             :   // TODO(neis): Convert HeapNumber to Smi if possible?
    2150             : 
    2151             :   KeyedAccessStoreMode store_mode = STANDARD_STORE;
    2152      341904 :   if (index->IsSmi()) {
    2153             :     DCHECK_GE(Smi::ToInt(*index), 0);
    2154      170950 :     uint32_t index32 = static_cast<uint32_t>(Smi::ToInt(*index));
    2155      170951 :     store_mode = GetStoreMode(array, index32, value);
    2156             :   }
    2157             : 
    2158             :   Handle<Map> old_array_map(array->map(), isolate());
    2159      170951 :   bool array_was_cow = array->elements()->IsCowArray();
    2160      170952 :   StoreOwnElement(isolate(), array, index, value);
    2161             : 
    2162      341904 :   if (index->IsSmi()) {
    2163             :     DCHECK(!old_array_map->is_abandoned_prototype_map());
    2164      170952 :     UpdateStoreElement(old_array_map, store_mode, array_was_cow);
    2165             :   } else {
    2166             :     set_slow_stub_reason("index out of Smi range");
    2167             :   }
    2168             : 
    2169      170951 :   if (vector_needs_update()) {
    2170           0 :     ConfigureVectorState(MEGAMORPHIC, index);
    2171             :   }
    2172      170951 :   TraceIC("StoreInArrayLiteralIC", index);
    2173             : }
    2174             : 
    2175             : // ----------------------------------------------------------------------------
    2176             : // Static IC stub generators.
    2177             : //
    2178             : //
    2179             : namespace {
    2180             : 
    2181             : // TODO(8580): Compute the language mode lazily to avoid the expensive
    2182             : // computation of language mode here.
    2183     3975866 : LanguageMode GetLanguageMode(Handle<FeedbackVector> vector, Context context) {
    2184     3975867 :   LanguageMode language_mode = vector->shared_function_info()->language_mode();
    2185     3975869 :   if (context->scope_info()->language_mode() > language_mode) {
    2186         424 :     return context->scope_info()->language_mode();
    2187             :   }
    2188             :   return language_mode;
    2189             : }
    2190             : 
    2191             : }  // namespace
    2192             : 
    2193     1291983 : RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
    2194     1291933 :   HandleScope scope(isolate);
    2195             :   DCHECK_EQ(4, args.length());
    2196             :   // Runtime functions don't follow the IC's calling convention.
    2197     1291945 :   Handle<Object> receiver = args.at(0);
    2198     1291956 :   Handle<Name> key = args.at<Name>(1);
    2199     1291965 :   Handle<Smi> slot = args.at<Smi>(2);
    2200     1291966 :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2201     1291968 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2202             : 
    2203             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2204     2583929 :   if (!maybe_vector->IsUndefined()) {
    2205             :     DCHECK(maybe_vector->IsFeedbackVector());
    2206     1291961 :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2207             :   }
    2208             :   // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
    2209             :   // LoadIC miss handler if the handler misses. Since the vector Nexus is
    2210             :   // set up outside the IC, handle that here.
    2211             :   // The only case where we call without a vector is from the LoadNamedProperty
    2212             :   // bytecode handler. Also, when there is no feedback vector, there is no
    2213             :   // difference between LoadProperty or LoadKeyed kind.
    2214             :   FeedbackSlotKind kind = FeedbackSlotKind::kLoadProperty;
    2215     1291960 :   if (!vector.is_null()) {
    2216     1291961 :     kind = vector->GetKind(vector_slot);
    2217             :   }
    2218     1291948 :   if (IsLoadICKind(kind)) {
    2219     1291949 :     LoadIC ic(isolate, vector, vector_slot, kind);
    2220     1291955 :     ic.UpdateState(receiver, key);
    2221     3875892 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2222             : 
    2223           0 :   } else if (IsLoadGlobalICKind(kind)) {
    2224             :     DCHECK_EQ(isolate->native_context()->global_proxy(), *receiver);
    2225           0 :     receiver = isolate->global_object();
    2226           0 :     LoadGlobalIC ic(isolate, vector, vector_slot, kind);
    2227           0 :     ic.UpdateState(receiver, key);
    2228           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key));
    2229             : 
    2230             :   } else {
    2231             :     DCHECK(IsKeyedLoadICKind(kind));
    2232           0 :     KeyedLoadIC ic(isolate, vector, vector_slot, kind);
    2233           0 :     ic.UpdateState(receiver, key);
    2234           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2235     1291962 :   }
    2236             : }
    2237             : 
    2238     2072914 : RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) {
    2239     2072864 :   HandleScope scope(isolate);
    2240             :   DCHECK_EQ(4, args.length());
    2241             :   // Runtime functions don't follow the IC's calling convention.
    2242     2072870 :   Handle<JSGlobalObject> global = isolate->global_object();
    2243     2072854 :   Handle<String> name = args.at<String>(0);
    2244     2072858 :   Handle<Smi> slot = args.at<Smi>(1);
    2245     2072860 :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2246     4145716 :   CONVERT_INT32_ARG_CHECKED(typeof_value, 3);
    2247     2072859 :   TypeofMode typeof_mode = static_cast<TypeofMode>(typeof_value);
    2248     2072861 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2249             : 
    2250             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2251     4145717 :   if (!maybe_vector->IsUndefined()) {
    2252             :     DCHECK(maybe_vector->IsFeedbackVector());
    2253     2072862 :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2254             :   }
    2255             : 
    2256             :   FeedbackSlotKind kind = (typeof_mode == TypeofMode::INSIDE_TYPEOF)
    2257             :                               ? FeedbackSlotKind::kLoadGlobalInsideTypeof
    2258     2072861 :                               : FeedbackSlotKind::kLoadGlobalNotInsideTypeof;
    2259     4145727 :   LoadGlobalIC ic(isolate, vector, vector_slot, kind);
    2260     2072862 :   ic.UpdateState(global, name);
    2261             : 
    2262             :   Handle<Object> result;
    2263     4145750 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(name));
    2264     2072869 :   return *result;
    2265             : }
    2266             : 
    2267         784 : RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) {
    2268         784 :   HandleScope scope(isolate);
    2269             :   DCHECK_EQ(3, args.length());
    2270        1568 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
    2271             : 
    2272         784 :   Handle<Context> native_context = isolate->native_context();
    2273             :   Handle<ScriptContextTable> script_contexts(
    2274        1568 :       native_context->script_context_table(), isolate);
    2275             : 
    2276             :   ScriptContextTable::LookupResult lookup_result;
    2277         784 :   if (ScriptContextTable::Lookup(isolate, script_contexts, name,
    2278             :                                  &lookup_result)) {
    2279             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    2280           0 :         isolate, script_contexts, lookup_result.context_index);
    2281             :     Handle<Object> result(script_context->get(lookup_result.slot_index),
    2282           0 :                           isolate);
    2283           0 :     if (*result == ReadOnlyRoots(isolate).the_hole_value()) {
    2284           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2285             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2286             :     }
    2287             :     return *result;
    2288             :   }
    2289             : 
    2290        1568 :   Handle<JSGlobalObject> global(native_context->global_object(), isolate);
    2291             :   Handle<Object> result;
    2292         784 :   bool is_found = false;
    2293        1568 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    2294             :       isolate, result,
    2295             :       Runtime::GetObjectProperty(isolate, global, name, &is_found));
    2296         784 :   if (!is_found) {
    2297           0 :     Handle<Smi> slot = args.at<Smi>(1);
    2298           0 :     Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2299           0 :     FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2300           0 :     FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2301             :     // It is actually a LoadGlobalICs here but the predicate handles this case
    2302             :     // properly.
    2303           0 :     if (LoadIC::ShouldThrowReferenceError(kind)) {
    2304           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2305             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2306             :     }
    2307             :   }
    2308         784 :   return *result;
    2309             : }
    2310             : 
    2311      215089 : RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) {
    2312      215089 :   HandleScope scope(isolate);
    2313             :   DCHECK_EQ(4, args.length());
    2314             :   // Runtime functions don't follow the IC's calling convention.
    2315      215089 :   Handle<Object> receiver = args.at(0);
    2316      215089 :   Handle<Object> key = args.at(1);
    2317      215089 :   Handle<Smi> slot = args.at<Smi>(2);
    2318      215090 :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2319             : 
    2320             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2321      430180 :   if (!maybe_vector->IsUndefined()) {
    2322             :     DCHECK(maybe_vector->IsFeedbackVector());
    2323      215089 :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2324             :   }
    2325      215089 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2326      430179 :   KeyedLoadIC ic(isolate, vector, vector_slot, FeedbackSlotKind::kLoadKeyed);
    2327      215089 :   ic.UpdateState(receiver, key);
    2328      645269 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
    2329             : }
    2330             : 
    2331     1296183 : RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
    2332     1296183 :   HandleScope scope(isolate);
    2333             :   DCHECK_EQ(5, args.length());
    2334             :   // Runtime functions don't follow the IC's calling convention.
    2335     1296189 :   Handle<Object> value = args.at(0);
    2336     1296191 :   Handle<Smi> slot = args.at<Smi>(1);
    2337     1296192 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2338     1296196 :   Handle<Object> receiver = args.at(3);
    2339     1296196 :   Handle<Name> key = args.at<Name>(4);
    2340             : 
    2341     1296195 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2342     1296194 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2343     1296193 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2344     1296198 :   if (IsStoreICKind(kind) || IsStoreOwnICKind(kind)) {
    2345     1296194 :     StoreIC ic(isolate, vector, vector_slot, kind, language_mode);
    2346     1296191 :     ic.UpdateState(receiver, key);
    2347     3888586 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2348           0 :   } else if (IsStoreGlobalICKind(kind)) {
    2349             :     DCHECK_EQ(isolate->native_context()->global_proxy(), *receiver);
    2350           0 :     receiver = isolate->global_object();
    2351           0 :     StoreGlobalIC ic(isolate, vector, vector_slot, kind, language_mode);
    2352           0 :     ic.UpdateState(receiver, key);
    2353           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value));
    2354             :   } else {
    2355             :     DCHECK(IsKeyedStoreICKind(kind));
    2356           0 :     KeyedStoreIC ic(isolate, vector, vector_slot, kind, language_mode);
    2357           0 :     ic.UpdateState(receiver, key);
    2358           0 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2359     1296193 :   }
    2360             : }
    2361             : 
    2362           0 : RUNTIME_FUNCTION(Runtime_StoreICNoFeedback_Miss) {
    2363           0 :   HandleScope scope(isolate);
    2364             :   DCHECK_EQ(5, args.length());
    2365           0 :   Handle<Object> value = args.at(0);
    2366           0 :   Handle<Object> receiver = args.at(1);
    2367           0 :   Handle<Name> key = args.at<Name>(2);
    2368           0 :   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
    2369           0 :   CONVERT_INT32_ARG_CHECKED(is_own_property_value, 4);
    2370             :   NamedPropertyType property_type =
    2371           0 :       static_cast<NamedPropertyType>(is_own_property_value);
    2372             : 
    2373             :   FeedbackSlotKind kind = (language_mode == LanguageMode::kStrict)
    2374             :                               ? FeedbackSlotKind::kStoreNamedStrict
    2375           0 :                               : FeedbackSlotKind::kStoreNamedSloppy;
    2376           0 :   if (property_type == NamedPropertyType::kOwn) {
    2377             :     language_mode = LanguageMode::kStrict;
    2378             :     kind = FeedbackSlotKind::kStoreOwnNamed;
    2379             :   }
    2380             :   StoreIC ic(isolate, Handle<FeedbackVector>(), FeedbackSlot(), kind,
    2381           0 :              language_mode);
    2382           0 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2383             : }
    2384             : 
    2385     1645920 : RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Miss) {
    2386     1645920 :   HandleScope scope(isolate);
    2387             :   DCHECK_EQ(4, args.length());
    2388             :   // Runtime functions don't follow the IC's calling convention.
    2389     1645920 :   Handle<Object> value = args.at(0);
    2390     1645920 :   Handle<Smi> slot = args.at<Smi>(1);
    2391     1645920 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2392     1645920 :   Handle<Name> key = args.at<Name>(3);
    2393             : 
    2394     1645920 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2395     1645920 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2396     1645920 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2397     3291840 :   StoreGlobalIC ic(isolate, vector, vector_slot, kind, language_mode);
    2398     1645920 :   Handle<JSGlobalObject> global = isolate->global_object();
    2399     1645920 :   ic.UpdateState(global, key);
    2400     4937760 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value));
    2401             : }
    2402             : 
    2403           0 : RUNTIME_FUNCTION(Runtime_StoreGlobalICNoFeedback_Miss) {
    2404           0 :   HandleScope scope(isolate);
    2405             :   DCHECK_EQ(3, args.length());
    2406             :   // Runtime functions don't follow the IC's calling convention.
    2407           0 :   Handle<Object> value = args.at(0);
    2408           0 :   Handle<Name> key = args.at<Name>(1);
    2409           0 :   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
    2410             : 
    2411             :   FeedbackSlotKind kind = (language_mode == LanguageMode::kStrict)
    2412             :                               ? FeedbackSlotKind::kStoreGlobalStrict
    2413           0 :                               : FeedbackSlotKind::kStoreGlobalSloppy;
    2414             :   StoreGlobalIC ic(isolate, Handle<FeedbackVector>(), FeedbackSlot(), kind,
    2415           0 :                    language_mode);
    2416           0 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(key, value));
    2417             : }
    2418             : 
    2419        7418 : RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) {
    2420        7418 :   HandleScope scope(isolate);
    2421             :   DCHECK_EQ(5, args.length());
    2422             :   // Runtime functions don't follow the IC's calling convention.
    2423        7418 :   Handle<Object> value = args.at(0);
    2424        7418 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2425       14836 :   CONVERT_ARG_HANDLE_CHECKED(String, name, 4);
    2426             : 
    2427             : #ifdef DEBUG
    2428             :   {
    2429             :     Handle<Smi> slot = args.at<Smi>(1);
    2430             :     FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2431             :     FeedbackSlotKind slot_kind = vector->GetKind(vector_slot);
    2432             :     DCHECK(IsStoreGlobalICKind(slot_kind));
    2433             :     Handle<Object> receiver = args.at(3);
    2434             :     DCHECK(receiver->IsJSGlobalProxy());
    2435             :   }
    2436             : #endif
    2437             : 
    2438        7418 :   Handle<JSGlobalObject> global = isolate->global_object();
    2439        7418 :   Handle<Context> native_context = isolate->native_context();
    2440             :   Handle<ScriptContextTable> script_contexts(
    2441       14836 :       native_context->script_context_table(), isolate);
    2442             : 
    2443             :   ScriptContextTable::LookupResult lookup_result;
    2444        7418 :   if (ScriptContextTable::Lookup(isolate, script_contexts, name,
    2445             :                                  &lookup_result)) {
    2446             :     Handle<Context> script_context = ScriptContextTable::GetContext(
    2447          18 :         isolate, script_contexts, lookup_result.context_index);
    2448          18 :     if (lookup_result.mode == VariableMode::kConst) {
    2449          18 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2450             :           isolate, NewTypeError(MessageTemplate::kConstAssign, global, name));
    2451             :     }
    2452             : 
    2453             :     Handle<Object> previous_value(script_context->get(lookup_result.slot_index),
    2454          27 :                                   isolate);
    2455             : 
    2456          18 :     if (previous_value->IsTheHole(isolate)) {
    2457           0 :       THROW_NEW_ERROR_RETURN_FAILURE(
    2458             :           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
    2459             :     }
    2460             : 
    2461          27 :     script_context->set(lookup_result.slot_index, *value);
    2462             :     return *value;
    2463             :   }
    2464             : 
    2465        7400 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2466       14800 :   RETURN_RESULT_OR_FAILURE(
    2467             :       isolate,
    2468             :       Runtime::SetObjectProperty(isolate, global, name, value, language_mode,
    2469        7418 :                                  StoreOrigin::kMaybeKeyed));
    2470             : }
    2471             : 
    2472      162309 : RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
    2473      162309 :   HandleScope scope(isolate);
    2474             :   DCHECK_EQ(5, args.length());
    2475             :   // Runtime functions don't follow the IC's calling convention.
    2476      162309 :   Handle<Object> value = args.at(0);
    2477      162309 :   Handle<Smi> slot = args.at<Smi>(1);
    2478      162309 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2479      162309 :   Handle<Object> receiver = args.at(3);
    2480      162309 :   Handle<Object> key = args.at(4);
    2481             : 
    2482      162309 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2483      162309 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2484      162309 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2485             : 
    2486             :   // The elements store stubs miss into this function, but they are shared by
    2487             :   // different ICs.
    2488      162309 :   if (IsKeyedStoreICKind(kind)) {
    2489      160665 :     KeyedStoreIC ic(isolate, vector, vector_slot, kind, language_mode);
    2490      160665 :     ic.UpdateState(receiver, key);
    2491      481995 :     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2492             :   } else {
    2493             :     DCHECK(IsStoreInArrayLiteralICKind(kind));
    2494             :     DCHECK(receiver->IsJSArray());
    2495             :     DCHECK(key->IsNumber());
    2496        1644 :     StoreInArrayLiteralIC ic(isolate, vector, vector_slot);
    2497        1644 :     ic.UpdateState(receiver, key);
    2498        1644 :     ic.Store(Handle<JSArray>::cast(receiver), key, value);
    2499        1644 :     return *value;
    2500      162309 :   }
    2501             : }
    2502             : 
    2503           0 : RUNTIME_FUNCTION(Runtime_KeyedStoreICNoFeedback_Miss) {
    2504           0 :   HandleScope scope(isolate);
    2505             :   DCHECK_EQ(4, args.length());
    2506             :   // Runtime functions don't follow the IC's calling convention.
    2507           0 :   Handle<Object> value = args.at(0);
    2508           0 :   Handle<Object> receiver = args.at(1);
    2509           0 :   Handle<Object> key = args.at(2);
    2510           0 :   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 3);
    2511             : 
    2512             :   FeedbackSlotKind kind = (language_mode == LanguageMode::kStrict)
    2513             :                               ? FeedbackSlotKind::kStoreKeyedStrict
    2514           0 :                               : FeedbackSlotKind::kStoreKeyedSloppy;
    2515             :   KeyedStoreIC ic(isolate, Handle<FeedbackVector>(), FeedbackSlot(), kind,
    2516           0 :                   language_mode);
    2517           0 :   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
    2518             : }
    2519             : 
    2520      169305 : RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Miss) {
    2521      169305 :   HandleScope scope(isolate);
    2522             :   DCHECK_EQ(5, args.length());
    2523             :   // Runtime functions don't follow the IC's calling convention.
    2524      169308 :   Handle<Object> value = args.at(0);
    2525      169308 :   Handle<Smi> slot = args.at<Smi>(1);
    2526      169308 :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(2);
    2527      169308 :   Handle<Object> receiver = args.at(3);
    2528      169308 :   Handle<Object> key = args.at(4);
    2529             :   Handle<FeedbackVector> vector = Handle<FeedbackVector>();
    2530      338616 :   if (!maybe_vector->IsUndefined()) {
    2531             :     DCHECK(maybe_vector->IsFeedbackVector());
    2532      169308 :     vector = Handle<FeedbackVector>::cast(maybe_vector);
    2533             :   }
    2534             :   DCHECK(receiver->IsJSArray());
    2535             :   DCHECK(key->IsNumber());
    2536      169308 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2537      338613 :   StoreInArrayLiteralIC ic(isolate, vector, vector_slot);
    2538      169306 :   ic.Store(Handle<JSArray>::cast(receiver), key, value);
    2539      169307 :   return *value;
    2540             : }
    2541             : 
    2542      317557 : RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
    2543      317557 :   HandleScope scope(isolate);
    2544             :   DCHECK_EQ(5, args.length());
    2545             :   // Runtime functions don't follow the IC's calling convention.
    2546      317557 :   Handle<Object> value = args.at(0);
    2547      317557 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2548      317557 :   Handle<Object> object = args.at(3);
    2549      317557 :   Handle<Object> key = args.at(4);
    2550      317557 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2551      635114 :   RETURN_RESULT_OR_FAILURE(
    2552             :       isolate,
    2553             :       Runtime::SetObjectProperty(isolate, object, key, value, language_mode,
    2554      317557 :                                  StoreOrigin::kMaybeKeyed));
    2555             : }
    2556             : 
    2557          47 : RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
    2558          47 :   HandleScope scope(isolate);
    2559             :   DCHECK_EQ(3, args.length());
    2560             :   // Runtime functions don't follow the IC's calling convention.
    2561          47 :   Handle<Object> value = args.at(0);
    2562          47 :   Handle<Object> array = args.at(1);
    2563          47 :   Handle<Object> index = args.at(2);
    2564          47 :   StoreOwnElement(isolate, Handle<JSArray>::cast(array), index, value);
    2565          47 :   return *value;
    2566             : }
    2567             : 
    2568         225 : RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
    2569         225 :   HandleScope scope(isolate);
    2570             :   DCHECK_EQ(6, args.length());
    2571             :   // Runtime functions don't follow the IC's calling convention.
    2572         225 :   Handle<Object> object = args.at(0);
    2573         225 :   Handle<Object> key = args.at(1);
    2574         225 :   Handle<Object> value = args.at(2);
    2575         225 :   Handle<Map> map = args.at<Map>(3);
    2576         225 :   Handle<Smi> slot = args.at<Smi>(4);
    2577         225 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(5);
    2578         225 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2579         225 :   FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2580             : 
    2581         450 :   if (object->IsJSObject()) {
    2582             :     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
    2583         225 :                                      map->elements_kind());
    2584             :   }
    2585             : 
    2586         225 :   if (IsStoreInArrayLiteralICKind(kind)) {
    2587          80 :     StoreOwnElement(isolate, Handle<JSArray>::cast(object), key, value);
    2588             :     return *value;
    2589             :   } else {
    2590             :     DCHECK(IsKeyedStoreICKind(kind) || IsStoreICKind(kind));
    2591         145 :     LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2592         290 :     RETURN_RESULT_OR_FAILURE(
    2593             :         isolate,
    2594             :         Runtime::SetObjectProperty(isolate, object, key, value, language_mode,
    2595             :                                    StoreOrigin::kMaybeKeyed));
    2596         225 :   }
    2597             : }
    2598             : 
    2599         513 : static bool CanFastCloneObject(Handle<Map> map) {
    2600             :   DisallowHeapAllocation no_gc;
    2601         513 :   if (map->IsNullOrUndefinedMap()) return true;
    2602         909 :   if (!map->IsJSObjectMap() ||
    2603         891 :       !IsSmiOrObjectElementsKind(map->elements_kind()) ||
    2604         891 :       !map->OnlyHasSimpleProperties()) {
    2605             :     return false;
    2606             :   }
    2607             : 
    2608         387 :   DescriptorArray descriptors = map->instance_descriptors();
    2609        1674 :   for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
    2610         477 :     PropertyDetails details = descriptors->GetDetails(i);
    2611         477 :     Name key = descriptors->GetKey(i);
    2612        1386 :     if (details.kind() != kData || !details.IsEnumerable() ||
    2613         450 :         key->IsPrivateName()) {
    2614          27 :       return false;
    2615             :     }
    2616             :   }
    2617             : 
    2618             :   return true;
    2619             : }
    2620             : 
    2621         387 : static Handle<Map> FastCloneObjectMap(Isolate* isolate,
    2622             :                                       Handle<HeapObject> source, int flags) {
    2623             :   Handle<Map> source_map(source->map(), isolate);
    2624             :   SLOW_DCHECK(source->IsNullOrUndefined() || CanFastCloneObject(source_map));
    2625        1161 :   Handle<JSFunction> constructor(isolate->native_context()->object_function(),
    2626         387 :                                  isolate);
    2627             :   DCHECK(constructor->has_initial_map());
    2628         774 :   Handle<Map> initial_map(constructor->initial_map(), isolate);
    2629             :   Handle<Map> map = initial_map;
    2630             : 
    2631        1494 :   if (source_map->IsJSObjectMap() && source_map->GetInObjectProperties() !=
    2632         747 :                                          initial_map->GetInObjectProperties()) {
    2633         306 :     int inobject_properties = source_map->GetInObjectProperties();
    2634             :     int instance_size =
    2635         306 :         JSObject::kHeaderSize + kTaggedSize * inobject_properties;
    2636         306 :     int unused = source_map->UnusedInObjectProperties();
    2637             :     DCHECK(instance_size <= JSObject::kMaxInstanceSize);
    2638             :     map = Map::CopyInitialMap(isolate, map, instance_size, inobject_properties,
    2639         306 :                               unused);
    2640             :   }
    2641             : 
    2642         387 :   if (flags & ObjectLiteral::kHasNullPrototype) {
    2643           0 :     if (map.is_identical_to(initial_map)) {
    2644           0 :       map = Map::Copy(isolate, map, "ObjectWithNullProto");
    2645             :     }
    2646           0 :     Map::SetPrototype(isolate, map, isolate->factory()->null_value());
    2647             :   }
    2648             : 
    2649        1134 :   if (source->IsNullOrUndefined() || !source_map->NumberOfOwnDescriptors()) {
    2650         126 :     return map;
    2651             :   }
    2652             : 
    2653         261 :   if (map.is_identical_to(initial_map)) {
    2654          18 :     map = Map::Copy(isolate, map, "InitializeClonedDescriptors");
    2655             :   }
    2656             : 
    2657             :   Handle<DescriptorArray> source_descriptors(source_map->instance_descriptors(),
    2658         522 :                                              isolate);
    2659             :   int size = source_map->NumberOfOwnDescriptors();
    2660             :   int slack = 0;
    2661             :   Handle<DescriptorArray> descriptors = DescriptorArray::CopyForFastObjectClone(
    2662         261 :       isolate, source_descriptors, size, slack);
    2663             :   Handle<LayoutDescriptor> layout =
    2664         261 :       LayoutDescriptor::New(isolate, map, descriptors, size);
    2665         261 :   map->InitializeDescriptors(isolate, *descriptors, *layout);
    2666         261 :   map->CopyUnusedPropertyFieldsAdjustedForInstanceSize(*source_map);
    2667             : 
    2668             :   // Update bitfields
    2669             :   map->set_may_have_interesting_symbols(
    2670         522 :       source_map->may_have_interesting_symbols());
    2671             : 
    2672         261 :   return map;
    2673             : }
    2674             : 
    2675         126 : static MaybeHandle<JSObject> CloneObjectSlowPath(Isolate* isolate,
    2676             :                                                  Handle<HeapObject> source,
    2677             :                                                  int flags) {
    2678             :   Handle<JSObject> new_object;
    2679         126 :   if (flags & ObjectLiteral::kHasNullPrototype) {
    2680           0 :     new_object = isolate->factory()->NewJSObjectWithNullProto();
    2681             :   } else {
    2682         378 :     Handle<JSFunction> constructor(isolate->native_context()->object_function(),
    2683         126 :                                    isolate);
    2684         126 :     new_object = isolate->factory()->NewJSObject(constructor);
    2685             :   }
    2686             : 
    2687         252 :   if (source->IsNullOrUndefined()) {
    2688           0 :     return new_object;
    2689             :   }
    2690             : 
    2691         126 :   MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, new_object, source,
    2692             :                                                    nullptr, false),
    2693             :                MaybeHandle<JSObject>());
    2694          90 :   return new_object;
    2695             : }
    2696             : 
    2697         513 : RUNTIME_FUNCTION(Runtime_CloneObjectIC_Miss) {
    2698         513 :   HandleScope scope(isolate);
    2699             :   DCHECK_EQ(4, args.length());
    2700         513 :   Handle<HeapObject> source = args.at<HeapObject>(0);
    2701         513 :   int flags = args.smi_at(1);
    2702             : 
    2703         513 :   MigrateDeprecated(source);
    2704             : 
    2705         513 :   FeedbackSlot slot = FeedbackVector::ToSlot(args.smi_at(2));
    2706         513 :   Handle<HeapObject> maybe_vector = args.at<HeapObject>(3);
    2707        1026 :   if (maybe_vector->IsUndefined()) {
    2708           0 :     RETURN_RESULT_OR_FAILURE(isolate,
    2709             :                              CloneObjectSlowPath(isolate, source, flags));
    2710             :   }
    2711             : 
    2712             :   DCHECK(maybe_vector->IsFeedbackVector());
    2713         513 :   Handle<FeedbackVector> vector = Handle<FeedbackVector>::cast(maybe_vector);
    2714             : 
    2715         513 :   FeedbackNexus nexus(vector, slot);
    2716        1026 :   Handle<Map> source_map(source->map(), isolate);
    2717             : 
    2718         513 :   if (!CanFastCloneObject(source_map) || nexus.IsMegamorphic()) {
    2719             :     // Migrate to slow mode if needed.
    2720         126 :     nexus.ConfigureMegamorphic();
    2721         252 :     RETURN_RESULT_OR_FAILURE(isolate,
    2722             :                              CloneObjectSlowPath(isolate, source, flags));
    2723             :   }
    2724             : 
    2725         387 :   Handle<Map> result_map = FastCloneObjectMap(isolate, source, flags);
    2726         387 :   nexus.ConfigureCloneObject(source_map, result_map);
    2727             : 
    2728         513 :   return *result_map;
    2729             : }
    2730             : 
    2731      495922 : RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
    2732      495922 :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2733      495922 :   Handle<JSObject> holder = args.at<JSObject>(1);
    2734      495922 :   Handle<AccessorInfo> info = args.at<AccessorInfo>(2);
    2735      495922 :   Handle<Name> name = args.at<Name>(3);
    2736      495922 :   Handle<Object> value = args.at(4);
    2737      991844 :   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 5);
    2738      495922 :   HandleScope scope(isolate);
    2739             : 
    2740      495922 :   if (V8_UNLIKELY(FLAG_runtime_stats)) {
    2741           0 :     RETURN_RESULT_OR_FAILURE(
    2742             :         isolate,
    2743             :         Runtime::SetObjectProperty(isolate, receiver, name, value,
    2744             :                                    language_mode, StoreOrigin::kMaybeKeyed));
    2745             :   }
    2746             : 
    2747             :   DCHECK(info->IsCompatibleReceiver(*receiver));
    2748             : 
    2749             :   ShouldThrow should_throw =
    2750      495922 :       is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
    2751             :   PropertyCallbackArguments arguments(isolate, info->data(), *receiver, *holder,
    2752     1487766 :                                       should_throw);
    2753      495922 :   arguments.CallAccessorSetter(info, name, value);
    2754      495922 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2755      495922 :   return *value;
    2756             : }
    2757             : 
    2758        6276 : RUNTIME_FUNCTION(Runtime_LoadCallbackProperty) {
    2759        1046 :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2760        1046 :   Handle<JSObject> holder = args.at<JSObject>(1);
    2761        1046 :   Handle<AccessorInfo> info = args.at<AccessorInfo>(2);
    2762        1046 :   Handle<Name> name = args.at<Name>(3);
    2763        1046 :   HandleScope scope(isolate);
    2764             : 
    2765             :   DCHECK(info->IsCompatibleReceiver(*receiver));
    2766             : 
    2767             :   PropertyCallbackArguments custom_args(isolate, info->data(), *receiver,
    2768        3138 :                                         *holder, kThrowOnError);
    2769        1046 :   Handle<Object> result = custom_args.CallAccessorGetter(info, name);
    2770        1046 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2771        1046 :   if (result.is_null()) return ReadOnlyRoots(isolate).undefined_value();
    2772        1046 :   return *result;
    2773             : }
    2774             : 
    2775       24030 : RUNTIME_FUNCTION(Runtime_LoadAccessorProperty) {
    2776        4005 :   HandleScope scope(isolate);
    2777             :   DCHECK_EQ(args.length(), 3);
    2778        4005 :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2779        4005 :   int handler_kind = args.smi_at(1);
    2780        4005 :   Handle<CallHandlerInfo> call_handler_info = args.at<CallHandlerInfo>(2);
    2781             : 
    2782        4005 :   Object holder = *receiver;
    2783        4005 :   if (handler_kind == LoadHandler::kApiGetterHolderIsPrototype) {
    2784           0 :     holder = receiver->map()->prototype();
    2785             :   } else {
    2786             :     DCHECK_EQ(handler_kind, LoadHandler::kApiGetter);
    2787             :   }
    2788             : 
    2789             :   // Call the accessor without additional arguments.
    2790             :   FunctionCallbackArguments custom(isolate, call_handler_info->data(),
    2791       16020 :                                    *receiver, holder, HeapObject(), nullptr, 0);
    2792        4005 :   Handle<Object> result_handle = custom.Call(*call_handler_info);
    2793        4005 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2794        4005 :   if (result_handle.is_null()) return ReadOnlyRoots(isolate).undefined_value();
    2795        4005 :   return *result_handle;
    2796             : }
    2797             : 
    2798             : /**
    2799             :  * Loads a property with an interceptor performing post interceptor
    2800             :  * lookup if interceptor failed.
    2801             :  */
    2802      134144 : RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) {
    2803      134144 :   HandleScope scope(isolate);
    2804             :   DCHECK_EQ(5, args.length());
    2805      134144 :   Handle<Name> name = args.at<Name>(0);
    2806      134144 :   Handle<Object> receiver = args.at(1);
    2807      134144 :   Handle<JSObject> holder = args.at<JSObject>(2);
    2808             : 
    2809      268288 :   if (!receiver->IsJSReceiver()) {
    2810          10 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    2811             :         isolate, receiver, Object::ConvertReceiver(isolate, receiver));
    2812             :   }
    2813             : 
    2814      268288 :   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor(), isolate);
    2815             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2816      268288 :                                       *holder, kDontThrow);
    2817      134144 :   Handle<Object> result = arguments.CallNamedGetter(interceptor, name);
    2818             : 
    2819      134144 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2820             : 
    2821      134132 :   if (!result.is_null()) return *result;
    2822             : 
    2823       55316 :   LookupIterator it(receiver, name, holder);
    2824             :   // Skip any lookup work until we hit the (possibly non-masking) interceptor.
    2825      165948 :   while (it.state() != LookupIterator::INTERCEPTOR ||
    2826      110632 :          !it.GetHolder<JSObject>().is_identical_to(holder)) {
    2827             :     DCHECK(it.state() != LookupIterator::ACCESS_CHECK || it.HasAccess());
    2828           0 :     it.Next();
    2829             :   }
    2830             :   // Skip past the interceptor.
    2831       55316 :   it.Next();
    2832      110632 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
    2833             : 
    2834       55304 :   if (it.IsFound()) return *result;
    2835             : 
    2836        6437 :   Handle<Smi> slot = args.at<Smi>(3);
    2837        6437 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(4);
    2838        6437 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2839        6437 :   FeedbackSlotKind slot_kind = vector->GetKind(vector_slot);
    2840             :   // It could actually be any kind of load IC slot here but the predicate
    2841             :   // handles all the cases properly.
    2842        6437 :   if (!LoadIC::ShouldThrowReferenceError(slot_kind)) {
    2843             :     return ReadOnlyRoots(isolate).undefined_value();
    2844             :   }
    2845             : 
    2846             :   // Throw a reference error.
    2847         396 :   THROW_NEW_ERROR_RETURN_FAILURE(
    2848      134144 :       isolate, NewReferenceError(MessageTemplate::kNotDefined, it.name()));
    2849             : }
    2850             : 
    2851             : 
    2852      546346 : RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
    2853      546346 :   HandleScope scope(isolate);
    2854             :   DCHECK_EQ(5, args.length());
    2855             :   // Runtime functions don't follow the IC's calling convention.
    2856      546346 :   Handle<Object> value = args.at(0);
    2857      546346 :   Handle<Smi> slot = args.at<Smi>(1);
    2858      546346 :   Handle<FeedbackVector> vector = args.at<FeedbackVector>(2);
    2859      546346 :   Handle<JSObject> receiver = args.at<JSObject>(3);
    2860      546346 :   Handle<Name> name = args.at<Name>(4);
    2861      546346 :   FeedbackSlot vector_slot = FeedbackVector::ToSlot(slot->value());
    2862      546346 :   LanguageMode language_mode = GetLanguageMode(vector, isolate->context());
    2863             : 
    2864             :   // TODO(ishell): Cache interceptor_holder in the store handler like we do
    2865             :   // for LoadHandler::kInterceptor case.
    2866             :   Handle<JSObject> interceptor_holder = receiver;
    2867     1092692 :   if (receiver->IsJSGlobalProxy()) {
    2868         294 :     FeedbackSlotKind kind = vector->GetKind(vector_slot);
    2869         294 :     if (IsStoreGlobalICKind(kind)) {
    2870         294 :       interceptor_holder = Handle<JSObject>::cast(isolate->global_object());
    2871             :     }
    2872             :   }
    2873             :   DCHECK(interceptor_holder->HasNamedInterceptor());
    2874             :   Handle<InterceptorInfo> interceptor(interceptor_holder->GetNamedInterceptor(),
    2875     1092692 :                                       isolate);
    2876             : 
    2877             :   DCHECK(!interceptor->non_masking());
    2878             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2879     1639038 :                                       *receiver, kDontThrow);
    2880             : 
    2881      546346 :   Handle<Object> result = arguments.CallNamedSetter(interceptor, name, value);
    2882      546346 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2883      546340 :   if (!result.is_null()) return *value;
    2884             : 
    2885      300294 :   LookupIterator it(receiver, name, receiver);
    2886             :   // Skip past any access check on the receiver.
    2887      300294 :   if (it.state() == LookupIterator::ACCESS_CHECK) {
    2888             :     DCHECK(it.HasAccess());
    2889         288 :     it.Next();
    2890             :   }
    2891             :   // Skip past the interceptor on the receiver.
    2892             :   DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
    2893      300294 :   it.Next();
    2894             : 
    2895      300294 :   MAYBE_RETURN(
    2896             :       Object::SetProperty(&it, value, language_mode, StoreOrigin::kNamed),
    2897             :       ReadOnlyRoots(isolate).exception());
    2898      546346 :   return *value;
    2899             : }
    2900             : 
    2901             : 
    2902        2238 : RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) {
    2903             :   // TODO(verwaest): This should probably get the holder and receiver as input.
    2904        2238 :   HandleScope scope(isolate);
    2905        2238 :   Handle<JSObject> receiver = args.at<JSObject>(0);
    2906             :   DCHECK_GE(args.smi_at(1), 0);
    2907        2238 :   uint32_t index = args.smi_at(1);
    2908             : 
    2909             :   Handle<InterceptorInfo> interceptor(receiver->GetIndexedInterceptor(),
    2910        4476 :                                       isolate);
    2911             :   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
    2912        6714 :                                       *receiver, kDontThrow);
    2913        2238 :   Handle<Object> result = arguments.CallIndexedGetter(interceptor, index);
    2914             : 
    2915        2238 :   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
    2916             : 
    2917        2238 :   if (result.is_null()) {
    2918           0 :     LookupIterator it(isolate, receiver, index, receiver);
    2919             :     DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
    2920           0 :     it.Next();
    2921           0 :     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
    2922             :                                        Object::GetProperty(&it));
    2923             :   }
    2924             : 
    2925        2238 :   return *result;
    2926             : }
    2927             : }  // namespace internal
    2928      183867 : }  // namespace v8

Generated by: LCOV version 1.10