Home | History | Annotate | Download | only in ic
      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.h"
     11 #include "src/base/bits.h"
     12 #include "src/codegen.h"
     13 #include "src/conversions.h"
     14 #include "src/execution.h"
     15 #include "src/field-type.h"
     16 #include "src/frames-inl.h"
     17 #include "src/ic/call-optimization.h"
     18 #include "src/ic/handler-compiler.h"
     19 #include "src/ic/ic-compiler.h"
     20 #include "src/ic/ic-inl.h"
     21 #include "src/ic/stub-cache.h"
     22 #include "src/isolate-inl.h"
     23 #include "src/macro-assembler.h"
     24 #include "src/prototype.h"
     25 #include "src/runtime/runtime-utils.h"
     26 #include "src/runtime/runtime.h"
     27 #include "src/tracing/trace-event.h"
     28 
     29 namespace v8 {
     30 namespace internal {
     31 
     32 char IC::TransitionMarkFromState(IC::State state) {
     33   switch (state) {
     34     case UNINITIALIZED:
     35       return '0';
     36     case PREMONOMORPHIC:
     37       return '.';
     38     case MONOMORPHIC:
     39       return '1';
     40     case RECOMPUTE_HANDLER:
     41       return '^';
     42     case POLYMORPHIC:
     43       return 'P';
     44     case MEGAMORPHIC:
     45       return 'N';
     46     case GENERIC:
     47       return 'G';
     48   }
     49   UNREACHABLE();
     50   return 0;
     51 }
     52 
     53 
     54 const char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) {
     55   if (mode == STORE_NO_TRANSITION_HANDLE_COW) return ".COW";
     56   if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
     57     return ".IGNORE_OOB";
     58   }
     59   if (IsGrowStoreMode(mode)) return ".GROW";
     60   return "";
     61 }
     62 
     63 
     64 #ifdef DEBUG
     65 
     66 #define TRACE_GENERIC_IC(isolate, type, reason)                \
     67   do {                                                         \
     68     if (FLAG_trace_ic) {                                       \
     69       PrintF("[%s patching generic stub in ", type);           \
     70       JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
     71       PrintF(" (%s)]\n", reason);                              \
     72     }                                                          \
     73   } while (false)
     74 
     75 #else
     76 
     77 #define TRACE_GENERIC_IC(isolate, type, reason)      \
     78   do {                                               \
     79     if (FLAG_trace_ic) {                             \
     80       PrintF("[%s patching generic stub in ", type); \
     81       PrintF("(see below) (%s)]\n", reason);         \
     82     }                                                \
     83   } while (false)
     84 
     85 #endif  // DEBUG
     86 
     87 
     88 void IC::TraceIC(const char* type, Handle<Object> name) {
     89   if (FLAG_trace_ic) {
     90     if (AddressIsDeoptimizedCode()) return;
     91     DCHECK(UseVector());
     92     State new_state = nexus()->StateFromFeedback();
     93     TraceIC(type, name, state(), new_state);
     94   }
     95 }
     96 
     97 
     98 void IC::TraceIC(const char* type, Handle<Object> name, State old_state,
     99                  State new_state) {
    100   if (FLAG_trace_ic) {
    101     PrintF("[%s%s in ", is_keyed() ? "Keyed" : "", type);
    102 
    103     // TODO(jkummerow): Add support for "apply". The logic is roughly:
    104     // marker = [fp_ + kMarkerOffset];
    105     // if marker is smi and marker.value == INTERNAL and
    106     //     the frame's code == builtin(Builtins::kFunctionApply):
    107     // then print "apply from" and advance one frame
    108 
    109     Object* maybe_function =
    110         Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset);
    111     if (maybe_function->IsJSFunction()) {
    112       JSFunction* function = JSFunction::cast(maybe_function);
    113       JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(),
    114                                               stdout, true);
    115     }
    116 
    117     const char* modifier = "";
    118     if (kind() == Code::KEYED_STORE_IC) {
    119       KeyedAccessStoreMode mode =
    120           casted_nexus<KeyedStoreICNexus>()->GetKeyedAccessStoreMode();
    121       modifier = GetTransitionMarkModifier(mode);
    122     }
    123     void* map = nullptr;
    124     if (!receiver_map().is_null()) {
    125       map = reinterpret_cast<void*>(*receiver_map());
    126     }
    127     PrintF(" (%c->%c%s) map=%p ", TransitionMarkFromState(old_state),
    128            TransitionMarkFromState(new_state), modifier, map);
    129     name->ShortPrint(stdout);
    130     PrintF("]\n");
    131   }
    132 }
    133 
    134 
    135 #define TRACE_IC(type, name) TraceIC(type, name)
    136 
    137 
    138 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus)
    139     : isolate_(isolate),
    140       vector_set_(false),
    141       target_maps_set_(false),
    142       nexus_(nexus) {
    143   // To improve the performance of the (much used) IC code, we unfold a few
    144   // levels of the stack frame iteration code. This yields a ~35% speedup when
    145   // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
    146   const Address entry = Isolate::c_entry_fp(isolate->thread_local_top());
    147   Address* constant_pool = NULL;
    148   if (FLAG_enable_embedded_constant_pool) {
    149     constant_pool = reinterpret_cast<Address*>(
    150         entry + ExitFrameConstants::kConstantPoolOffset);
    151   }
    152   Address* pc_address =
    153       reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
    154   Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
    155   // If there's another JavaScript frame on the stack or a
    156   // StubFailureTrampoline, we need to look one frame further down the stack to
    157   // find the frame pointer and the return address stack slot.
    158   if (depth == EXTRA_CALL_FRAME) {
    159     if (FLAG_enable_embedded_constant_pool) {
    160       constant_pool = reinterpret_cast<Address*>(
    161           fp + StandardFrameConstants::kConstantPoolOffset);
    162     }
    163     const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
    164     pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
    165     fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
    166   }
    167 #ifdef DEBUG
    168   StackFrameIterator it(isolate);
    169   for (int i = 0; i < depth + 1; i++) it.Advance();
    170   StackFrame* frame = it.frame();
    171   DCHECK(fp == frame->fp() && pc_address == frame->pc_address());
    172 #endif
    173   fp_ = fp;
    174   if (FLAG_enable_embedded_constant_pool) {
    175     constant_pool_address_ = constant_pool;
    176   }
    177   pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
    178   Code* target = this->target();
    179   kind_ = target->kind();
    180   state_ = UseVector() ? nexus->StateFromFeedback() : StateFromCode(target);
    181   old_state_ = state_;
    182   extra_ic_state_ = target->extra_ic_state();
    183 }
    184 
    185 InlineCacheState IC::StateFromCode(Code* code) {
    186   Isolate* isolate = code->GetIsolate();
    187   switch (code->kind()) {
    188     case Code::BINARY_OP_IC: {
    189       BinaryOpICState state(isolate, code->extra_ic_state());
    190       return state.GetICState();
    191     }
    192     case Code::COMPARE_IC: {
    193       CompareICStub stub(isolate, code->extra_ic_state());
    194       return stub.GetICState();
    195     }
    196     case Code::TO_BOOLEAN_IC: {
    197       ToBooleanICStub stub(isolate, code->extra_ic_state());
    198       return stub.GetICState();
    199     }
    200     default:
    201       if (code->is_debug_stub()) return UNINITIALIZED;
    202       UNREACHABLE();
    203       return UNINITIALIZED;
    204   }
    205 }
    206 
    207 SharedFunctionInfo* IC::GetSharedFunctionInfo() 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   StackFrameIterator it(isolate());
    212   while (it.frame()->fp() != this->fp()) it.Advance();
    213   if (FLAG_ignition && it.frame()->type() == StackFrame::STUB) {
    214     // Advance over bytecode handler frame.
    215     // TODO(rmcilroy): Remove this once bytecode handlers don't need a frame.
    216     it.Advance();
    217   }
    218   JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
    219   // Find the function on the stack and both the active code for the
    220   // function and the original code.
    221   JSFunction* function = frame->function();
    222   return function->shared();
    223 }
    224 
    225 
    226 Code* IC::GetCode() const {
    227   HandleScope scope(isolate());
    228   Handle<SharedFunctionInfo> shared(GetSharedFunctionInfo(), isolate());
    229   Code* code = shared->code();
    230   return code;
    231 }
    232 
    233 
    234 bool IC::AddressIsOptimizedCode() const {
    235   Code* host =
    236       isolate()->inner_pointer_to_code_cache()->GetCacheEntry(address())->code;
    237   return host->kind() == Code::OPTIMIZED_FUNCTION;
    238 }
    239 
    240 static void LookupForRead(LookupIterator* it) {
    241   for (; it->IsFound(); it->Next()) {
    242     switch (it->state()) {
    243       case LookupIterator::NOT_FOUND:
    244       case LookupIterator::TRANSITION:
    245         UNREACHABLE();
    246       case LookupIterator::JSPROXY:
    247         return;
    248       case LookupIterator::INTERCEPTOR: {
    249         // If there is a getter, return; otherwise loop to perform the lookup.
    250         Handle<JSObject> holder = it->GetHolder<JSObject>();
    251         if (!holder->GetNamedInterceptor()->getter()->IsUndefined(
    252                 it->isolate())) {
    253           return;
    254         }
    255         break;
    256       }
    257       case LookupIterator::ACCESS_CHECK:
    258         // PropertyHandlerCompiler::CheckPrototypes() knows how to emit
    259         // access checks for global proxies.
    260         if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && it->HasAccess()) {
    261           break;
    262         }
    263         return;
    264       case LookupIterator::ACCESSOR:
    265       case LookupIterator::INTEGER_INDEXED_EXOTIC:
    266       case LookupIterator::DATA:
    267         return;
    268     }
    269   }
    270 }
    271 
    272 bool IC::ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name) {
    273   if (!RecomputeHandlerForName(name)) return false;
    274 
    275   DCHECK(UseVector());
    276   maybe_handler_ = nexus()->FindHandlerForMap(receiver_map());
    277 
    278   // This is a contextual access, always just update the handler and stay
    279   // monomorphic.
    280   if (kind() == Code::LOAD_GLOBAL_IC) return true;
    281 
    282   // The current map wasn't handled yet. There's no reason to stay monomorphic,
    283   // *unless* we're moving from a deprecated map to its replacement, or
    284   // to a more general elements kind.
    285   // TODO(verwaest): Check if the current map is actually what the old map
    286   // would transition to.
    287   if (maybe_handler_.is_null()) {
    288     if (!receiver_map()->IsJSObjectMap()) return false;
    289     Map* first_map = FirstTargetMap();
    290     if (first_map == NULL) return false;
    291     Handle<Map> old_map(first_map);
    292     if (old_map->is_deprecated()) return true;
    293     return IsMoreGeneralElementsKindTransition(old_map->elements_kind(),
    294                                                receiver_map()->elements_kind());
    295   }
    296 
    297   return true;
    298 }
    299 
    300 bool IC::RecomputeHandlerForName(Handle<Object> name) {
    301   if (is_keyed()) {
    302     // Determine whether the failure is due to a name failure.
    303     if (!name->IsName()) return false;
    304     DCHECK(UseVector());
    305     Name* stub_name = nexus()->FindFirstName();
    306     if (*name != stub_name) return false;
    307   }
    308 
    309   return true;
    310 }
    311 
    312 
    313 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
    314   update_receiver_map(receiver);
    315   if (!name->IsString()) return;
    316   if (state() != MONOMORPHIC && state() != POLYMORPHIC) return;
    317   if (receiver->IsUndefined(isolate()) || receiver->IsNull(isolate())) return;
    318 
    319   // Remove the target from the code cache if it became invalid
    320   // because of changes in the prototype chain to avoid hitting it
    321   // again.
    322   if (ShouldRecomputeHandler(receiver, Handle<String>::cast(name))) {
    323     MarkRecomputeHandler(name);
    324   }
    325 }
    326 
    327 
    328 MaybeHandle<Object> IC::TypeError(MessageTemplate::Template index,
    329                                   Handle<Object> object, Handle<Object> key) {
    330   HandleScope scope(isolate());
    331   THROW_NEW_ERROR(isolate(), NewTypeError(index, key, object), Object);
    332 }
    333 
    334 
    335 MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) {
    336   HandleScope scope(isolate());
    337   THROW_NEW_ERROR(
    338       isolate(), NewReferenceError(MessageTemplate::kNotDefined, name), Object);
    339 }
    340 
    341 
    342 static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state,
    343                                       int* polymorphic_delta,
    344                                       int* generic_delta) {
    345   switch (old_state) {
    346     case UNINITIALIZED:
    347     case PREMONOMORPHIC:
    348       if (new_state == UNINITIALIZED || new_state == PREMONOMORPHIC) break;
    349       if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) {
    350         *polymorphic_delta = 1;
    351       } else if (new_state == MEGAMORPHIC || new_state == GENERIC) {
    352         *generic_delta = 1;
    353       }
    354       break;
    355     case MONOMORPHIC:
    356     case POLYMORPHIC:
    357       if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) break;
    358       *polymorphic_delta = -1;
    359       if (new_state == MEGAMORPHIC || new_state == GENERIC) {
    360         *generic_delta = 1;
    361       }
    362       break;
    363     case MEGAMORPHIC:
    364     case GENERIC:
    365       if (new_state == MEGAMORPHIC || new_state == GENERIC) break;
    366       *generic_delta = -1;
    367       if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) {
    368         *polymorphic_delta = 1;
    369       }
    370       break;
    371     case RECOMPUTE_HANDLER:
    372       UNREACHABLE();
    373   }
    374 }
    375 
    376 // static
    377 void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host) {
    378   if (host->kind() != Code::FUNCTION) return;
    379 
    380   TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
    381   info->change_own_type_change_checksum();
    382   host->set_profiler_ticks(0);
    383   isolate->runtime_profiler()->NotifyICChanged();
    384   // TODO(2029): When an optimized function is patched, it would
    385   // be nice to propagate the corresponding type information to its
    386   // unoptimized version for the benefit of later inlining.
    387 }
    388 
    389 void IC::PostPatching(Address address, Code* target, Code* old_target) {
    390   // Type vector based ICs update these statistics at a different time because
    391   // they don't always patch on state change.
    392   if (ICUseVector(target->kind())) return;
    393 
    394   DCHECK(old_target->is_inline_cache_stub());
    395   DCHECK(target->is_inline_cache_stub());
    396   State old_state = StateFromCode(old_target);
    397   State new_state = StateFromCode(target);
    398 
    399   Isolate* isolate = target->GetIsolate();
    400   Code* host =
    401       isolate->inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
    402   if (host->kind() != Code::FUNCTION) return;
    403 
    404   // Not all Code objects have TypeFeedbackInfo.
    405   if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
    406     if (FLAG_type_info_threshold > 0) {
    407       int polymorphic_delta = 0;  // "Polymorphic" here includes monomorphic.
    408       int generic_delta = 0;      // "Generic" here includes megamorphic.
    409       ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
    410                                 &generic_delta);
    411       TypeFeedbackInfo* info =
    412           TypeFeedbackInfo::cast(host->type_feedback_info());
    413       info->change_ic_with_type_info_count(polymorphic_delta);
    414       info->change_ic_generic_count(generic_delta);
    415     }
    416     TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
    417     info->change_own_type_change_checksum();
    418   }
    419   host->set_profiler_ticks(0);
    420   isolate->runtime_profiler()->NotifyICChanged();
    421   // TODO(2029): When an optimized function is patched, it would
    422   // be nice to propagate the corresponding type information to its
    423   // unoptimized version for the benefit of later inlining.
    424 }
    425 
    426 void IC::Clear(Isolate* isolate, Address address, Address constant_pool) {
    427   Code* target = GetTargetAtAddress(address, constant_pool);
    428 
    429   // Don't clear debug break inline cache as it will remove the break point.
    430   if (target->is_debug_stub()) return;
    431 
    432   if (target->kind() == Code::COMPARE_IC) {
    433     CompareIC::Clear(isolate, address, target, constant_pool);
    434   }
    435 }
    436 
    437 
    438 void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) {
    439   if (IsCleared(nexus)) return;
    440   // Make sure to also clear the map used in inline fast cases.  If we
    441   // do not clear these maps, cached code can keep objects alive
    442   // through the embedded maps.
    443   nexus->ConfigurePremonomorphic();
    444   OnTypeFeedbackChanged(isolate, host);
    445 }
    446 
    447 
    448 void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
    449   // Determine our state.
    450   Object* feedback = nexus->vector()->Get(nexus->slot());
    451   State state = nexus->StateFromFeedback();
    452 
    453   if (state != UNINITIALIZED && !feedback->IsAllocationSite()) {
    454     nexus->ConfigureUninitialized();
    455     // The change in state must be processed.
    456     OnTypeFeedbackChanged(isolate, host);
    457   }
    458 }
    459 
    460 
    461 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
    462   if (IsCleared(nexus)) return;
    463   nexus->ConfigurePremonomorphic();
    464   OnTypeFeedbackChanged(isolate, host);
    465 }
    466 
    467 void LoadGlobalIC::Clear(Isolate* isolate, Code* host,
    468                          LoadGlobalICNexus* nexus) {
    469   if (IsCleared(nexus)) return;
    470   nexus->ConfigureUninitialized();
    471   OnTypeFeedbackChanged(isolate, host);
    472 }
    473 
    474 void StoreIC::Clear(Isolate* isolate, Code* host, StoreICNexus* nexus) {
    475   if (IsCleared(nexus)) return;
    476   nexus->ConfigurePremonomorphic();
    477   OnTypeFeedbackChanged(isolate, host);
    478 }
    479 
    480 
    481 void KeyedStoreIC::Clear(Isolate* isolate, Code* host,
    482                          KeyedStoreICNexus* nexus) {
    483   if (IsCleared(nexus)) return;
    484   nexus->ConfigurePremonomorphic();
    485   OnTypeFeedbackChanged(isolate, host);
    486 }
    487 
    488 
    489 void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
    490                       Address constant_pool) {
    491   DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC);
    492   CompareICStub stub(target->stub_key(), isolate);
    493   // Only clear CompareICs that can retain objects.
    494   if (stub.state() != CompareICState::KNOWN_RECEIVER) return;
    495   SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()),
    496                      constant_pool);
    497   PatchInlinedSmiCode(isolate, address, DISABLE_INLINED_SMI_CHECK);
    498 }
    499 
    500 
    501 // static
    502 Handle<Code> KeyedLoadIC::ChooseMegamorphicStub(Isolate* isolate,
    503                                                 ExtraICState extra_state) {
    504   // TODO(ishell): remove extra_ic_state
    505   if (FLAG_compiled_keyed_generic_loads) {
    506     return KeyedLoadGenericStub(isolate).GetCode();
    507   } else {
    508     return isolate->builtins()->KeyedLoadIC_Megamorphic();
    509   }
    510 }
    511 
    512 
    513 static bool MigrateDeprecated(Handle<Object> object) {
    514   if (!object->IsJSObject()) return false;
    515   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
    516   if (!receiver->map()->is_deprecated()) return false;
    517   JSObject::MigrateInstance(Handle<JSObject>::cast(object));
    518   return true;
    519 }
    520 
    521 void IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
    522   DCHECK(UseVector());
    523   if (new_state == PREMONOMORPHIC) {
    524     nexus()->ConfigurePremonomorphic();
    525   } else if (new_state == MEGAMORPHIC) {
    526     if (kind() == Code::LOAD_IC || kind() == Code::STORE_IC) {
    527       nexus()->ConfigureMegamorphic();
    528     } else if (kind() == Code::KEYED_LOAD_IC) {
    529       KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
    530       nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
    531     } else {
    532       DCHECK(kind() == Code::KEYED_STORE_IC);
    533       KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
    534       nexus->ConfigureMegamorphicKeyed(key->IsName() ? PROPERTY : ELEMENT);
    535     }
    536   } else {
    537     UNREACHABLE();
    538   }
    539 
    540   vector_set_ = true;
    541   OnTypeFeedbackChanged(isolate(), get_host());
    542 }
    543 
    544 
    545 void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
    546                               Handle<Code> handler) {
    547   DCHECK(UseVector());
    548   if (kind() == Code::LOAD_IC) {
    549     LoadICNexus* nexus = casted_nexus<LoadICNexus>();
    550     nexus->ConfigureMonomorphic(map, handler);
    551   } else if (kind() == Code::LOAD_GLOBAL_IC) {
    552     LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
    553     nexus->ConfigureHandlerMode(handler);
    554   } else if (kind() == Code::KEYED_LOAD_IC) {
    555     KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
    556     nexus->ConfigureMonomorphic(name, map, handler);
    557   } else if (kind() == Code::STORE_IC) {
    558     StoreICNexus* nexus = casted_nexus<StoreICNexus>();
    559     nexus->ConfigureMonomorphic(map, handler);
    560   } else {
    561     DCHECK(kind() == Code::KEYED_STORE_IC);
    562     KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
    563     nexus->ConfigureMonomorphic(name, map, handler);
    564   }
    565 
    566   vector_set_ = true;
    567   OnTypeFeedbackChanged(isolate(), get_host());
    568 }
    569 
    570 
    571 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps,
    572                               CodeHandleList* handlers) {
    573   DCHECK(UseVector());
    574   if (kind() == Code::LOAD_IC) {
    575     LoadICNexus* nexus = casted_nexus<LoadICNexus>();
    576     nexus->ConfigurePolymorphic(maps, handlers);
    577   } else if (kind() == Code::KEYED_LOAD_IC) {
    578     KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
    579     nexus->ConfigurePolymorphic(name, maps, handlers);
    580   } else if (kind() == Code::STORE_IC) {
    581     StoreICNexus* nexus = casted_nexus<StoreICNexus>();
    582     nexus->ConfigurePolymorphic(maps, handlers);
    583   } else {
    584     DCHECK(kind() == Code::KEYED_STORE_IC);
    585     KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
    586     nexus->ConfigurePolymorphic(name, maps, handlers);
    587   }
    588 
    589   vector_set_ = true;
    590   OnTypeFeedbackChanged(isolate(), get_host());
    591 }
    592 
    593 
    594 void IC::ConfigureVectorState(MapHandleList* maps,
    595                               MapHandleList* transitioned_maps,
    596                               CodeHandleList* handlers) {
    597   DCHECK(UseVector());
    598   DCHECK(kind() == Code::KEYED_STORE_IC);
    599   KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>();
    600   nexus->ConfigurePolymorphic(maps, transitioned_maps, handlers);
    601 
    602   vector_set_ = true;
    603   OnTypeFeedbackChanged(isolate(), get_host());
    604 }
    605 
    606 
    607 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
    608   // If the object is undefined or null it's illegal to try to get any
    609   // of its properties; throw a TypeError in that case.
    610   if (object->IsUndefined(isolate()) || object->IsNull(isolate())) {
    611     return TypeError(MessageTemplate::kNonObjectPropertyLoad, object, name);
    612   }
    613 
    614   bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
    615 
    616   if (state() != UNINITIALIZED) {
    617     JSObject::MakePrototypesFast(object, kStartAtReceiver, isolate());
    618     update_receiver_map(object);
    619   }
    620   // Named lookup in the object.
    621   LookupIterator it(object, name);
    622   LookupForRead(&it);
    623 
    624   if (it.IsFound() || !ShouldThrowReferenceError()) {
    625     // Update inline cache and stub cache.
    626     if (use_ic) UpdateCaches(&it);
    627 
    628     // Get the property.
    629     Handle<Object> result;
    630 
    631     ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it),
    632                                Object);
    633     if (it.IsFound()) {
    634       return result;
    635     } else if (!ShouldThrowReferenceError()) {
    636       LOG(isolate(), SuspectReadEvent(*name, *object));
    637       return result;
    638     }
    639   }
    640   return ReferenceError(name);
    641 }
    642 
    643 MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name) {
    644   Handle<JSGlobalObject> global = isolate()->global_object();
    645 
    646   if (name->IsString()) {
    647     // Look up in script context table.
    648     Handle<String> str_name = Handle<String>::cast(name);
    649     Handle<ScriptContextTable> script_contexts(
    650         global->native_context()->script_context_table());
    651 
    652     ScriptContextTable::LookupResult lookup_result;
    653     if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
    654       Handle<Object> result =
    655           FixedArray::get(*ScriptContextTable::GetContext(
    656                               script_contexts, lookup_result.context_index),
    657                           lookup_result.slot_index, isolate());
    658       if (result->IsTheHole(isolate())) {
    659         // Do not install stubs and stay pre-monomorphic for
    660         // uninitialized accesses.
    661         return ReferenceError(name);
    662       }
    663 
    664       if (FLAG_use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) {
    665         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadScriptContextFieldStub);
    666         LoadScriptContextFieldStub stub(isolate(), &lookup_result);
    667         PatchCache(name, stub.GetCode());
    668         TRACE_IC("LoadGlobalIC", name);
    669       }
    670       return result;
    671     }
    672   }
    673   return LoadIC::Load(global, name);
    674 }
    675 
    676 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
    677                                        Handle<Map> new_receiver_map) {
    678   DCHECK(!new_receiver_map.is_null());
    679   for (int current = 0; current < receiver_maps->length(); ++current) {
    680     if (!receiver_maps->at(current).is_null() &&
    681         receiver_maps->at(current).is_identical_to(new_receiver_map)) {
    682       return false;
    683     }
    684   }
    685   receiver_maps->Add(new_receiver_map);
    686   return true;
    687 }
    688 
    689 
    690 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) {
    691   if (!code->is_handler()) return false;
    692   if (is_keyed() && state() != RECOMPUTE_HANDLER) return false;
    693   Handle<Map> map = receiver_map();
    694   MapHandleList maps;
    695   CodeHandleList handlers;
    696 
    697   TargetMaps(&maps);
    698   int number_of_maps = maps.length();
    699   int deprecated_maps = 0;
    700   int handler_to_overwrite = -1;
    701 
    702   for (int i = 0; i < number_of_maps; i++) {
    703     Handle<Map> current_map = maps.at(i);
    704     if (current_map->is_deprecated()) {
    705       // Filter out deprecated maps to ensure their instances get migrated.
    706       ++deprecated_maps;
    707     } else if (map.is_identical_to(current_map)) {
    708       // If the receiver type is already in the polymorphic IC, this indicates
    709       // there was a prototoype chain failure. In that case, just overwrite the
    710       // handler.
    711       handler_to_overwrite = i;
    712     } else if (handler_to_overwrite == -1 &&
    713                IsTransitionOfMonomorphicTarget(*current_map, *map)) {
    714       handler_to_overwrite = i;
    715     }
    716   }
    717 
    718   int number_of_valid_maps =
    719       number_of_maps - deprecated_maps - (handler_to_overwrite != -1);
    720 
    721   if (number_of_valid_maps >= 4) return false;
    722   if (number_of_maps == 0 && state() != MONOMORPHIC && state() != POLYMORPHIC) {
    723     return false;
    724   }
    725   DCHECK(UseVector());
    726   if (!nexus()->FindHandlers(&handlers, maps.length())) return false;
    727 
    728   number_of_valid_maps++;
    729   if (number_of_valid_maps > 1 && is_keyed()) return false;
    730   Handle<Code> ic;
    731   if (number_of_valid_maps == 1) {
    732     ConfigureVectorState(name, receiver_map(), code);
    733   } else {
    734     if (handler_to_overwrite >= 0) {
    735       handlers.Set(handler_to_overwrite, code);
    736       if (!map.is_identical_to(maps.at(handler_to_overwrite))) {
    737         maps.Set(handler_to_overwrite, map);
    738       }
    739     } else {
    740       maps.Add(map);
    741       handlers.Add(code);
    742     }
    743 
    744     ConfigureVectorState(name, &maps, &handlers);
    745   }
    746 
    747   return true;
    748 }
    749 
    750 
    751 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) {
    752   DCHECK(handler->is_handler());
    753   ConfigureVectorState(name, receiver_map(), handler);
    754 }
    755 
    756 
    757 void IC::CopyICToMegamorphicCache(Handle<Name> name) {
    758   MapHandleList maps;
    759   CodeHandleList handlers;
    760   TargetMaps(&maps);
    761   if (!nexus()->FindHandlers(&handlers, maps.length())) return;
    762   for (int i = 0; i < maps.length(); i++) {
    763     UpdateMegamorphicCache(*maps.at(i), *name, *handlers.at(i));
    764   }
    765 }
    766 
    767 
    768 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
    769   if (source_map == NULL) return true;
    770   if (target_map == NULL) return false;
    771   ElementsKind target_elements_kind = target_map->elements_kind();
    772   bool more_general_transition = IsMoreGeneralElementsKindTransition(
    773       source_map->elements_kind(), target_elements_kind);
    774   Map* transitioned_map = nullptr;
    775   if (more_general_transition) {
    776     MapHandleList map_list;
    777     map_list.Add(handle(target_map));
    778     transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list);
    779   }
    780   return transitioned_map == target_map;
    781 }
    782 
    783 
    784 void IC::PatchCache(Handle<Name> name, Handle<Code> code) {
    785   switch (state()) {
    786     case UNINITIALIZED:
    787     case PREMONOMORPHIC:
    788       UpdateMonomorphicIC(code, name);
    789       break;
    790     case RECOMPUTE_HANDLER:
    791     case MONOMORPHIC:
    792       if (kind() == Code::LOAD_GLOBAL_IC) {
    793         UpdateMonomorphicIC(code, name);
    794         break;
    795       }
    796     // Fall through.
    797     case POLYMORPHIC:
    798       if (!is_keyed() || state() == RECOMPUTE_HANDLER) {
    799         if (UpdatePolymorphicIC(name, code)) break;
    800         // For keyed stubs, we can't know whether old handlers were for the
    801         // same key.
    802         CopyICToMegamorphicCache(name);
    803       }
    804       DCHECK(UseVector());
    805       ConfigureVectorState(MEGAMORPHIC, name);
    806     // Fall through.
    807     case MEGAMORPHIC:
    808       UpdateMegamorphicCache(*receiver_map(), *name, *code);
    809       // Indicate that we've handled this case.
    810       DCHECK(UseVector());
    811       vector_set_ = true;
    812       break;
    813     case GENERIC:
    814       UNREACHABLE();
    815       break;
    816   }
    817 }
    818 
    819 Handle<Code> LoadIC::initialize_stub_in_optimized_code(Isolate* isolate) {
    820   if (FLAG_tf_load_ic_stub) {
    821     return LoadICTFStub(isolate).GetCode();
    822   }
    823   return LoadICStub(isolate).GetCode();
    824 }
    825 
    826 Handle<Code> LoadGlobalIC::initialize_stub_in_optimized_code(
    827     Isolate* isolate, ExtraICState extra_state) {
    828   return LoadGlobalICStub(isolate, LoadGlobalICState(extra_state)).GetCode();
    829 }
    830 
    831 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
    832     Isolate* isolate, ExtraICState extra_state) {
    833   // TODO(ishell): remove extra_ic_state
    834   return KeyedLoadICStub(isolate).GetCode();
    835 }
    836 
    837 Handle<Code> KeyedStoreIC::initialize_stub_in_optimized_code(
    838     Isolate* isolate, LanguageMode language_mode) {
    839   StoreICState state = StoreICState(language_mode);
    840   return VectorKeyedStoreICStub(isolate, state).GetCode();
    841 }
    842 
    843 
    844 Handle<Code> KeyedStoreIC::ChooseMegamorphicStub(Isolate* isolate,
    845                                                  ExtraICState extra_state) {
    846   LanguageMode mode = StoreICState::GetLanguageMode(extra_state);
    847   return is_strict(mode)
    848              ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
    849              : isolate->builtins()->KeyedStoreIC_Megamorphic();
    850 }
    851 
    852 
    853 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
    854   TRACE_HANDLER_STATS(isolate(), LoadIC_LoadFieldStub);
    855   LoadFieldStub stub(isolate(), index);
    856   return stub.GetCode();
    857 }
    858 
    859 
    860 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
    861   DCHECK(lookup->state() == LookupIterator::ACCESSOR);
    862   Isolate* isolate = lookup->isolate();
    863   Handle<Object> accessors = lookup->GetAccessors();
    864   if (accessors->IsAccessorInfo()) {
    865     Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
    866     if (info->getter() != NULL &&
    867         !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) {
    868       return false;
    869     }
    870   } else if (accessors->IsAccessorPair()) {
    871     Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
    872                           isolate);
    873     if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) {
    874       return false;
    875     }
    876     Handle<JSObject> holder = lookup->GetHolder<JSObject>();
    877     Handle<Object> receiver = lookup->GetReceiver();
    878     if (holder->HasFastProperties()) {
    879       if (getter->IsJSFunction()) {
    880         Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
    881         if (!receiver->IsJSObject() && !function->shared()->IsBuiltin() &&
    882             is_sloppy(function->shared()->language_mode())) {
    883           // Calling sloppy non-builtins with a value as the receiver
    884           // requires boxing.
    885           return false;
    886         }
    887       }
    888       CallOptimization call_optimization(getter);
    889       if (call_optimization.is_simple_api_call() &&
    890           !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) {
    891         return false;
    892       }
    893     }
    894   }
    895   return true;
    896 }
    897 
    898 
    899 void LoadIC::UpdateCaches(LookupIterator* lookup) {
    900   if (state() == UNINITIALIZED && kind() != Code::LOAD_GLOBAL_IC) {
    901     // This is the first time we execute this inline cache. Set the target to
    902     // the pre monomorphic stub to delay setting the monomorphic state.
    903     ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
    904     TRACE_IC("LoadIC", lookup->name());
    905     return;
    906   }
    907 
    908   Handle<Code> code;
    909   if (lookup->state() == LookupIterator::JSPROXY ||
    910       lookup->state() == LookupIterator::ACCESS_CHECK) {
    911     code = slow_stub();
    912   } else if (!lookup->IsFound()) {
    913     if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC) {
    914       code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(),
    915                                                               receiver_map());
    916       // TODO(jkummerow/verwaest): Introduce a builtin that handles this case.
    917       if (code.is_null()) code = slow_stub();
    918     } else {
    919       code = slow_stub();
    920     }
    921   } else {
    922     if (kind() == Code::LOAD_GLOBAL_IC &&
    923         lookup->state() == LookupIterator::DATA &&
    924         lookup->GetHolder<Object>()->IsJSGlobalObject()) {
    925 #if DEBUG
    926       Handle<Object> holder = lookup->GetHolder<Object>();
    927       Handle<Object> receiver = lookup->GetReceiver();
    928       DCHECK_EQ(*receiver, *holder);
    929 #endif
    930       // Now update the cell in the feedback vector.
    931       LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>();
    932       nexus->ConfigurePropertyCellMode(lookup->GetPropertyCell());
    933       TRACE_IC("LoadGlobalIC", lookup->name());
    934       return;
    935     } else if (lookup->state() == LookupIterator::ACCESSOR) {
    936       if (!IsCompatibleReceiver(lookup, receiver_map())) {
    937         TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
    938         code = slow_stub();
    939       }
    940     } else if (lookup->state() == LookupIterator::INTERCEPTOR) {
    941       if (kind() == Code::LOAD_GLOBAL_IC) {
    942         // The interceptor handler requires name but it is not passed explicitly
    943         // to LoadGlobalIC and the LoadGlobalIC dispatcher also does not load
    944         // it so we will just use slow stub.
    945         code = slow_stub();
    946       } else {
    947         // Perform a lookup behind the interceptor. Copy the LookupIterator
    948         // since the original iterator will be used to fetch the value.
    949         LookupIterator it = *lookup;
    950         it.Next();
    951         LookupForRead(&it);
    952         if (it.state() == LookupIterator::ACCESSOR &&
    953             !IsCompatibleReceiver(&it, receiver_map())) {
    954           TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
    955           code = slow_stub();
    956         }
    957       }
    958     }
    959     if (code.is_null()) code = ComputeHandler(lookup);
    960   }
    961 
    962   PatchCache(lookup->name(), code);
    963   TRACE_IC("LoadIC", lookup->name());
    964 }
    965 
    966 
    967 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
    968   isolate()->stub_cache()->Set(name, map, code);
    969 }
    970 
    971 
    972 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
    973   // Try to find a globally shared handler stub.
    974   Handle<Code> code = GetMapIndependentHandler(lookup);
    975   if (!code.is_null()) return code;
    976 
    977   // Otherwise check the map's handler cache for a map-specific handler, and
    978   // compile one if the cache comes up empty.
    979   bool receiver_is_holder =
    980       lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
    981   CacheHolderFlag flag;
    982   Handle<Map> stub_holder_map;
    983   if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC ||
    984       kind() == Code::KEYED_LOAD_IC) {
    985     stub_holder_map = IC::GetHandlerCacheHolder(
    986         receiver_map(), receiver_is_holder, isolate(), &flag);
    987   } else {
    988     DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC);
    989     // Store handlers cannot be cached on prototypes.
    990     flag = kCacheOnReceiver;
    991     stub_holder_map = receiver_map();
    992   }
    993 
    994   code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(),
    995                                        flag);
    996   // Use the cached value if it exists, and if it is different from the
    997   // handler that just missed.
    998   if (!code.is_null()) {
    999     Handle<Code> handler;
   1000     if (maybe_handler_.ToHandle(&handler)) {
   1001       if (!handler.is_identical_to(code)) {
   1002         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
   1003         return code;
   1004       }
   1005     } else {
   1006       // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs.
   1007       // In MEGAMORPHIC case, check if the handler in the megamorphic stub
   1008       // cache (which just missed) is different from the cached handler.
   1009       if (state() == MEGAMORPHIC && lookup->GetReceiver()->IsHeapObject()) {
   1010         Map* map = Handle<HeapObject>::cast(lookup->GetReceiver())->map();
   1011         Code* megamorphic_cached_code =
   1012             isolate()->stub_cache()->Get(*lookup->name(), map, code->flags());
   1013         if (megamorphic_cached_code != *code) {
   1014           TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
   1015           return code;
   1016         }
   1017       } else {
   1018         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit);
   1019         return code;
   1020       }
   1021     }
   1022   }
   1023 
   1024   code = CompileHandler(lookup, value, flag);
   1025   DCHECK(code->is_handler());
   1026   DCHECK(Code::ExtractCacheHolderFromFlags(code->flags()) == flag);
   1027   Map::UpdateCodeCache(stub_holder_map, lookup->name(), code);
   1028 
   1029   return code;
   1030 }
   1031 
   1032 Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) {
   1033   Handle<Object> receiver = lookup->GetReceiver();
   1034   if (receiver->IsString() &&
   1035       Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
   1036     FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset);
   1037     return SimpleFieldLoad(index);
   1038   }
   1039 
   1040   if (receiver->IsStringWrapper() &&
   1041       Name::Equals(isolate()->factory()->length_string(), lookup->name())) {
   1042     TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub);
   1043     StringLengthStub string_length_stub(isolate());
   1044     return string_length_stub.GetCode();
   1045   }
   1046 
   1047   // Use specialized code for getting prototype of functions.
   1048   if (receiver->IsJSFunction() &&
   1049       Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) &&
   1050       receiver->IsConstructor() &&
   1051       !Handle<JSFunction>::cast(receiver)
   1052            ->map()
   1053            ->has_non_instance_prototype()) {
   1054     Handle<Code> stub;
   1055     TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub);
   1056     FunctionPrototypeStub function_prototype_stub(isolate());
   1057     return function_prototype_stub.GetCode();
   1058   }
   1059 
   1060   Handle<Map> map = receiver_map();
   1061   Handle<JSObject> holder = lookup->GetHolder<JSObject>();
   1062   bool receiver_is_holder = receiver.is_identical_to(holder);
   1063   switch (lookup->state()) {
   1064     case LookupIterator::INTERCEPTOR:
   1065       break;  // Custom-compiled handler.
   1066 
   1067     case LookupIterator::ACCESSOR: {
   1068       // Use simple field loads for some well-known callback properties.
   1069       // The method will only return true for absolute truths based on the
   1070       // receiver maps.
   1071       int object_offset;
   1072       if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
   1073                                              &object_offset)) {
   1074         FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map);
   1075         return SimpleFieldLoad(index);
   1076       }
   1077 
   1078       if (IsCompatibleReceiver(lookup, map)) {
   1079         Handle<Object> accessors = lookup->GetAccessors();
   1080         if (accessors->IsAccessorPair()) {
   1081           if (!holder->HasFastProperties()) {
   1082             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1083             return slow_stub();
   1084           }
   1085           // When debugging we need to go the slow path to flood the accessor.
   1086           if (GetSharedFunctionInfo()->HasDebugInfo()) {
   1087             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1088             return slow_stub();
   1089           }
   1090           break;  // Custom-compiled handler.
   1091         } else if (accessors->IsAccessorInfo()) {
   1092           Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
   1093           if (v8::ToCData<Address>(info->getter()) == nullptr) {
   1094             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1095             return slow_stub();
   1096           }
   1097           // Ruled out by IsCompatibleReceiver() above.
   1098           DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map));
   1099           if (!holder->HasFastProperties()) return slow_stub();
   1100           if (receiver_is_holder) {
   1101             TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub);
   1102             int index = lookup->GetAccessorIndex();
   1103             LoadApiGetterStub stub(isolate(), true, index);
   1104             return stub.GetCode();
   1105           }
   1106           if (info->is_sloppy() && !receiver->IsJSReceiver()) {
   1107             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1108             return slow_stub();
   1109           }
   1110           break;  // Custom-compiled handler.
   1111         }
   1112       }
   1113       TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1114       return slow_stub();
   1115     }
   1116 
   1117     case LookupIterator::DATA: {
   1118       if (lookup->is_dictionary_holder()) {
   1119         if (kind() != Code::LOAD_IC && kind() != Code::LOAD_GLOBAL_IC) {
   1120           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1121           return slow_stub();
   1122         }
   1123         if (holder->IsJSGlobalObject()) {
   1124           break;  // Custom-compiled handler.
   1125         }
   1126         // There is only one shared stub for loading normalized
   1127         // properties. It does not traverse the prototype chain, so the
   1128         // property must be found in the object for the stub to be
   1129         // applicable.
   1130         if (!receiver_is_holder) {
   1131           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1132           return slow_stub();
   1133         }
   1134         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal);
   1135         return isolate()->builtins()->LoadIC_Normal();
   1136       }
   1137 
   1138       // -------------- Fields --------------
   1139       if (lookup->property_details().type() == DATA) {
   1140         FieldIndex field = lookup->GetFieldIndex();
   1141         if (receiver_is_holder) {
   1142           return SimpleFieldLoad(field);
   1143         }
   1144         break;  // Custom-compiled handler.
   1145       }
   1146 
   1147       // -------------- Constant properties --------------
   1148       DCHECK(lookup->property_details().type() == DATA_CONSTANT);
   1149       if (receiver_is_holder) {
   1150         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub);
   1151         LoadConstantStub stub(isolate(), lookup->GetConstantIndex());
   1152         return stub.GetCode();
   1153       }
   1154       break;  // Custom-compiled handler.
   1155     }
   1156 
   1157     case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1158       TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
   1159       return slow_stub();
   1160     case LookupIterator::ACCESS_CHECK:
   1161     case LookupIterator::JSPROXY:
   1162     case LookupIterator::NOT_FOUND:
   1163     case LookupIterator::TRANSITION:
   1164       UNREACHABLE();
   1165   }
   1166 
   1167   return Handle<Code>::null();
   1168 }
   1169 
   1170 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
   1171                                     Handle<Object> unused,
   1172                                     CacheHolderFlag cache_holder) {
   1173   Handle<JSObject> holder = lookup->GetHolder<JSObject>();
   1174 #ifdef DEBUG
   1175   // Only used by DCHECKs below.
   1176   Handle<Object> receiver = lookup->GetReceiver();
   1177   bool receiver_is_holder = receiver.is_identical_to(holder);
   1178 #endif
   1179   // Non-map-specific handler stubs have already been selected.
   1180   DCHECK(!receiver->IsString() ||
   1181          !Name::Equals(isolate()->factory()->length_string(), lookup->name()));
   1182   DCHECK(!receiver->IsStringWrapper() ||
   1183          !Name::Equals(isolate()->factory()->length_string(), lookup->name()));
   1184 
   1185   DCHECK(!(
   1186       receiver->IsJSFunction() &&
   1187       Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) &&
   1188       receiver->IsConstructor() &&
   1189       !Handle<JSFunction>::cast(receiver)
   1190            ->map()
   1191            ->has_non_instance_prototype()));
   1192 
   1193   Handle<Map> map = receiver_map();
   1194   switch (lookup->state()) {
   1195     case LookupIterator::INTERCEPTOR: {
   1196       DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined(isolate()));
   1197       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor);
   1198       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1199       // Perform a lookup behind the interceptor. Copy the LookupIterator since
   1200       // the original iterator will be used to fetch the value.
   1201       LookupIterator it = *lookup;
   1202       it.Next();
   1203       LookupForRead(&it);
   1204       return compiler.CompileLoadInterceptor(&it);
   1205     }
   1206 
   1207     case LookupIterator::ACCESSOR: {
   1208 #ifdef DEBUG
   1209       int object_offset;
   1210       DCHECK(!Accessors::IsJSObjectFieldAccessor(map, lookup->name(),
   1211                                                  &object_offset));
   1212 #endif
   1213 
   1214       DCHECK(IsCompatibleReceiver(lookup, map));
   1215       Handle<Object> accessors = lookup->GetAccessors();
   1216       if (accessors->IsAccessorPair()) {
   1217         DCHECK(holder->HasFastProperties());
   1218         DCHECK(!GetSharedFunctionInfo()->HasDebugInfo());
   1219         Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
   1220                               isolate());
   1221         CallOptimization call_optimization(getter);
   1222         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1223         if (call_optimization.is_simple_api_call()) {
   1224           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
   1225           int index = lookup->GetAccessorIndex();
   1226           Handle<Code> code = compiler.CompileLoadCallback(
   1227               lookup->name(), call_optimization, index);
   1228           return code;
   1229         }
   1230         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter);
   1231         int expected_arguments = Handle<JSFunction>::cast(getter)
   1232                                      ->shared()
   1233                                      ->internal_formal_parameter_count();
   1234         return compiler.CompileLoadViaGetter(
   1235             lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
   1236       } else {
   1237         DCHECK(accessors->IsAccessorInfo());
   1238         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
   1239         DCHECK(v8::ToCData<Address>(info->getter()) != nullptr);
   1240         DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map));
   1241         DCHECK(holder->HasFastProperties());
   1242         DCHECK(!receiver_is_holder);
   1243         DCHECK(!info->is_sloppy() || receiver->IsJSReceiver());
   1244         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback);
   1245         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1246         Handle<Code> code = compiler.CompileLoadCallback(lookup->name(), info);
   1247         return code;
   1248       }
   1249       UNREACHABLE();
   1250     }
   1251 
   1252     case LookupIterator::DATA: {
   1253       if (lookup->is_dictionary_holder()) {
   1254         DCHECK(kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC);
   1255         DCHECK(holder->IsJSGlobalObject());
   1256         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal);
   1257         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1258         Handle<PropertyCell> cell = lookup->GetPropertyCell();
   1259         Handle<Code> code = compiler.CompileLoadGlobal(
   1260             cell, lookup->name(), lookup->IsConfigurable());
   1261         return code;
   1262       }
   1263 
   1264       // -------------- Fields --------------
   1265       if (lookup->property_details().type() == DATA) {
   1266         FieldIndex field = lookup->GetFieldIndex();
   1267         DCHECK(!receiver_is_holder);
   1268         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField);
   1269         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1270         return compiler.CompileLoadField(lookup->name(), field);
   1271       }
   1272 
   1273       // -------------- Constant properties --------------
   1274       DCHECK(lookup->property_details().type() == DATA_CONSTANT);
   1275       DCHECK(!receiver_is_holder);
   1276       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant);
   1277       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder);
   1278       return compiler.CompileLoadConstant(lookup->name(),
   1279                                           lookup->GetConstantIndex());
   1280     }
   1281 
   1282     case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1283     case LookupIterator::ACCESS_CHECK:
   1284     case LookupIterator::JSPROXY:
   1285     case LookupIterator::NOT_FOUND:
   1286     case LookupIterator::TRANSITION:
   1287       UNREACHABLE();
   1288   }
   1289   UNREACHABLE();
   1290   return slow_stub();
   1291 }
   1292 
   1293 
   1294 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
   1295   // This helper implements a few common fast cases for converting
   1296   // non-smi keys of keyed loads/stores to a smi or a string.
   1297   if (key->IsHeapNumber()) {
   1298     double value = Handle<HeapNumber>::cast(key)->value();
   1299     if (std::isnan(value)) {
   1300       key = isolate->factory()->nan_string();
   1301     } else {
   1302       int int_value = FastD2I(value);
   1303       if (value == int_value && Smi::IsValid(int_value)) {
   1304         key = handle(Smi::FromInt(int_value), isolate);
   1305       }
   1306     }
   1307   } else if (key->IsUndefined(isolate)) {
   1308     key = isolate->factory()->undefined_string();
   1309   }
   1310   return key;
   1311 }
   1312 
   1313 void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver) {
   1314   Handle<Map> receiver_map(receiver->map(), isolate());
   1315   DCHECK(receiver_map->instance_type() != JS_VALUE_TYPE &&
   1316          receiver_map->instance_type() != JS_PROXY_TYPE);  // Checked by caller.
   1317   MapHandleList target_receiver_maps;
   1318   TargetMaps(&target_receiver_maps);
   1319 
   1320   if (target_receiver_maps.length() == 0) {
   1321     Handle<Code> handler =
   1322         PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
   1323             receiver_map, extra_ic_state());
   1324     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
   1325   }
   1326 
   1327   for (int i = 0; i < target_receiver_maps.length(); i++) {
   1328     Handle<Map> map = target_receiver_maps.at(i);
   1329     if (map.is_null()) continue;
   1330     if (map->instance_type() == JS_VALUE_TYPE) {
   1331       TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "JSValue");
   1332       return;
   1333     }
   1334     if (map->instance_type() == JS_PROXY_TYPE) {
   1335       TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "JSProxy");
   1336       return;
   1337     }
   1338   }
   1339 
   1340   // The first time a receiver is seen that is a transitioned version of the
   1341   // previous monomorphic receiver type, assume the new ElementsKind is the
   1342   // monomorphic type. This benefits global arrays that only transition
   1343   // once, and all call sites accessing them are faster if they remain
   1344   // monomorphic. If this optimistic assumption is not true, the IC will
   1345   // miss again and it will become polymorphic and support both the
   1346   // untransitioned and transitioned maps.
   1347   if (state() == MONOMORPHIC && !receiver->IsString() &&
   1348       IsMoreGeneralElementsKindTransition(
   1349           target_receiver_maps.at(0)->elements_kind(),
   1350           Handle<JSObject>::cast(receiver)->GetElementsKind())) {
   1351     Handle<Code> handler =
   1352         PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
   1353             receiver_map, extra_ic_state());
   1354     return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
   1355   }
   1356 
   1357   DCHECK(state() != GENERIC);
   1358 
   1359   // Determine the list of receiver maps that this call site has seen,
   1360   // adding the map that was just encountered.
   1361   if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
   1362     // If the miss wasn't due to an unseen map, a polymorphic stub
   1363     // won't help, use the generic stub.
   1364     TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
   1365     return;
   1366   }
   1367 
   1368   // If the maximum number of receiver maps has been exceeded, use the generic
   1369   // version of the IC.
   1370   if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
   1371     TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
   1372     return;
   1373   }
   1374 
   1375   CodeHandleList handlers(target_receiver_maps.length());
   1376   TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_PolymorphicElement);
   1377   ElementHandlerCompiler compiler(isolate());
   1378   compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
   1379   ConfigureVectorState(Handle<Name>(), &target_receiver_maps, &handlers);
   1380 }
   1381 
   1382 
   1383 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
   1384                                       Handle<Object> key) {
   1385   if (MigrateDeprecated(object)) {
   1386     Handle<Object> result;
   1387     ASSIGN_RETURN_ON_EXCEPTION(
   1388         isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
   1389         Object);
   1390     return result;
   1391   }
   1392 
   1393   Handle<Object> load_handle;
   1394 
   1395   // Check for non-string values that can be converted into an
   1396   // internalized string directly or is representable as a smi.
   1397   key = TryConvertKey(key, isolate());
   1398 
   1399   uint32_t index;
   1400   if ((key->IsInternalizedString() &&
   1401        !String::cast(*key)->AsArrayIndex(&index)) ||
   1402       key->IsSymbol()) {
   1403     ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle,
   1404                                LoadIC::Load(object, Handle<Name>::cast(key)),
   1405                                Object);
   1406   } else if (FLAG_use_ic && !object->IsAccessCheckNeeded() &&
   1407              !object->IsJSValue()) {
   1408     if (object->IsJSObject() || (object->IsString() && key->IsNumber())) {
   1409       Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
   1410       if (object->IsString() || key->IsSmi()) UpdateLoadElement(receiver);
   1411     }
   1412   }
   1413 
   1414   if (!is_vector_set()) {
   1415     ConfigureVectorState(MEGAMORPHIC, key);
   1416     TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
   1417   }
   1418   TRACE_IC("LoadIC", key);
   1419 
   1420   if (!load_handle.is_null()) return load_handle;
   1421 
   1422   Handle<Object> result;
   1423   ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
   1424                              Runtime::GetObjectProperty(isolate(), object, key),
   1425                              Object);
   1426   return result;
   1427 }
   1428 
   1429 
   1430 bool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value,
   1431                              JSReceiver::StoreFromKeyed store_mode) {
   1432   // Disable ICs for non-JSObjects for now.
   1433   Handle<Object> object = it->GetReceiver();
   1434   if (!object->IsJSObject()) return false;
   1435   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
   1436   DCHECK(!receiver->map()->is_deprecated());
   1437 
   1438   for (; it->IsFound(); it->Next()) {
   1439     switch (it->state()) {
   1440       case LookupIterator::NOT_FOUND:
   1441       case LookupIterator::TRANSITION:
   1442         UNREACHABLE();
   1443       case LookupIterator::JSPROXY:
   1444         return false;
   1445       case LookupIterator::INTERCEPTOR: {
   1446         Handle<JSObject> holder = it->GetHolder<JSObject>();
   1447         InterceptorInfo* info = holder->GetNamedInterceptor();
   1448         if (it->HolderIsReceiverOrHiddenPrototype()) {
   1449           return !info->non_masking() && receiver.is_identical_to(holder) &&
   1450                  !info->setter()->IsUndefined(it->isolate());
   1451         } else if (!info->getter()->IsUndefined(it->isolate()) ||
   1452                    !info->query()->IsUndefined(it->isolate())) {
   1453           return false;
   1454         }
   1455         break;
   1456       }
   1457       case LookupIterator::ACCESS_CHECK:
   1458         if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false;
   1459         break;
   1460       case LookupIterator::ACCESSOR:
   1461         return !it->IsReadOnly();
   1462       case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1463         return false;
   1464       case LookupIterator::DATA: {
   1465         if (it->IsReadOnly()) return false;
   1466         Handle<JSObject> holder = it->GetHolder<JSObject>();
   1467         if (receiver.is_identical_to(holder)) {
   1468           it->PrepareForDataProperty(value);
   1469           // The previous receiver map might just have been deprecated,
   1470           // so reload it.
   1471           update_receiver_map(receiver);
   1472           return true;
   1473         }
   1474 
   1475         // Receiver != holder.
   1476         if (receiver->IsJSGlobalProxy()) {
   1477           PrototypeIterator iter(it->isolate(), receiver);
   1478           return it->GetHolder<Object>().is_identical_to(
   1479               PrototypeIterator::GetCurrent(iter));
   1480         }
   1481 
   1482         if (it->HolderIsReceiverOrHiddenPrototype()) return false;
   1483 
   1484         if (it->ExtendingNonExtensible(receiver)) return false;
   1485         it->PrepareTransitionToDataProperty(receiver, value, NONE, store_mode);
   1486         return it->IsCacheableTransition();
   1487       }
   1488     }
   1489   }
   1490 
   1491   receiver = it->GetStoreTarget();
   1492   if (it->ExtendingNonExtensible(receiver)) return false;
   1493   it->PrepareTransitionToDataProperty(receiver, value, NONE, store_mode);
   1494   return it->IsCacheableTransition();
   1495 }
   1496 
   1497 
   1498 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
   1499                                    Handle<Object> value,
   1500                                    JSReceiver::StoreFromKeyed store_mode) {
   1501   if (object->IsJSGlobalObject() && name->IsString()) {
   1502     // Look up in script context table.
   1503     Handle<String> str_name = Handle<String>::cast(name);
   1504     Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object);
   1505     Handle<ScriptContextTable> script_contexts(
   1506         global->native_context()->script_context_table());
   1507 
   1508     ScriptContextTable::LookupResult lookup_result;
   1509     if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
   1510       Handle<Context> script_context = ScriptContextTable::GetContext(
   1511           script_contexts, lookup_result.context_index);
   1512       if (lookup_result.mode == CONST) {
   1513         return TypeError(MessageTemplate::kConstAssign, object, name);
   1514       }
   1515 
   1516       Handle<Object> previous_value =
   1517           FixedArray::get(*script_context, lookup_result.slot_index, isolate());
   1518 
   1519       if (previous_value->IsTheHole(isolate())) {
   1520         // Do not install stubs and stay pre-monomorphic for
   1521         // uninitialized accesses.
   1522         return ReferenceError(name);
   1523       }
   1524 
   1525       if (FLAG_use_ic &&
   1526           StoreScriptContextFieldStub::Accepted(&lookup_result)) {
   1527         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreScriptContextFieldStub);
   1528         StoreScriptContextFieldStub stub(isolate(), &lookup_result);
   1529         PatchCache(name, stub.GetCode());
   1530       }
   1531 
   1532       script_context->set(lookup_result.slot_index, *value);
   1533       return value;
   1534     }
   1535   }
   1536 
   1537   // TODO(verwaest): Let SetProperty do the migration, since storing a property
   1538   // might deprecate the current map again, if value does not fit.
   1539   if (MigrateDeprecated(object) || object->IsJSProxy()) {
   1540     Handle<Object> result;
   1541     ASSIGN_RETURN_ON_EXCEPTION(
   1542         isolate(), result,
   1543         Object::SetProperty(object, name, value, language_mode()), Object);
   1544     return result;
   1545   }
   1546 
   1547   // If the object is undefined or null it's illegal to try to set any
   1548   // properties on it; throw a TypeError in that case.
   1549   if (object->IsUndefined(isolate()) || object->IsNull(isolate())) {
   1550     return TypeError(MessageTemplate::kNonObjectPropertyStore, object, name);
   1551   }
   1552 
   1553   if (state() != UNINITIALIZED) {
   1554     JSObject::MakePrototypesFast(object, kStartAtPrototype, isolate());
   1555   }
   1556   LookupIterator it(object, name);
   1557   if (FLAG_use_ic) UpdateCaches(&it, value, store_mode);
   1558 
   1559   MAYBE_RETURN_NULL(
   1560       Object::SetProperty(&it, value, language_mode(), store_mode));
   1561   return value;
   1562 }
   1563 
   1564 Handle<Code> CallIC::initialize_stub_in_optimized_code(
   1565     Isolate* isolate, int argc, ConvertReceiverMode mode,
   1566     TailCallMode tail_call_mode) {
   1567   CallICStub stub(isolate, CallICState(argc, mode, tail_call_mode));
   1568   Handle<Code> code = stub.GetCode();
   1569   return code;
   1570 }
   1571 
   1572 Handle<Code> StoreIC::initialize_stub_in_optimized_code(
   1573     Isolate* isolate, LanguageMode language_mode) {
   1574   VectorStoreICStub stub(isolate, StoreICState(language_mode));
   1575   return stub.GetCode();
   1576 }
   1577 
   1578 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
   1579                            JSReceiver::StoreFromKeyed store_mode) {
   1580   if (state() == UNINITIALIZED) {
   1581     // This is the first time we execute this inline cache. Set the target to
   1582     // the pre monomorphic stub to delay setting the monomorphic state.
   1583     ConfigureVectorState(PREMONOMORPHIC, Handle<Object>());
   1584     TRACE_IC("StoreIC", lookup->name());
   1585     return;
   1586   }
   1587 
   1588   bool use_ic = LookupForWrite(lookup, value, store_mode);
   1589   if (!use_ic) {
   1590     TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'");
   1591   }
   1592   Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub();
   1593 
   1594   PatchCache(lookup->name(), code);
   1595   TRACE_IC("StoreIC", lookup->name());
   1596 }
   1597 
   1598 
   1599 static Handle<Code> PropertyCellStoreHandler(
   1600     Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder,
   1601     Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) {
   1602   auto constant_type = Nothing<PropertyCellConstantType>();
   1603   if (type == PropertyCellType::kConstantType) {
   1604     constant_type = Just(cell->GetConstantType());
   1605   }
   1606   StoreGlobalStub stub(isolate, type, constant_type,
   1607                        receiver->IsJSGlobalProxy());
   1608   auto code = stub.GetCodeCopyFromTemplate(holder, cell);
   1609   // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
   1610   HeapObject::UpdateMapCodeCache(receiver, name, code);
   1611   return code;
   1612 }
   1613 
   1614 Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) {
   1615   DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
   1616 
   1617   // This is currently guaranteed by checks in StoreIC::Store.
   1618   Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
   1619   Handle<JSObject> holder = lookup->GetHolder<JSObject>();
   1620   DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
   1621 
   1622   switch (lookup->state()) {
   1623     case LookupIterator::TRANSITION: {
   1624       auto store_target = lookup->GetStoreTarget();
   1625       if (store_target->IsJSGlobalObject()) {
   1626         break;  // Custom-compiled handler.
   1627       }
   1628       // Currently not handled by CompileStoreTransition.
   1629       if (!holder->HasFastProperties()) {
   1630         TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow");
   1631         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1632         return slow_stub();
   1633       }
   1634 
   1635       DCHECK(lookup->IsCacheableTransition());
   1636       break;  // Custom-compiled handler.
   1637     }
   1638 
   1639     case LookupIterator::INTERCEPTOR: {
   1640       DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate()));
   1641       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
   1642       StoreInterceptorStub stub(isolate());
   1643       return stub.GetCode();
   1644     }
   1645 
   1646     case LookupIterator::ACCESSOR: {
   1647       if (!holder->HasFastProperties()) {
   1648         TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map");
   1649         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1650         return slow_stub();
   1651       }
   1652       Handle<Object> accessors = lookup->GetAccessors();
   1653       if (accessors->IsAccessorInfo()) {
   1654         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
   1655         if (v8::ToCData<Address>(info->setter()) == nullptr) {
   1656           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == nullptr");
   1657           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1658           return slow_stub();
   1659         }
   1660         if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
   1661             !lookup->HolderIsReceiverOrHiddenPrototype()) {
   1662           TRACE_GENERIC_IC(isolate(), "StoreIC",
   1663                            "special data property in prototype chain");
   1664           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1665           return slow_stub();
   1666         }
   1667         if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info,
   1668                                                    receiver_map())) {
   1669           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type");
   1670           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1671           return slow_stub();
   1672         }
   1673         if (info->is_sloppy() && !receiver->IsJSReceiver()) {
   1674           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1675           return slow_stub();
   1676         }
   1677         break;  // Custom-compiled handler.
   1678       } else if (accessors->IsAccessorPair()) {
   1679         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
   1680                               isolate());
   1681         if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) {
   1682           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function");
   1683           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1684           return slow_stub();
   1685         }
   1686         CallOptimization call_optimization(setter);
   1687         if (call_optimization.is_simple_api_call()) {
   1688           if (call_optimization.IsCompatibleReceiver(receiver, holder)) {
   1689             break;  // Custom-compiled handler.
   1690           }
   1691           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver");
   1692           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1693           return slow_stub();
   1694         }
   1695         break;  // Custom-compiled handler.
   1696       }
   1697       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1698       return slow_stub();
   1699     }
   1700 
   1701     case LookupIterator::DATA: {
   1702       if (lookup->is_dictionary_holder()) {
   1703         if (holder->IsJSGlobalObject()) {
   1704           break;  // Custom-compiled handler.
   1705         }
   1706         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal);
   1707         DCHECK(holder.is_identical_to(receiver));
   1708         return isolate()->builtins()->StoreIC_Normal();
   1709       }
   1710 
   1711       // -------------- Fields --------------
   1712       if (lookup->property_details().type() == DATA) {
   1713         bool use_stub = true;
   1714         if (lookup->representation().IsHeapObject()) {
   1715           // Only use a generic stub if no types need to be tracked.
   1716           Handle<FieldType> field_type = lookup->GetFieldType();
   1717           use_stub = !field_type->IsClass();
   1718         }
   1719         if (use_stub) {
   1720           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub);
   1721           StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
   1722                               lookup->representation());
   1723           return stub.GetCode();
   1724         }
   1725         break;  // Custom-compiled handler.
   1726       }
   1727 
   1728       // -------------- Constant properties --------------
   1729       DCHECK(lookup->property_details().type() == DATA_CONSTANT);
   1730       TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property");
   1731       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
   1732       return slow_stub();
   1733     }
   1734 
   1735     case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1736     case LookupIterator::ACCESS_CHECK:
   1737     case LookupIterator::JSPROXY:
   1738     case LookupIterator::NOT_FOUND:
   1739       UNREACHABLE();
   1740   }
   1741   return Handle<Code>::null();
   1742 }
   1743 
   1744 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
   1745                                      Handle<Object> value,
   1746                                      CacheHolderFlag cache_holder) {
   1747   DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
   1748 
   1749   // This is currently guaranteed by checks in StoreIC::Store.
   1750   Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
   1751   Handle<JSObject> holder = lookup->GetHolder<JSObject>();
   1752   DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate());
   1753 
   1754   switch (lookup->state()) {
   1755     case LookupIterator::TRANSITION: {
   1756       auto store_target = lookup->GetStoreTarget();
   1757       if (store_target->IsJSGlobalObject()) {
   1758         // TODO(dcarney): this currently just deopts. Use the transition cell.
   1759         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition);
   1760         auto cell = isolate()->factory()->NewPropertyCell();
   1761         cell->set_value(*value);
   1762         auto code = PropertyCellStoreHandler(
   1763             isolate(), store_target, Handle<JSGlobalObject>::cast(store_target),
   1764             lookup->name(), cell, PropertyCellType::kConstant);
   1765         cell->set_value(isolate()->heap()->the_hole_value());
   1766         return code;
   1767       }
   1768       Handle<Map> transition = lookup->transition_map();
   1769       // Currently not handled by CompileStoreTransition.
   1770       DCHECK(holder->HasFastProperties());
   1771 
   1772       DCHECK(lookup->IsCacheableTransition());
   1773       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition);
   1774       NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
   1775       return compiler.CompileStoreTransition(transition, lookup->name());
   1776     }
   1777 
   1778     case LookupIterator::INTERCEPTOR:
   1779       UNREACHABLE();
   1780 
   1781     case LookupIterator::ACCESSOR: {
   1782       DCHECK(holder->HasFastProperties());
   1783       Handle<Object> accessors = lookup->GetAccessors();
   1784       if (accessors->IsAccessorInfo()) {
   1785         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors);
   1786         DCHECK(v8::ToCData<Address>(info->setter()) != 0);
   1787         DCHECK(!AccessorInfo::cast(*accessors)->is_special_data_property() ||
   1788                lookup->HolderIsReceiverOrHiddenPrototype());
   1789         DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info,
   1790                                                      receiver_map()));
   1791         DCHECK(!info->is_sloppy() || receiver->IsJSReceiver());
   1792         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
   1793         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
   1794         Handle<Code> code = compiler.CompileStoreCallback(
   1795             receiver, lookup->name(), info, language_mode());
   1796         return code;
   1797       } else {
   1798         DCHECK(accessors->IsAccessorPair());
   1799         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
   1800                               isolate());
   1801         DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo());
   1802         CallOptimization call_optimization(setter);
   1803         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
   1804         if (call_optimization.is_simple_api_call()) {
   1805           DCHECK(call_optimization.IsCompatibleReceiver(receiver, holder));
   1806           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback);
   1807           Handle<Code> code = compiler.CompileStoreCallback(
   1808               receiver, lookup->name(), call_optimization,
   1809               lookup->GetAccessorIndex());
   1810           return code;
   1811         }
   1812         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter);
   1813         int expected_arguments = JSFunction::cast(*setter)
   1814                                      ->shared()
   1815                                      ->internal_formal_parameter_count();
   1816         return compiler.CompileStoreViaSetter(receiver, lookup->name(),
   1817                                               lookup->GetAccessorIndex(),
   1818                                               expected_arguments);
   1819       }
   1820     }
   1821 
   1822     case LookupIterator::DATA: {
   1823       if (lookup->is_dictionary_holder()) {
   1824         DCHECK(holder->IsJSGlobalObject());
   1825         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal);
   1826         DCHECK(holder.is_identical_to(receiver) ||
   1827                receiver->map()->prototype() == *holder);
   1828         auto cell = lookup->GetPropertyCell();
   1829         auto updated_type =
   1830             PropertyCell::UpdatedType(cell, value, lookup->property_details());
   1831         auto code = PropertyCellStoreHandler(
   1832             isolate(), receiver, Handle<JSGlobalObject>::cast(holder),
   1833             lookup->name(), cell, updated_type);
   1834         return code;
   1835       }
   1836 
   1837       // -------------- Fields --------------
   1838       if (lookup->property_details().type() == DATA) {
   1839 #ifdef DEBUG
   1840         bool use_stub = true;
   1841         if (lookup->representation().IsHeapObject()) {
   1842           // Only use a generic stub if no types need to be tracked.
   1843           Handle<FieldType> field_type = lookup->GetFieldType();
   1844           use_stub = !field_type->IsClass();
   1845         }
   1846         DCHECK(!use_stub);
   1847 #endif
   1848         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField);
   1849         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder);
   1850         return compiler.CompileStoreField(lookup);
   1851       }
   1852 
   1853       // -------------- Constant properties --------------
   1854       DCHECK(lookup->property_details().type() == DATA_CONSTANT);
   1855       UNREACHABLE();
   1856     }
   1857 
   1858     case LookupIterator::INTEGER_INDEXED_EXOTIC:
   1859     case LookupIterator::ACCESS_CHECK:
   1860     case LookupIterator::JSPROXY:
   1861     case LookupIterator::NOT_FOUND:
   1862       UNREACHABLE();
   1863   }
   1864   UNREACHABLE();
   1865   return slow_stub();
   1866 }
   1867 
   1868 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
   1869                                       KeyedAccessStoreMode store_mode) {
   1870   MapHandleList target_receiver_maps;
   1871   TargetMaps(&target_receiver_maps);
   1872   if (target_receiver_maps.length() == 0) {
   1873     Handle<Map> monomorphic_map =
   1874         ComputeTransitionedMap(receiver_map, store_mode);
   1875     store_mode = GetNonTransitioningStoreMode(store_mode);
   1876     Handle<Code> handler =
   1877         PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(monomorphic_map,
   1878                                                                 store_mode);
   1879     return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler);
   1880   }
   1881 
   1882   for (int i = 0; i < target_receiver_maps.length(); i++) {
   1883     if (!target_receiver_maps.at(i).is_null() &&
   1884         target_receiver_maps.at(i)->instance_type() == JS_VALUE_TYPE) {
   1885       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "JSValue");
   1886       return;
   1887     }
   1888   }
   1889 
   1890   // There are several special cases where an IC that is MONOMORPHIC can still
   1891   // transition to a different GetNonTransitioningStoreMode IC that handles a
   1892   // superset of the original IC. Handle those here if the receiver map hasn't
   1893   // changed or it has transitioned to a more general kind.
   1894   KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode();
   1895   Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
   1896   if (state() == MONOMORPHIC) {
   1897     Handle<Map> transitioned_receiver_map = receiver_map;
   1898     if (IsTransitionStoreMode(store_mode)) {
   1899       transitioned_receiver_map =
   1900           ComputeTransitionedMap(receiver_map, store_mode);
   1901     }
   1902     if ((receiver_map.is_identical_to(previous_receiver_map) &&
   1903          IsTransitionStoreMode(store_mode)) ||
   1904         IsTransitionOfMonomorphicTarget(*previous_receiver_map,
   1905                                         *transitioned_receiver_map)) {
   1906       // If the "old" and "new" maps are in the same elements map family, or
   1907       // if they at least come from the same origin for a transitioning store,
   1908       // stay MONOMORPHIC and use the map for the most generic ElementsKind.
   1909       store_mode = GetNonTransitioningStoreMode(store_mode);
   1910       Handle<Code> handler =
   1911           PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(
   1912               transitioned_receiver_map, store_mode);
   1913       ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler);
   1914       return;
   1915     }
   1916     if (receiver_map.is_identical_to(previous_receiver_map) &&
   1917         old_store_mode == STANDARD_STORE &&
   1918         (store_mode == STORE_AND_GROW_NO_TRANSITION ||
   1919          store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
   1920          store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
   1921       // A "normal" IC that handles stores can switch to a version that can
   1922       // grow at the end of the array, handle OOB accesses or copy COW arrays
   1923       // and still stay MONOMORPHIC.
   1924       Handle<Code> handler =
   1925           PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(receiver_map,
   1926                                                                   store_mode);
   1927       return ConfigureVectorState(Handle<Name>(), receiver_map, handler);
   1928     }
   1929   }
   1930 
   1931   DCHECK(state() != GENERIC);
   1932 
   1933   bool map_added =
   1934       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
   1935 
   1936   if (IsTransitionStoreMode(store_mode)) {
   1937     Handle<Map> transitioned_receiver_map =
   1938         ComputeTransitionedMap(receiver_map, store_mode);
   1939     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
   1940                                             transitioned_receiver_map);
   1941   }
   1942 
   1943   if (!map_added) {
   1944     // If the miss wasn't due to an unseen map, a polymorphic stub
   1945     // won't help, use the megamorphic stub which can handle everything.
   1946     TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice");
   1947     return;
   1948   }
   1949 
   1950   // If the maximum number of receiver maps has been exceeded, use the
   1951   // megamorphic version of the IC.
   1952   if (target_receiver_maps.length() > kMaxKeyedPolymorphism) return;
   1953 
   1954   // Make sure all polymorphic handlers have the same store mode, otherwise the
   1955   // megamorphic stub must be used.
   1956   store_mode = GetNonTransitioningStoreMode(store_mode);
   1957   if (old_store_mode != STANDARD_STORE) {
   1958     if (store_mode == STANDARD_STORE) {
   1959       store_mode = old_store_mode;
   1960     } else if (store_mode != old_store_mode) {
   1961       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch");
   1962       return;
   1963     }
   1964   }
   1965 
   1966   // If the store mode isn't the standard mode, make sure that all polymorphic
   1967   // receivers are either external arrays, or all "normal" arrays. Otherwise,
   1968   // use the megamorphic stub.
   1969   if (store_mode != STANDARD_STORE) {
   1970     int external_arrays = 0;
   1971     for (int i = 0; i < target_receiver_maps.length(); ++i) {
   1972       if (target_receiver_maps[i]->has_fixed_typed_array_elements()) {
   1973         external_arrays++;
   1974       }
   1975     }
   1976     if (external_arrays != 0 &&
   1977         external_arrays != target_receiver_maps.length()) {
   1978       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
   1979                        "unsupported combination of external and normal arrays");
   1980       return;
   1981     }
   1982   }
   1983 
   1984   TRACE_HANDLER_STATS(isolate(), KeyedStoreIC_Polymorphic);
   1985   MapHandleList transitioned_maps(target_receiver_maps.length());
   1986   CodeHandleList handlers(target_receiver_maps.length());
   1987   PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers(
   1988       &target_receiver_maps, &transitioned_maps, &handlers, store_mode);
   1989   ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers);
   1990 }
   1991 
   1992 
   1993 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
   1994     Handle<Map> map, KeyedAccessStoreMode store_mode) {
   1995   switch (store_mode) {
   1996     case STORE_TRANSITION_TO_OBJECT:
   1997     case STORE_AND_GROW_TRANSITION_TO_OBJECT: {
   1998       ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind())
   1999                               ? FAST_HOLEY_ELEMENTS
   2000                               : FAST_ELEMENTS;
   2001       return Map::TransitionElementsTo(map, kind);
   2002     }
   2003     case STORE_TRANSITION_TO_DOUBLE:
   2004     case STORE_AND_GROW_TRANSITION_TO_DOUBLE: {
   2005       ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind())
   2006                               ? FAST_HOLEY_DOUBLE_ELEMENTS
   2007                               : FAST_DOUBLE_ELEMENTS;
   2008       return Map::TransitionElementsTo(map, kind);
   2009     }
   2010     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
   2011       DCHECK(map->has_fixed_typed_array_elements());
   2012     // Fall through
   2013     case STORE_NO_TRANSITION_HANDLE_COW:
   2014     case STANDARD_STORE:
   2015     case STORE_AND_GROW_NO_TRANSITION:
   2016       return map;
   2017   }
   2018   UNREACHABLE();
   2019   return MaybeHandle<Map>().ToHandleChecked();
   2020 }
   2021 
   2022 
   2023 bool IsOutOfBoundsAccess(Handle<JSObject> receiver, uint32_t index) {
   2024   uint32_t length = 0;
   2025   if (receiver->IsJSArray()) {
   2026     JSArray::cast(*receiver)->length()->ToArrayLength(&length);
   2027   } else {
   2028     length = static_cast<uint32_t>(receiver->elements()->length());
   2029   }
   2030   return index >= length;
   2031 }
   2032 
   2033 
   2034 static KeyedAccessStoreMode GetStoreMode(Handle<JSObject> receiver,
   2035                                          uint32_t index, Handle<Object> value) {
   2036   bool oob_access = IsOutOfBoundsAccess(receiver, index);
   2037   // Don't consider this a growing store if the store would send the receiver to
   2038   // dictionary mode.
   2039   bool allow_growth = receiver->IsJSArray() && oob_access &&
   2040                       !receiver->WouldConvertToSlowElements(index);
   2041   if (allow_growth) {
   2042     // Handle growing array in stub if necessary.
   2043     if (receiver->HasFastSmiElements()) {
   2044       if (value->IsHeapNumber()) {
   2045         return STORE_AND_GROW_TRANSITION_TO_DOUBLE;
   2046       }
   2047       if (value->IsHeapObject()) {
   2048         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
   2049       }
   2050     } else if (receiver->HasFastDoubleElements()) {
   2051       if (!value->IsSmi() && !value->IsHeapNumber()) {
   2052         return STORE_AND_GROW_TRANSITION_TO_OBJECT;
   2053       }
   2054     }
   2055     return STORE_AND_GROW_NO_TRANSITION;
   2056   } else {
   2057     // Handle only in-bounds elements accesses.
   2058     if (receiver->HasFastSmiElements()) {
   2059       if (value->IsHeapNumber()) {
   2060         return STORE_TRANSITION_TO_DOUBLE;
   2061       } else if (value->IsHeapObject()) {
   2062         return STORE_TRANSITION_TO_OBJECT;
   2063       }
   2064     } else if (receiver->HasFastDoubleElements()) {
   2065       if (!value->IsSmi() && !value->IsHeapNumber()) {
   2066         return STORE_TRANSITION_TO_OBJECT;
   2067       }
   2068     }
   2069     if (!FLAG_trace_external_array_abuse &&
   2070         receiver->map()->has_fixed_typed_array_elements() && oob_access) {
   2071       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
   2072     }
   2073     Heap* heap = receiver->GetHeap();
   2074     if (receiver->elements()->map() == heap->fixed_cow_array_map()) {
   2075       return STORE_NO_TRANSITION_HANDLE_COW;
   2076     } else {
   2077       return STANDARD_STORE;
   2078     }
   2079   }
   2080 }
   2081 
   2082 
   2083 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
   2084                                         Handle<Object> key,
   2085                                         Handle<Object> value) {
   2086   // TODO(verwaest): Let SetProperty do the migration, since storing a property
   2087   // might deprecate the current map again, if value does not fit.
   2088   if (MigrateDeprecated(object)) {
   2089     Handle<Object> result;
   2090     ASSIGN_RETURN_ON_EXCEPTION(
   2091         isolate(), result, Runtime::SetObjectProperty(isolate(), object, key,
   2092                                                       value, language_mode()),
   2093         Object);
   2094     return result;
   2095   }
   2096 
   2097   // Check for non-string values that can be converted into an
   2098   // internalized string directly or is representable as a smi.
   2099   key = TryConvertKey(key, isolate());
   2100 
   2101   Handle<Object> store_handle;
   2102 
   2103   uint32_t index;
   2104   if ((key->IsInternalizedString() &&
   2105        !String::cast(*key)->AsArrayIndex(&index)) ||
   2106       key->IsSymbol()) {
   2107     ASSIGN_RETURN_ON_EXCEPTION(
   2108         isolate(), store_handle,
   2109         StoreIC::Store(object, Handle<Name>::cast(key), value,
   2110                        JSReceiver::MAY_BE_STORE_FROM_KEYED),
   2111         Object);
   2112     if (!is_vector_set()) {
   2113       ConfigureVectorState(MEGAMORPHIC, key);
   2114       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
   2115                        "unhandled internalized string key");
   2116       TRACE_IC("StoreIC", key);
   2117     }
   2118     return store_handle;
   2119   }
   2120 
   2121   bool use_ic = FLAG_use_ic && !object->IsStringWrapper() &&
   2122                 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy();
   2123   if (use_ic && !object->IsSmi()) {
   2124     // Don't use ICs for maps of the objects in Array's prototype chain. We
   2125     // expect to be able to trap element sets to objects with those maps in
   2126     // the runtime to enable optimization of element hole access.
   2127     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
   2128     if (heap_object->map()->IsMapInArrayPrototypeChain()) {
   2129       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype");
   2130       use_ic = false;
   2131     }
   2132   }
   2133 
   2134   Handle<Map> old_receiver_map;
   2135   bool sloppy_arguments_elements = false;
   2136   bool key_is_valid_index = false;
   2137   KeyedAccessStoreMode store_mode = STANDARD_STORE;
   2138   if (use_ic && object->IsJSObject()) {
   2139     Handle<JSObject> receiver = Handle<JSObject>::cast(object);
   2140     old_receiver_map = handle(receiver->map(), isolate());
   2141     sloppy_arguments_elements =
   2142         !is_sloppy(language_mode()) &&
   2143         receiver->elements()->map() ==
   2144             isolate()->heap()->sloppy_arguments_elements_map();
   2145     if (!sloppy_arguments_elements) {
   2146       key_is_valid_index = key->IsSmi() && Smi::cast(*key)->value() >= 0;
   2147       if (key_is_valid_index) {
   2148         uint32_t index = static_cast<uint32_t>(Smi::cast(*key)->value());
   2149         store_mode = GetStoreMode(receiver, index, value);
   2150       }
   2151     }
   2152   }
   2153 
   2154   DCHECK(store_handle.is_null());
   2155   ASSIGN_RETURN_ON_EXCEPTION(isolate(), store_handle,
   2156                              Runtime::SetObjectProperty(isolate(), object, key,
   2157                                                         value, language_mode()),
   2158                              Object);
   2159 
   2160   if (use_ic) {
   2161     if (!old_receiver_map.is_null()) {
   2162       if (sloppy_arguments_elements) {
   2163         TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
   2164       } else if (key_is_valid_index) {
   2165         // We should go generic if receiver isn't a dictionary, but our
   2166         // prototype chain does have dictionary elements. This ensures that
   2167         // other non-dictionary receivers in the polymorphic case benefit
   2168         // from fast path keyed stores.
   2169         if (!old_receiver_map->DictionaryElementsInPrototypeChainOnly()) {
   2170           UpdateStoreElement(old_receiver_map, store_mode);
   2171         } else {
   2172           TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
   2173                            "dictionary or proxy prototype");
   2174         }
   2175       } else {
   2176         TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
   2177       }
   2178     } else {
   2179       TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
   2180     }
   2181   }
   2182 
   2183   if (!is_vector_set()) {
   2184     ConfigureVectorState(MEGAMORPHIC, key);
   2185     TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
   2186   }
   2187   TRACE_IC("StoreIC", key);
   2188 
   2189   return store_handle;
   2190 }
   2191 
   2192 
   2193 void CallIC::HandleMiss(Handle<Object> function) {
   2194   Handle<Object> name = isolate()->factory()->empty_string();
   2195   CallICNexus* nexus = casted_nexus<CallICNexus>();
   2196   Object* feedback = nexus->GetFeedback();
   2197 
   2198   // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
   2199   DCHECK(!feedback->IsSmi());
   2200 
   2201   if (feedback->IsWeakCell() || !function->IsJSFunction() ||
   2202       feedback->IsAllocationSite()) {
   2203     // We are going generic.
   2204     nexus->ConfigureMegamorphic();
   2205   } else {
   2206     DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()));
   2207     Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
   2208 
   2209     Handle<JSFunction> array_function =
   2210         Handle<JSFunction>(isolate()->native_context()->array_function());
   2211     if (array_function.is_identical_to(js_function)) {
   2212       // Alter the slot.
   2213       nexus->ConfigureMonomorphicArray();
   2214     } else if (js_function->context()->native_context() !=
   2215                *isolate()->native_context()) {
   2216       // Don't collect cross-native context feedback for the CallIC.
   2217       // TODO(bmeurer): We should collect the SharedFunctionInfo as
   2218       // feedback in this case instead.
   2219       nexus->ConfigureMegamorphic();
   2220     } else {
   2221       nexus->ConfigureMonomorphic(js_function);
   2222     }
   2223   }
   2224 
   2225   if (function->IsJSFunction()) {
   2226     Handle<JSFunction> js_function = Handle<JSFunction>::cast(function);
   2227     name = handle(js_function->shared()->name(), isolate());
   2228   }
   2229 
   2230   OnTypeFeedbackChanged(isolate(), get_host());
   2231   TRACE_IC("CallIC", name);
   2232 }
   2233 
   2234 
   2235 #undef TRACE_IC
   2236 
   2237 
   2238 // ----------------------------------------------------------------------------
   2239 // Static IC stub generators.
   2240 //
   2241 
   2242 // Used from ic-<arch>.cc.
   2243 RUNTIME_FUNCTION(Runtime_CallIC_Miss) {
   2244   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2245   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2246   HandleScope scope(isolate);
   2247   DCHECK(args.length() == 3);
   2248   Handle<Object> function = args.at<Object>(0);
   2249   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1);
   2250   Handle<Smi> slot = args.at<Smi>(2);
   2251   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2252   CallICNexus nexus(vector, vector_slot);
   2253   CallIC ic(isolate, &nexus);
   2254   ic.HandleMiss(function);
   2255   return *function;
   2256 }
   2257 
   2258 
   2259 // Used from ic-<arch>.cc.
   2260 RUNTIME_FUNCTION(Runtime_LoadIC_Miss) {
   2261   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2262   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2263   HandleScope scope(isolate);
   2264   Handle<Object> receiver = args.at<Object>(0);
   2265 
   2266   DCHECK_EQ(4, args.length());
   2267   Handle<Smi> slot = args.at<Smi>(2);
   2268   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
   2269   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2270   // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
   2271   // LoadIC miss handler if the handler misses. Since the vector Nexus is
   2272   // set up outside the IC, handle that here.
   2273   FeedbackVectorSlotKind kind = vector->GetKind(vector_slot);
   2274   if (kind == FeedbackVectorSlotKind::LOAD_IC) {
   2275     Handle<Name> key = args.at<Name>(1);
   2276     LoadICNexus nexus(vector, vector_slot);
   2277     LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2278     ic.UpdateState(receiver, key);
   2279     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   2280 
   2281   } else if (kind == FeedbackVectorSlotKind::LOAD_GLOBAL_IC) {
   2282     Handle<Name> key(vector->GetName(vector_slot), isolate);
   2283     DCHECK_NE(*key, *isolate->factory()->empty_string());
   2284     DCHECK_EQ(*isolate->global_object(), *receiver);
   2285     LoadGlobalICNexus nexus(vector, vector_slot);
   2286     LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2287     ic.UpdateState(receiver, key);
   2288     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(key));
   2289 
   2290   } else {
   2291     Handle<Name> key = args.at<Name>(1);
   2292     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC, kind);
   2293     KeyedLoadICNexus nexus(vector, vector_slot);
   2294     KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2295     ic.UpdateState(receiver, key);
   2296     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   2297   }
   2298 }
   2299 
   2300 // Used from ic-<arch>.cc.
   2301 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) {
   2302   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2303   HandleScope scope(isolate);
   2304   DCHECK_EQ(2, args.length());
   2305   Handle<JSGlobalObject> global = isolate->global_object();
   2306   Handle<Smi> slot = args.at<Smi>(0);
   2307   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(1);
   2308   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2309   DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
   2310             vector->GetKind(vector_slot));
   2311   Handle<String> name(vector->GetName(vector_slot), isolate);
   2312   DCHECK_NE(*name, *isolate->factory()->empty_string());
   2313 
   2314   LoadGlobalICNexus nexus(vector, vector_slot);
   2315   LoadGlobalIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2316   ic.UpdateState(global, name);
   2317 
   2318   Handle<Object> result;
   2319   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(name));
   2320   return *result;
   2321 }
   2322 
   2323 RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) {
   2324   HandleScope scope(isolate);
   2325   DCHECK_EQ(2, args.length());
   2326   CONVERT_SMI_ARG_CHECKED(slot, 0);
   2327   CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, vector, 1);
   2328 
   2329   FeedbackVectorSlot vector_slot = vector->ToSlot(slot);
   2330   DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
   2331             vector->GetKind(vector_slot));
   2332   Handle<String> name(vector->GetName(vector_slot), isolate);
   2333   DCHECK_NE(*name, *isolate->factory()->empty_string());
   2334 
   2335   Handle<JSGlobalObject> global = isolate->global_object();
   2336 
   2337   Handle<ScriptContextTable> script_contexts(
   2338       global->native_context()->script_context_table());
   2339 
   2340   ScriptContextTable::LookupResult lookup_result;
   2341   if (ScriptContextTable::Lookup(script_contexts, name, &lookup_result)) {
   2342     Handle<Context> script_context = ScriptContextTable::GetContext(
   2343         script_contexts, lookup_result.context_index);
   2344     Handle<Object> result =
   2345         FixedArray::get(*script_context, lookup_result.slot_index, isolate);
   2346     if (*result == *isolate->factory()->the_hole_value()) {
   2347       THROW_NEW_ERROR_RETURN_FAILURE(
   2348           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
   2349     }
   2350     return *result;
   2351   }
   2352 
   2353   Handle<Object> result;
   2354   bool is_found = false;
   2355   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2356       isolate, result,
   2357       Runtime::GetObjectProperty(isolate, global, name, &is_found));
   2358   if (!is_found) {
   2359     LoadICNexus nexus(isolate);
   2360     LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2361     // It is actually a LoadGlobalICs here but the predicate handles this case
   2362     // properly.
   2363     if (ic.ShouldThrowReferenceError()) {
   2364       THROW_NEW_ERROR_RETURN_FAILURE(
   2365           isolate, NewReferenceError(MessageTemplate::kNotDefined, name));
   2366     }
   2367   }
   2368   return *result;
   2369 }
   2370 
   2371 // Used from ic-<arch>.cc
   2372 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) {
   2373   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2374   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2375   HandleScope scope(isolate);
   2376   Handle<Object> receiver = args.at<Object>(0);
   2377   Handle<Object> key = args.at<Object>(1);
   2378 
   2379   DCHECK(args.length() == 4);
   2380   Handle<Smi> slot = args.at<Smi>(2);
   2381   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
   2382   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2383   KeyedLoadICNexus nexus(vector, vector_slot);
   2384   KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2385   ic.UpdateState(receiver, key);
   2386   RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   2387 }
   2388 
   2389 
   2390 RUNTIME_FUNCTION(Runtime_KeyedLoadIC_MissFromStubFailure) {
   2391   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2392   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2393   HandleScope scope(isolate);
   2394   Handle<Object> receiver = args.at<Object>(0);
   2395   Handle<Object> key = args.at<Object>(1);
   2396 
   2397   DCHECK(args.length() == 4);
   2398   Handle<Smi> slot = args.at<Smi>(2);
   2399   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
   2400   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2401   KeyedLoadICNexus nexus(vector, vector_slot);
   2402   KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   2403   ic.UpdateState(receiver, key);
   2404   RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   2405 }
   2406 
   2407 
   2408 // Used from ic-<arch>.cc.
   2409 RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
   2410   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2411   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2412   HandleScope scope(isolate);
   2413   Handle<Object> receiver = args.at<Object>(0);
   2414   Handle<Name> key = args.at<Name>(1);
   2415   Handle<Object> value = args.at<Object>(2);
   2416 
   2417   DCHECK(args.length() == 5 || args.length() == 6);
   2418   Handle<Smi> slot = args.at<Smi>(3);
   2419   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
   2420   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2421   if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
   2422     StoreICNexus nexus(vector, vector_slot);
   2423     StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2424     ic.UpdateState(receiver, key);
   2425     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2426   } else {
   2427     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC,
   2428               vector->GetKind(vector_slot));
   2429     KeyedStoreICNexus nexus(vector, vector_slot);
   2430     KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2431     ic.UpdateState(receiver, key);
   2432     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2433   }
   2434 }
   2435 
   2436 
   2437 RUNTIME_FUNCTION(Runtime_StoreIC_MissFromStubFailure) {
   2438   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2439   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2440   HandleScope scope(isolate);
   2441   Handle<Object> receiver = args.at<Object>(0);
   2442   Handle<Name> key = args.at<Name>(1);
   2443   Handle<Object> value = args.at<Object>(2);
   2444 
   2445   int length = args.length();
   2446   DCHECK(length == 5 || length == 6);
   2447   // We might have slot and vector, for a normal miss (slot(3), vector(4)).
   2448   // Or, map and vector for a transitioning store miss (map(3), vector(4)).
   2449   // In this case, we need to recover the slot from a virtual register.
   2450   // If length == 6, then a map is included (map(3), slot(4), vector(5)).
   2451   Handle<Smi> slot;
   2452   Handle<TypeFeedbackVector> vector;
   2453   if (length == 5) {
   2454     if (args.at<Object>(3)->IsMap()) {
   2455       vector = args.at<TypeFeedbackVector>(4);
   2456       slot = handle(
   2457           *reinterpret_cast<Smi**>(isolate->virtual_slot_register_address()),
   2458           isolate);
   2459     } else {
   2460       vector = args.at<TypeFeedbackVector>(4);
   2461       slot = args.at<Smi>(3);
   2462     }
   2463   } else {
   2464     vector = args.at<TypeFeedbackVector>(5);
   2465     slot = args.at<Smi>(4);
   2466   }
   2467 
   2468   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2469   if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::STORE_IC) {
   2470     StoreICNexus nexus(vector, vector_slot);
   2471     StoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   2472     ic.UpdateState(receiver, key);
   2473     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2474   } else {
   2475     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_STORE_IC,
   2476               vector->GetKind(vector_slot));
   2477     KeyedStoreICNexus nexus(vector, vector_slot);
   2478     KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   2479     ic.UpdateState(receiver, key);
   2480     RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2481   }
   2482 }
   2483 
   2484 
   2485 // Used from ic-<arch>.cc.
   2486 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) {
   2487   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2488   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2489   HandleScope scope(isolate);
   2490   Handle<Object> receiver = args.at<Object>(0);
   2491   Handle<Object> key = args.at<Object>(1);
   2492   Handle<Object> value = args.at<Object>(2);
   2493 
   2494   DCHECK(args.length() == 5);
   2495   Handle<Smi> slot = args.at<Smi>(3);
   2496   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
   2497   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2498   KeyedStoreICNexus nexus(vector, vector_slot);
   2499   KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2500   ic.UpdateState(receiver, key);
   2501   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2502 }
   2503 
   2504 
   2505 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_MissFromStubFailure) {
   2506   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2507   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2508   HandleScope scope(isolate);
   2509   Handle<Object> receiver = args.at<Object>(0);
   2510   Handle<Object> key = args.at<Object>(1);
   2511   Handle<Object> value = args.at<Object>(2);
   2512 
   2513   DCHECK(args.length() == 5);
   2514   Handle<Smi> slot = args.at<Smi>(3);
   2515   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(4);
   2516   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   2517   KeyedStoreICNexus nexus(vector, vector_slot);
   2518   KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   2519   ic.UpdateState(receiver, key);
   2520   RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
   2521 }
   2522 
   2523 
   2524 RUNTIME_FUNCTION(Runtime_StoreIC_Slow) {
   2525   HandleScope scope(isolate);
   2526   DCHECK(args.length() == 5);
   2527   Handle<Object> object = args.at<Object>(0);
   2528   Handle<Object> key = args.at<Object>(1);
   2529   Handle<Object> value = args.at<Object>(2);
   2530   LanguageMode language_mode;
   2531   StoreICNexus nexus(isolate);
   2532   StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2533   language_mode = ic.language_mode();
   2534   RETURN_RESULT_OR_FAILURE(
   2535       isolate,
   2536       Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
   2537 }
   2538 
   2539 
   2540 RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
   2541   HandleScope scope(isolate);
   2542   DCHECK(args.length() == 5);
   2543   Handle<Object> object = args.at<Object>(0);
   2544   Handle<Object> key = args.at<Object>(1);
   2545   Handle<Object> value = args.at<Object>(2);
   2546   LanguageMode language_mode;
   2547   KeyedStoreICNexus nexus(isolate);
   2548   KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2549   language_mode = ic.language_mode();
   2550   RETURN_RESULT_OR_FAILURE(
   2551       isolate,
   2552       Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
   2553 }
   2554 
   2555 
   2556 RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
   2557   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2558   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2559   HandleScope scope(isolate);
   2560   // Length == 5 or 6, depending on whether the vector slot
   2561   // is passed in a virtual register or not.
   2562   DCHECK(args.length() == 5 || args.length() == 6);
   2563   Handle<Object> object = args.at<Object>(0);
   2564   Handle<Object> key = args.at<Object>(1);
   2565   Handle<Object> value = args.at<Object>(2);
   2566   Handle<Map> map = args.at<Map>(3);
   2567   LanguageMode language_mode;
   2568   KeyedStoreICNexus nexus(isolate);
   2569   KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   2570   language_mode = ic.language_mode();
   2571   if (object->IsJSObject()) {
   2572     JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
   2573                                      map->elements_kind());
   2574   }
   2575   RETURN_RESULT_OR_FAILURE(
   2576       isolate,
   2577       Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
   2578 }
   2579 
   2580 
   2581 MaybeHandle<Object> BinaryOpIC::Transition(
   2582     Handle<AllocationSite> allocation_site, Handle<Object> left,
   2583     Handle<Object> right) {
   2584   BinaryOpICState state(isolate(), extra_ic_state());
   2585 
   2586   // Compute the actual result using the builtin for the binary operation.
   2587   Handle<Object> result;
   2588   switch (state.op()) {
   2589     default:
   2590       UNREACHABLE();
   2591     case Token::ADD:
   2592       ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
   2593                                  Object::Add(isolate(), left, right), Object);
   2594       break;
   2595     case Token::SUB:
   2596       ASSIGN_RETURN_ON_EXCEPTION(
   2597           isolate(), result, Object::Subtract(isolate(), left, right), Object);
   2598       break;
   2599     case Token::MUL:
   2600       ASSIGN_RETURN_ON_EXCEPTION(
   2601           isolate(), result, Object::Multiply(isolate(), left, right), Object);
   2602       break;
   2603     case Token::DIV:
   2604       ASSIGN_RETURN_ON_EXCEPTION(
   2605           isolate(), result, Object::Divide(isolate(), left, right), Object);
   2606       break;
   2607     case Token::MOD:
   2608       ASSIGN_RETURN_ON_EXCEPTION(
   2609           isolate(), result, Object::Modulus(isolate(), left, right), Object);
   2610       break;
   2611     case Token::BIT_OR:
   2612       ASSIGN_RETURN_ON_EXCEPTION(
   2613           isolate(), result, Object::BitwiseOr(isolate(), left, right), Object);
   2614       break;
   2615     case Token::BIT_AND:
   2616       ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
   2617                                  Object::BitwiseAnd(isolate(), left, right),
   2618                                  Object);
   2619       break;
   2620     case Token::BIT_XOR:
   2621       ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
   2622                                  Object::BitwiseXor(isolate(), left, right),
   2623                                  Object);
   2624       break;
   2625     case Token::SAR:
   2626       ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
   2627                                  Object::ShiftRight(isolate(), left, right),
   2628                                  Object);
   2629       break;
   2630     case Token::SHR:
   2631       ASSIGN_RETURN_ON_EXCEPTION(
   2632           isolate(), result, Object::ShiftRightLogical(isolate(), left, right),
   2633           Object);
   2634       break;
   2635     case Token::SHL:
   2636       ASSIGN_RETURN_ON_EXCEPTION(
   2637           isolate(), result, Object::ShiftLeft(isolate(), left, right), Object);
   2638       break;
   2639   }
   2640 
   2641   // Do not try to update the target if the code was marked for lazy
   2642   // deoptimization. (Since we do not relocate addresses in these
   2643   // code objects, an attempt to access the target could fail.)
   2644   if (AddressIsDeoptimizedCode()) {
   2645     return result;
   2646   }
   2647 
   2648   // Compute the new state.
   2649   BinaryOpICState old_state(isolate(), target()->extra_ic_state());
   2650   state.Update(left, right, result);
   2651 
   2652   // Check if we have a string operation here.
   2653   Handle<Code> new_target;
   2654   if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) {
   2655     // Setup the allocation site on-demand.
   2656     if (allocation_site.is_null()) {
   2657       allocation_site = isolate()->factory()->NewAllocationSite();
   2658     }
   2659 
   2660     // Install the stub with an allocation site.
   2661     BinaryOpICWithAllocationSiteStub stub(isolate(), state);
   2662     new_target = stub.GetCodeCopyFromTemplate(allocation_site);
   2663 
   2664     // Sanity check the trampoline stub.
   2665     DCHECK_EQ(*allocation_site, new_target->FindFirstAllocationSite());
   2666   } else {
   2667     // Install the generic stub.
   2668     BinaryOpICStub stub(isolate(), state);
   2669     new_target = stub.GetCode();
   2670 
   2671     // Sanity check the generic stub.
   2672     DCHECK_NULL(new_target->FindFirstAllocationSite());
   2673   }
   2674   set_target(*new_target);
   2675 
   2676   if (FLAG_trace_ic) {
   2677     OFStream os(stdout);
   2678     os << "[BinaryOpIC" << old_state << " => " << state << " @ "
   2679        << static_cast<void*>(*new_target) << " <- ";
   2680     JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
   2681     if (!allocation_site.is_null()) {
   2682       os << " using allocation site " << static_cast<void*>(*allocation_site);
   2683     }
   2684     os << "]" << std::endl;
   2685   }
   2686 
   2687   // Patch the inlined smi code as necessary.
   2688   if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) {
   2689     PatchInlinedSmiCode(isolate(), address(), ENABLE_INLINED_SMI_CHECK);
   2690   } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) {
   2691     PatchInlinedSmiCode(isolate(), address(), DISABLE_INLINED_SMI_CHECK);
   2692   }
   2693 
   2694   return result;
   2695 }
   2696 
   2697 
   2698 RUNTIME_FUNCTION(Runtime_BinaryOpIC_Miss) {
   2699   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2700   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2701   HandleScope scope(isolate);
   2702   DCHECK_EQ(2, args.length());
   2703   Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft);
   2704   Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight);
   2705   BinaryOpIC ic(isolate);
   2706   RETURN_RESULT_OR_FAILURE(
   2707       isolate, ic.Transition(Handle<AllocationSite>::null(), left, right));
   2708 }
   2709 
   2710 
   2711 RUNTIME_FUNCTION(Runtime_BinaryOpIC_MissWithAllocationSite) {
   2712   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2713   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2714   HandleScope scope(isolate);
   2715   DCHECK_EQ(3, args.length());
   2716   Handle<AllocationSite> allocation_site =
   2717       args.at<AllocationSite>(BinaryOpWithAllocationSiteStub::kAllocationSite);
   2718   Handle<Object> left = args.at<Object>(BinaryOpWithAllocationSiteStub::kLeft);
   2719   Handle<Object> right =
   2720       args.at<Object>(BinaryOpWithAllocationSiteStub::kRight);
   2721   BinaryOpIC ic(isolate);
   2722   RETURN_RESULT_OR_FAILURE(isolate,
   2723                            ic.Transition(allocation_site, left, right));
   2724 }
   2725 
   2726 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
   2727   CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED,
   2728                      CompareICState::UNINITIALIZED,
   2729                      CompareICState::UNINITIALIZED);
   2730   Code* code = NULL;
   2731   CHECK(stub.FindCodeInCache(&code));
   2732   return code;
   2733 }
   2734 
   2735 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) {
   2736   CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED,
   2737                      CompareICState::UNINITIALIZED,
   2738                      CompareICState::UNINITIALIZED);
   2739   return stub.GetCode();
   2740 }
   2741 
   2742 
   2743 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
   2744   HandleScope scope(isolate());
   2745   CompareICStub old_stub(target()->stub_key(), isolate());
   2746   CompareICState::State new_left =
   2747       CompareICState::NewInputState(old_stub.left(), x);
   2748   CompareICState::State new_right =
   2749       CompareICState::NewInputState(old_stub.right(), y);
   2750   CompareICState::State state = CompareICState::TargetState(
   2751       isolate(), old_stub.state(), old_stub.left(), old_stub.right(), op_,
   2752       HasInlinedSmiCode(address()), x, y);
   2753   CompareICStub stub(isolate(), op_, new_left, new_right, state);
   2754   if (state == CompareICState::KNOWN_RECEIVER) {
   2755     stub.set_known_map(
   2756         Handle<Map>(Handle<JSReceiver>::cast(x)->map(), isolate()));
   2757   }
   2758   Handle<Code> new_target = stub.GetCode();
   2759   set_target(*new_target);
   2760 
   2761   if (FLAG_trace_ic) {
   2762     PrintF("[CompareIC in ");
   2763     JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
   2764     PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
   2765            CompareICState::GetStateName(old_stub.left()),
   2766            CompareICState::GetStateName(old_stub.right()),
   2767            CompareICState::GetStateName(old_stub.state()),
   2768            CompareICState::GetStateName(new_left),
   2769            CompareICState::GetStateName(new_right),
   2770            CompareICState::GetStateName(state), Token::Name(op_),
   2771            static_cast<void*>(*stub.GetCode()));
   2772   }
   2773 
   2774   // Activate inlined smi code.
   2775   if (old_stub.state() == CompareICState::UNINITIALIZED) {
   2776     PatchInlinedSmiCode(isolate(), address(), ENABLE_INLINED_SMI_CHECK);
   2777   }
   2778 
   2779   return *new_target;
   2780 }
   2781 
   2782 
   2783 // Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc.
   2784 RUNTIME_FUNCTION(Runtime_CompareIC_Miss) {
   2785   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2786   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2787   HandleScope scope(isolate);
   2788   DCHECK(args.length() == 3);
   2789   CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
   2790   return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
   2791 }
   2792 
   2793 
   2794 RUNTIME_FUNCTION(Runtime_Unreachable) {
   2795   UNREACHABLE();
   2796   CHECK(false);
   2797   return isolate->heap()->undefined_value();
   2798 }
   2799 
   2800 
   2801 Handle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) {
   2802   ToBooleanICStub stub(isolate(), extra_ic_state());
   2803   bool to_boolean_value = stub.UpdateStatus(object);
   2804   Handle<Code> code = stub.GetCode();
   2805   set_target(*code);
   2806   return isolate()->factory()->ToBoolean(to_boolean_value);
   2807 }
   2808 
   2809 
   2810 RUNTIME_FUNCTION(Runtime_ToBooleanIC_Miss) {
   2811   TimerEventScope<TimerEventIcMiss> timer(isolate);
   2812   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   2813   DCHECK(args.length() == 1);
   2814   HandleScope scope(isolate);
   2815   Handle<Object> object = args.at<Object>(0);
   2816   ToBooleanIC ic(isolate);
   2817   return *ic.ToBoolean(object);
   2818 }
   2819 
   2820 
   2821 RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) {
   2822   Handle<JSObject> receiver = args.at<JSObject>(0);
   2823   Handle<JSObject> holder = args.at<JSObject>(1);
   2824   Handle<HeapObject> callback_or_cell = args.at<HeapObject>(2);
   2825   Handle<Name> name = args.at<Name>(3);
   2826   Handle<Object> value = args.at<Object>(4);
   2827   CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 5);
   2828   HandleScope scope(isolate);
   2829 
   2830   if (FLAG_runtime_call_stats) {
   2831     RETURN_RESULT_OR_FAILURE(
   2832         isolate, Runtime::SetObjectProperty(isolate, receiver, name, value,
   2833                                             language_mode));
   2834   }
   2835 
   2836   Handle<AccessorInfo> callback(
   2837       callback_or_cell->IsWeakCell()
   2838           ? AccessorInfo::cast(WeakCell::cast(*callback_or_cell)->value())
   2839           : AccessorInfo::cast(*callback_or_cell));
   2840 
   2841   DCHECK(callback->IsCompatibleReceiver(*receiver));
   2842 
   2843   Address setter_address = v8::ToCData<Address>(callback->setter());
   2844   v8::AccessorNameSetterCallback fun =
   2845       FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address);
   2846   DCHECK(fun != NULL);
   2847 
   2848   Object::ShouldThrow should_throw =
   2849       is_sloppy(language_mode) ? Object::DONT_THROW : Object::THROW_ON_ERROR;
   2850   PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
   2851                                         *holder, should_throw);
   2852   custom_args.Call(fun, name, value);
   2853   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   2854   return *value;
   2855 }
   2856 
   2857 
   2858 /**
   2859  * Attempts to load a property with an interceptor (which must be present),
   2860  * but doesn't search the prototype chain.
   2861  *
   2862  * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't
   2863  * provide any value for the given name.
   2864  */
   2865 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptorOnly) {
   2866   DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
   2867   Handle<Name> name =
   2868       args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
   2869   Handle<Object> receiver =
   2870       args.at<Object>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
   2871   Handle<JSObject> holder =
   2872       args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
   2873   HandleScope scope(isolate);
   2874 
   2875   if (!receiver->IsJSReceiver()) {
   2876     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2877         isolate, receiver, Object::ConvertReceiver(isolate, receiver));
   2878   }
   2879 
   2880   InterceptorInfo* interceptor = holder->GetNamedInterceptor();
   2881   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
   2882                                       *holder, Object::DONT_THROW);
   2883 
   2884   v8::GenericNamedPropertyGetterCallback getter =
   2885       v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
   2886           interceptor->getter());
   2887   Handle<Object> result = arguments.Call(getter, name);
   2888 
   2889   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   2890 
   2891   if (!result.is_null()) return *result;
   2892   return isolate->heap()->no_interceptor_result_sentinel();
   2893 }
   2894 
   2895 
   2896 /**
   2897  * Loads a property with an interceptor performing post interceptor
   2898  * lookup if interceptor failed.
   2899  */
   2900 RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) {
   2901   HandleScope scope(isolate);
   2902   DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
   2903   Handle<Name> name =
   2904       args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
   2905   Handle<Object> receiver =
   2906       args.at<Object>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex);
   2907   Handle<JSObject> holder =
   2908       args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex);
   2909 
   2910   if (!receiver->IsJSReceiver()) {
   2911     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
   2912         isolate, receiver, Object::ConvertReceiver(isolate, receiver));
   2913   }
   2914 
   2915   InterceptorInfo* interceptor = holder->GetNamedInterceptor();
   2916   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
   2917                                       *holder, Object::DONT_THROW);
   2918 
   2919   v8::GenericNamedPropertyGetterCallback getter =
   2920       v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
   2921           interceptor->getter());
   2922   Handle<Object> result = arguments.Call(getter, name);
   2923 
   2924   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   2925 
   2926   if (!result.is_null()) return *result;
   2927 
   2928   LookupIterator it(receiver, name, holder);
   2929   // Skip any lookup work until we hit the (possibly non-masking) interceptor.
   2930   while (it.state() != LookupIterator::INTERCEPTOR ||
   2931          !it.GetHolder<JSObject>().is_identical_to(holder)) {
   2932     DCHECK(it.state() != LookupIterator::ACCESS_CHECK || it.HasAccess());
   2933     it.Next();
   2934   }
   2935   // Skip past the interceptor.
   2936   it.Next();
   2937   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
   2938 
   2939   if (it.IsFound()) return *result;
   2940 
   2941 #ifdef DEBUG
   2942   LoadICNexus nexus(isolate);
   2943   LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2944   // It could actually be any kind of LoadICs here but the predicate handles
   2945   // all the cases properly.
   2946   DCHECK(!ic.ShouldThrowReferenceError());
   2947 #endif
   2948 
   2949   return isolate->heap()->undefined_value();
   2950 }
   2951 
   2952 
   2953 RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) {
   2954   HandleScope scope(isolate);
   2955   DCHECK(args.length() == 3);
   2956   StoreICNexus nexus(isolate);
   2957   StoreIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
   2958   Handle<JSObject> receiver = args.at<JSObject>(0);
   2959   Handle<Name> name = args.at<Name>(1);
   2960   Handle<Object> value = args.at<Object>(2);
   2961 
   2962   DCHECK(receiver->HasNamedInterceptor());
   2963   InterceptorInfo* interceptor = receiver->GetNamedInterceptor();
   2964   DCHECK(!interceptor->non_masking());
   2965   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
   2966                                       *receiver, Object::DONT_THROW);
   2967 
   2968   v8::GenericNamedPropertySetterCallback setter =
   2969       v8::ToCData<v8::GenericNamedPropertySetterCallback>(
   2970           interceptor->setter());
   2971   Handle<Object> result = arguments.Call(setter, name, value);
   2972   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   2973   if (!result.is_null()) return *value;
   2974 
   2975   LookupIterator it(receiver, name, receiver);
   2976   // Skip past any access check on the receiver.
   2977   if (it.state() == LookupIterator::ACCESS_CHECK) {
   2978     DCHECK(it.HasAccess());
   2979     it.Next();
   2980   }
   2981   // Skip past the interceptor on the receiver.
   2982   DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
   2983   it.Next();
   2984 
   2985   MAYBE_RETURN(Object::SetProperty(&it, value, ic.language_mode(),
   2986                                    JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED),
   2987                isolate->heap()->exception());
   2988   return *value;
   2989 }
   2990 
   2991 
   2992 RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) {
   2993   // TODO(verwaest): This should probably get the holder and receiver as input.
   2994   HandleScope scope(isolate);
   2995   Handle<JSObject> receiver = args.at<JSObject>(0);
   2996   DCHECK(args.smi_at(1) >= 0);
   2997   uint32_t index = args.smi_at(1);
   2998 
   2999   InterceptorInfo* interceptor = receiver->GetIndexedInterceptor();
   3000   PropertyCallbackArguments arguments(isolate, interceptor->data(), *receiver,
   3001                                       *receiver, Object::DONT_THROW);
   3002 
   3003   v8::IndexedPropertyGetterCallback getter =
   3004       v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
   3005   Handle<Object> result = arguments.Call(getter, index);
   3006 
   3007   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   3008 
   3009   if (result.is_null()) {
   3010     LookupIterator it(isolate, receiver, index, receiver);
   3011     DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state());
   3012     it.Next();
   3013     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
   3014                                        Object::GetProperty(&it));
   3015   }
   3016 
   3017   return *result;
   3018 }
   3019 
   3020 
   3021 RUNTIME_FUNCTION(Runtime_LoadIC_MissFromStubFailure) {
   3022   TimerEventScope<TimerEventIcMiss> timer(isolate);
   3023   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8"), "V8.IcMiss");
   3024   HandleScope scope(isolate);
   3025   Handle<Object> receiver = args.at<Object>(0);
   3026   Handle<Name> key = args.at<Name>(1);
   3027 
   3028   DCHECK(args.length() == 4);
   3029   Handle<Smi> slot = args.at<Smi>(2);
   3030   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
   3031   FeedbackVectorSlot vector_slot = vector->ToSlot(slot->value());
   3032   // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
   3033   // LoadIC miss handler if the handler misses. Since the vector Nexus is
   3034   // set up outside the IC, handle that here.
   3035   if (vector->GetKind(vector_slot) == FeedbackVectorSlotKind::LOAD_IC) {
   3036     LoadICNexus nexus(vector, vector_slot);
   3037     LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   3038     ic.UpdateState(receiver, key);
   3039     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   3040   } else {
   3041     DCHECK_EQ(FeedbackVectorSlotKind::KEYED_LOAD_IC,
   3042               vector->GetKind(vector_slot));
   3043     KeyedLoadICNexus nexus(vector, vector_slot);
   3044     KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
   3045     ic.UpdateState(receiver, key);
   3046     RETURN_RESULT_OR_FAILURE(isolate, ic.Load(receiver, key));
   3047   }
   3048 }
   3049 }  // namespace internal
   3050 }  // namespace v8
   3051