LCOV - code coverage report
Current view: top level - src - feedback-vector.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 404 472 85.6 %
Date: 2019-03-21 Functions: 54 62 87.1 %

          Line data    Source code
       1             : // Copyright 2014 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/feedback-vector.h"
       6             : #include "src/feedback-vector-inl.h"
       7             : #include "src/ic/handler-configuration-inl.h"
       8             : #include "src/ic/ic-inl.h"
       9             : #include "src/objects.h"
      10             : #include "src/objects/data-handler-inl.h"
      11             : #include "src/objects/hash-table-inl.h"
      12             : #include "src/objects/map-inl.h"
      13             : #include "src/objects/object-macros.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18    14595528 : FeedbackSlot FeedbackVectorSpec::AddSlot(FeedbackSlotKind kind) {
      19             :   int slot = slots();
      20    14595528 :   int entries_per_slot = FeedbackMetadata::GetSlotSize(kind);
      21             :   append(kind);
      22    39435111 :   for (int i = 1; i < entries_per_slot; i++) {
      23             :     append(FeedbackSlotKind::kInvalid);
      24             :   }
      25    14595405 :   return FeedbackSlot(slot);
      26             : }
      27             : 
      28          68 : FeedbackSlot FeedbackVectorSpec::AddTypeProfileSlot() {
      29          68 :   FeedbackSlot slot = AddSlot(FeedbackSlotKind::kTypeProfile);
      30          68 :   CHECK_EQ(FeedbackVectorSpec::kTypeProfileSlotIndex,
      31             :            FeedbackVector::GetIndex(slot));
      32          68 :   return slot;
      33             : }
      34             : 
      35           0 : bool FeedbackVectorSpec::HasTypeProfileSlot() const {
      36             :   FeedbackSlot slot =
      37             :       FeedbackVector::ToSlot(FeedbackVectorSpec::kTypeProfileSlotIndex);
      38           0 :   if (slots() <= slot.ToInt()) {
      39             :     return false;
      40             :   }
      41           0 :   return GetKind(slot) == FeedbackSlotKind::kTypeProfile;
      42             : }
      43             : 
      44     2128049 : static bool IsPropertyNameFeedback(MaybeObject feedback) {
      45     2128049 :   HeapObject heap_object;
      46     2128049 :   if (!feedback->GetHeapObjectIfStrong(&heap_object)) return false;
      47     1067351 :   if (heap_object->IsString()) {
      48             :     DCHECK(heap_object->IsInternalizedString());
      49             :     return true;
      50             :   }
      51     1036880 :   if (!heap_object->IsSymbol()) return false;
      52             :   Symbol symbol = Symbol::cast(heap_object);
      53             :   ReadOnlyRoots roots = symbol->GetReadOnlyRoots();
      54       42111 :   return symbol != roots.uninitialized_symbol() &&
      55      640047 :          symbol != roots.premonomorphic_symbol() &&
      56             :          symbol != roots.megamorphic_symbol();
      57             : }
      58             : 
      59           0 : std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind) {
      60           0 :   return os << FeedbackMetadata::Kind2String(kind);
      61             : }
      62             : 
      63         404 : FeedbackSlotKind FeedbackMetadata::GetKind(FeedbackSlot slot) const {
      64             :   int index = VectorICComputer::index(0, slot.ToInt());
      65             :   int data = get(index);
      66    44251957 :   return VectorICComputer::decode(data, slot.ToInt());
      67             : }
      68             : 
      69           0 : void FeedbackMetadata::SetKind(FeedbackSlot slot, FeedbackSlotKind kind) {
      70             :   int index = VectorICComputer::index(0, slot.ToInt());
      71             :   int data = get(index);
      72    51805938 :   int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
      73             :   set(index, new_data);
      74           0 : }
      75             : 
      76             : // static
      77     2090711 : Handle<FeedbackMetadata> FeedbackMetadata::New(Isolate* isolate,
      78             :                                                const FeedbackVectorSpec* spec) {
      79             :   Factory* factory = isolate->factory();
      80             : 
      81     2090711 :   const int slot_count = spec == nullptr ? 0 : spec->slots();
      82             :   const int closure_feedback_cell_count =
      83     2090711 :       spec == nullptr ? 0 : spec->closure_feedback_cells();
      84     2090711 :   if (slot_count == 0 && closure_feedback_cell_count == 0) {
      85             :     return factory->empty_feedback_metadata();
      86             :   }
      87             : #ifdef DEBUG
      88             :   for (int i = 0; i < slot_count;) {
      89             :     DCHECK(spec);
      90             :     FeedbackSlotKind kind = spec->GetKind(FeedbackSlot(i));
      91             :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
      92             :     for (int j = 1; j < entry_size; j++) {
      93             :       FeedbackSlotKind kind = spec->GetKind(FeedbackSlot(i + j));
      94             :       DCHECK_EQ(FeedbackSlotKind::kInvalid, kind);
      95             :     }
      96             :     i += entry_size;
      97             :   }
      98             : #endif
      99             : 
     100             :   Handle<FeedbackMetadata> metadata =
     101     1597425 :       factory->NewFeedbackMetadata(slot_count, closure_feedback_cell_count);
     102             : 
     103             :   // Initialize the slots. The raw data section has already been pre-zeroed in
     104             :   // NewFeedbackMetadata.
     105    53403365 :   for (int i = 0; i < slot_count; i++) {
     106             :     DCHECK(spec);
     107             :     FeedbackSlot slot(i);
     108             :     FeedbackSlotKind kind = spec->GetKind(slot);
     109             :     metadata->SetKind(slot, kind);
     110             :   }
     111             : 
     112     1597427 :   return metadata;
     113             : }
     114             : 
     115           0 : bool FeedbackMetadata::SpecDiffersFrom(
     116             :     const FeedbackVectorSpec* other_spec) const {
     117           0 :   if (other_spec->slots() != slot_count()) {
     118             :     return true;
     119             :   }
     120             : 
     121             :   int slots = slot_count();
     122           0 :   for (int i = 0; i < slots;) {
     123             :     FeedbackSlot slot(i);
     124             :     FeedbackSlotKind kind = GetKind(slot);
     125           0 :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
     126             : 
     127           0 :     if (kind != other_spec->GetKind(slot)) {
     128             :       return true;
     129             :     }
     130           0 :     i += entry_size;
     131             :   }
     132             :   return false;
     133             : }
     134             : 
     135           0 : const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
     136           0 :   switch (kind) {
     137             :     case FeedbackSlotKind::kInvalid:
     138             :       return "Invalid";
     139             :     case FeedbackSlotKind::kCall:
     140           0 :       return "Call";
     141             :     case FeedbackSlotKind::kLoadProperty:
     142           0 :       return "LoadProperty";
     143             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     144           0 :       return "LoadGlobalInsideTypeof";
     145             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     146           0 :       return "LoadGlobalNotInsideTypeof";
     147             :     case FeedbackSlotKind::kLoadKeyed:
     148           0 :       return "LoadKeyed";
     149             :     case FeedbackSlotKind::kHasKeyed:
     150           0 :       return "HasKeyed";
     151             :     case FeedbackSlotKind::kStoreNamedSloppy:
     152           0 :       return "StoreNamedSloppy";
     153             :     case FeedbackSlotKind::kStoreNamedStrict:
     154           0 :       return "StoreNamedStrict";
     155             :     case FeedbackSlotKind::kStoreOwnNamed:
     156           0 :       return "StoreOwnNamed";
     157             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     158           0 :       return "StoreGlobalSloppy";
     159             :     case FeedbackSlotKind::kStoreGlobalStrict:
     160           0 :       return "StoreGlobalStrict";
     161             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     162           0 :       return "StoreKeyedSloppy";
     163             :     case FeedbackSlotKind::kStoreKeyedStrict:
     164           0 :       return "StoreKeyedStrict";
     165             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     166           0 :       return "StoreInArrayLiteral";
     167             :     case FeedbackSlotKind::kBinaryOp:
     168           0 :       return "BinaryOp";
     169             :     case FeedbackSlotKind::kCompareOp:
     170           0 :       return "CompareOp";
     171             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     172           0 :       return "StoreDataPropertyInLiteral";
     173             :     case FeedbackSlotKind::kLiteral:
     174           0 :       return "Literal";
     175             :     case FeedbackSlotKind::kTypeProfile:
     176           0 :       return "TypeProfile";
     177             :     case FeedbackSlotKind::kForIn:
     178           0 :       return "ForIn";
     179             :     case FeedbackSlotKind::kInstanceOf:
     180           0 :       return "InstanceOf";
     181             :     case FeedbackSlotKind::kCloneObject:
     182           0 :       return "CloneObject";
     183             :     case FeedbackSlotKind::kKindsNumber:
     184             :       break;
     185             :   }
     186           0 :   UNREACHABLE();
     187             : }
     188             : 
     189         452 : bool FeedbackMetadata::HasTypeProfileSlot() const {
     190             :   FeedbackSlot slot =
     191             :       FeedbackVector::ToSlot(FeedbackVectorSpec::kTypeProfileSlotIndex);
     192         872 :   return slot.ToInt() < slot_count() &&
     193         452 :          GetKind(slot) == FeedbackSlotKind::kTypeProfile;
     194             : }
     195             : 
     196    23360074 : FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
     197             :   DCHECK(!is_empty());
     198    46720153 :   return metadata()->GetKind(slot);
     199             : }
     200             : 
     201         440 : FeedbackSlot FeedbackVector::GetTypeProfileSlot() const {
     202             :   DCHECK(metadata()->HasTypeProfileSlot());
     203             :   FeedbackSlot slot =
     204             :       FeedbackVector::ToSlot(FeedbackVectorSpec::kTypeProfileSlotIndex);
     205             :   DCHECK_EQ(FeedbackSlotKind::kTypeProfile, GetKind(slot));
     206         440 :   return slot;
     207             : }
     208             : 
     209             : // static
     210     3082537 : Handle<FeedbackVector> FeedbackVector::New(
     211             :     Isolate* isolate, Handle<SharedFunctionInfo> shared,
     212             :     Handle<FixedArray> closure_feedback_cell_array) {
     213             :   Factory* factory = isolate->factory();
     214             : 
     215             :   const int slot_count = shared->feedback_metadata()->slot_count();
     216             : 
     217             :   Handle<FeedbackVector> vector =
     218     3082537 :       factory->NewFeedbackVector(shared, AllocationType::kOld);
     219             : 
     220             :   DCHECK_EQ(vector->length(), slot_count);
     221             : 
     222             :   DCHECK_EQ(vector->shared_function_info(), *shared);
     223             :   DCHECK_EQ(
     224             :       vector->optimized_code_weak_or_smi(),
     225             :       MaybeObject::FromSmi(Smi::FromEnum(
     226             :           FLAG_log_function_events ? OptimizationMarker::kLogFirstExecution
     227             :                                    : OptimizationMarker::kNone)));
     228             :   DCHECK_EQ(vector->invocation_count(), 0);
     229             :   DCHECK_EQ(vector->profiler_ticks(), 0);
     230             :   DCHECK_EQ(vector->deopt_count(), 0);
     231             : 
     232     3082539 :   vector->set_closure_feedback_cell_array(*closure_feedback_cell_array);
     233             : 
     234             :   // Ensure we can skip the write barrier
     235             :   Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
     236             :   DCHECK_EQ(ReadOnlyRoots(isolate).uninitialized_symbol(),
     237             :             *uninitialized_sentinel);
     238    44701938 :   for (int i = 0; i < slot_count;) {
     239             :     FeedbackSlot slot(i);
     240             :     FeedbackSlotKind kind = shared->feedback_metadata()->GetKind(slot);
     241             :     int index = FeedbackVector::GetIndex(slot);
     242    20809693 :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
     243             : 
     244             :     Object extra_value = *uninitialized_sentinel;
     245    20809696 :     switch (kind) {
     246             :       case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     247             :       case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     248             :       case FeedbackSlotKind::kStoreGlobalSloppy:
     249             :       case FeedbackSlotKind::kStoreGlobalStrict:
     250    18757599 :         vector->set(index, HeapObjectReference::ClearedValue(isolate),
     251     6252533 :                     SKIP_WRITE_BARRIER);
     252     6252533 :         break;
     253             :       case FeedbackSlotKind::kForIn:
     254             :       case FeedbackSlotKind::kCompareOp:
     255             :       case FeedbackSlotKind::kBinaryOp:
     256     5517335 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     257     2758667 :         break;
     258             :       case FeedbackSlotKind::kLiteral:
     259      793444 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     260      396722 :         break;
     261             :       case FeedbackSlotKind::kCall:
     262    11607286 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     263             :         extra_value = Smi::kZero;
     264     5803643 :         break;
     265             :       case FeedbackSlotKind::kCloneObject:
     266             :       case FeedbackSlotKind::kLoadProperty:
     267             :       case FeedbackSlotKind::kLoadKeyed:
     268             :       case FeedbackSlotKind::kHasKeyed:
     269             :       case FeedbackSlotKind::kStoreNamedSloppy:
     270             :       case FeedbackSlotKind::kStoreNamedStrict:
     271             :       case FeedbackSlotKind::kStoreOwnNamed:
     272             :       case FeedbackSlotKind::kStoreKeyedSloppy:
     273             :       case FeedbackSlotKind::kStoreKeyedStrict:
     274             :       case FeedbackSlotKind::kStoreInArrayLiteral:
     275             :       case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     276             :       case FeedbackSlotKind::kTypeProfile:
     277             :       case FeedbackSlotKind::kInstanceOf:
     278    11196283 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     279     5598140 :         break;
     280             : 
     281             :       case FeedbackSlotKind::kInvalid:
     282             :       case FeedbackSlotKind::kKindsNumber:
     283           0 :         UNREACHABLE();
     284             :         break;
     285             :     }
     286    56068334 :     for (int j = 1; j < entry_size; j++) {
     287    52887949 :       vector->set(index + j, extra_value, SKIP_WRITE_BARRIER);
     288             :     }
     289    20809699 :     i += entry_size;
     290             :   }
     291             : 
     292             :   Handle<FeedbackVector> result = Handle<FeedbackVector>::cast(vector);
     293     3082546 :   if (!isolate->is_best_effort_code_coverage() ||
     294             :       isolate->is_collecting_type_profile()) {
     295        1200 :     AddToVectorsForProfilingTools(isolate, result);
     296             :   }
     297     3082546 :   return result;
     298             : }
     299             : 
     300             : // static
     301     3082534 : Handle<FixedArray> FeedbackVector::NewClosureFeedbackCellArray(
     302             :     Isolate* isolate, Handle<SharedFunctionInfo> shared) {
     303             :   Factory* factory = isolate->factory();
     304             : 
     305             :   int num_feedback_cells =
     306             :       shared->feedback_metadata()->closure_feedback_cell_count();
     307     3082534 :   if (num_feedback_cells == 0) {
     308             :     return factory->empty_fixed_array();
     309             :   }
     310             : 
     311             :   Handle<FixedArray> feedback_cell_array =
     312     1027145 :       factory->NewFixedArray(num_feedback_cells, AllocationType::kOld);
     313     9185659 :   for (int i = 0; i < num_feedback_cells; i++) {
     314             :     Handle<FeedbackCell> cell =
     315     4079254 :         factory->NewNoClosuresCell(factory->undefined_value());
     316     8158512 :     feedback_cell_array->set(i, *cell);
     317             :   }
     318     1027151 :   return feedback_cell_array;
     319             : }
     320             : 
     321             : // static
     322        1200 : void FeedbackVector::AddToVectorsForProfilingTools(
     323             :     Isolate* isolate, Handle<FeedbackVector> vector) {
     324             :   DCHECK(!isolate->is_best_effort_code_coverage() ||
     325             :          isolate->is_collecting_type_profile());
     326        1200 :   if (!vector->shared_function_info()->IsSubjectToDebugging()) return;
     327             :   Handle<ArrayList> list = Handle<ArrayList>::cast(
     328             :       isolate->factory()->feedback_vectors_for_profiling_tools());
     329        1200 :   list = ArrayList::Add(isolate, list, vector);
     330        1200 :   isolate->SetFeedbackVectorsForProfilingTools(*list);
     331             : }
     332             : 
     333             : // static
     334       24641 : void FeedbackVector::SetOptimizedCode(Handle<FeedbackVector> vector,
     335             :                                       Handle<Code> code) {
     336             :   DCHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
     337       49282 :   vector->set_optimized_code_weak_or_smi(HeapObjectReference::Weak(*code));
     338       24641 : }
     339             : 
     340           0 : void FeedbackVector::ClearOptimizedCode() {
     341             :   DCHECK(has_optimized_code());
     342             :   SetOptimizationMarker(OptimizationMarker::kNone);
     343           0 : }
     344             : 
     345      766351 : void FeedbackVector::ClearOptimizationMarker() {
     346             :   DCHECK(!has_optimized_code());
     347             :   SetOptimizationMarker(OptimizationMarker::kNone);
     348      766352 : }
     349             : 
     350      500589 : void FeedbackVector::SetOptimizationMarker(OptimizationMarker marker) {
     351     1269216 :   set_optimized_code_weak_or_smi(MaybeObject::FromSmi(Smi::FromEnum(marker)));
     352      500590 : }
     353             : 
     354     4413436 : void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
     355             :     SharedFunctionInfo shared, const char* reason) {
     356             :   MaybeObject slot = optimized_code_weak_or_smi();
     357     4413436 :   if (slot->IsSmi()) {
     358     3990670 :     return;
     359             :   }
     360             : 
     361      423030 :   if (slot->IsCleared()) {
     362             :     ClearOptimizationMarker();
     363             :     return;
     364             :   }
     365             : 
     366      422758 :   Code code = Code::cast(slot->GetHeapObject());
     367      422758 :   if (code->marked_for_deoptimization()) {
     368        2004 :     if (FLAG_trace_deopt) {
     369             :       PrintF("[evicting optimizing code marked for deoptimization (%s) for ",
     370           0 :              reason);
     371           0 :       shared->ShortPrint();
     372           0 :       PrintF("]\n");
     373             :     }
     374        2004 :     if (!code->deopt_already_counted()) {
     375             :       increment_deopt_count();
     376        1224 :       code->set_deopt_already_counted(true);
     377             :     }
     378             :     ClearOptimizedCode();
     379             :   }
     380             : }
     381             : 
     382       52599 : bool FeedbackVector::ClearSlots(Isolate* isolate) {
     383             :   MaybeObject uninitialized_sentinel = MaybeObject::FromObject(
     384             :       FeedbackVector::RawUninitializedSentinel(isolate));
     385             : 
     386             :   bool feedback_updated = false;
     387       52599 :   FeedbackMetadataIterator iter(metadata());
     388      214513 :   while (iter.HasNext()) {
     389       80957 :     FeedbackSlot slot = iter.Next();
     390             : 
     391             :     MaybeObject obj = Get(slot);
     392       80957 :     if (obj != uninitialized_sentinel) {
     393             :       FeedbackNexus nexus(*this, slot);
     394       55810 :       feedback_updated |= nexus.Clear();
     395             :     }
     396             :   }
     397       52599 :   return feedback_updated;
     398             : }
     399             : 
     400      413684 : void FeedbackVector::AssertNoLegacyTypes(MaybeObject object) {
     401             : #ifdef DEBUG
     402             :   HeapObject heap_object;
     403             :   if (object->GetHeapObject(&heap_object)) {
     404             :     // Instead of FixedArray, the Feedback and the Extra should contain
     405             :     // WeakFixedArrays. The only allowed FixedArray subtype is HashTable.
     406             :     DCHECK_IMPLIES(heap_object->IsFixedArray(), heap_object->IsHashTable());
     407             :   }
     408             : #endif
     409      413684 : }
     410             : 
     411      222365 : Handle<WeakFixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
     412             :   Isolate* isolate = GetIsolate();
     413             :   HeapObject heap_object;
     414      531235 :   if (GetFeedback()->GetHeapObjectIfStrong(&heap_object) &&
     415      308678 :       heap_object->IsWeakFixedArray() &&
     416             :       WeakFixedArray::cast(heap_object)->length() == length) {
     417             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     418             :   }
     419      215967 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     420             :   SetFeedback(*array);
     421      215967 :   return array;
     422             : }
     423             : 
     424       18011 : Handle<WeakFixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
     425             :   Isolate* isolate = GetIsolate();
     426             :   HeapObject heap_object;
     427       40384 :   if (GetFeedbackExtra()->GetHeapObjectIfStrong(&heap_object) &&
     428       22303 :       heap_object->IsWeakFixedArray() &&
     429             :       WeakFixedArray::cast(heap_object)->length() == length) {
     430             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     431             :   }
     432       17758 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     433       17758 :   SetFeedbackExtra(*array);
     434       17758 :   return array;
     435             : }
     436             : 
     437       45756 : void FeedbackNexus::ConfigureUninitialized() {
     438             :   Isolate* isolate = GetIsolate();
     439       45756 :   switch (kind()) {
     440             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     441             :     case FeedbackSlotKind::kStoreGlobalStrict:
     442             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     443             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     444       16132 :       SetFeedback(HeapObjectReference::ClearedValue(isolate),
     445        8066 :                   SKIP_WRITE_BARRIER);
     446       16132 :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     447        8066 :                        SKIP_WRITE_BARRIER);
     448        8066 :       break;
     449             :     }
     450             :     case FeedbackSlotKind::kCloneObject:
     451             :     case FeedbackSlotKind::kCall: {
     452             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     453             :                   SKIP_WRITE_BARRIER);
     454        6434 :       SetFeedbackExtra(Smi::kZero, SKIP_WRITE_BARRIER);
     455        6434 :       break;
     456             :     }
     457             :     case FeedbackSlotKind::kInstanceOf: {
     458             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     459             :                   SKIP_WRITE_BARRIER);
     460           0 :       break;
     461             :     }
     462             :     case FeedbackSlotKind::kStoreNamedSloppy:
     463             :     case FeedbackSlotKind::kStoreNamedStrict:
     464             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     465             :     case FeedbackSlotKind::kStoreKeyedStrict:
     466             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     467             :     case FeedbackSlotKind::kStoreOwnNamed:
     468             :     case FeedbackSlotKind::kLoadProperty:
     469             :     case FeedbackSlotKind::kLoadKeyed:
     470             :     case FeedbackSlotKind::kHasKeyed:
     471             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     472             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     473             :                   SKIP_WRITE_BARRIER);
     474       62512 :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     475       31256 :                        SKIP_WRITE_BARRIER);
     476       31256 :       break;
     477             :     }
     478             :     default:
     479           0 :       UNREACHABLE();
     480             :   }
     481       45756 : }
     482             : 
     483       55810 : bool FeedbackNexus::Clear() {
     484             :   bool feedback_updated = false;
     485             : 
     486             :   switch (kind()) {
     487             :     case FeedbackSlotKind::kTypeProfile:
     488             :       // We don't clear these kinds ever.
     489             :       break;
     490             : 
     491             :     case FeedbackSlotKind::kCompareOp:
     492             :     case FeedbackSlotKind::kForIn:
     493             :     case FeedbackSlotKind::kBinaryOp:
     494             :       // We don't clear these, either.
     495             :       break;
     496             : 
     497             :     case FeedbackSlotKind::kLiteral:
     498             :       SetFeedback(Smi::kZero, SKIP_WRITE_BARRIER);
     499             :       feedback_updated = true;
     500          13 :       break;
     501             : 
     502             :     case FeedbackSlotKind::kStoreNamedSloppy:
     503             :     case FeedbackSlotKind::kStoreNamedStrict:
     504             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     505             :     case FeedbackSlotKind::kStoreKeyedStrict:
     506             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     507             :     case FeedbackSlotKind::kStoreOwnNamed:
     508             :     case FeedbackSlotKind::kLoadProperty:
     509             :     case FeedbackSlotKind::kLoadKeyed:
     510             :     case FeedbackSlotKind::kHasKeyed:
     511             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     512             :     case FeedbackSlotKind::kStoreGlobalStrict:
     513             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     514             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     515             :     case FeedbackSlotKind::kCall:
     516             :     case FeedbackSlotKind::kInstanceOf:
     517             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     518             :     case FeedbackSlotKind::kCloneObject:
     519       47770 :       if (!IsCleared()) {
     520       45756 :         ConfigureUninitialized();
     521             :         feedback_updated = true;
     522             :       }
     523             :       break;
     524             : 
     525             :     case FeedbackSlotKind::kInvalid:
     526             :     case FeedbackSlotKind::kKindsNumber:
     527           0 :       UNREACHABLE();
     528             :       break;
     529             :   }
     530       55810 :   return feedback_updated;
     531             : }
     532             : 
     533      686666 : void FeedbackNexus::ConfigurePremonomorphic(Handle<Map> receiver_map) {
     534             :   SetFeedback(*FeedbackVector::PremonomorphicSentinel(GetIsolate()),
     535             :               SKIP_WRITE_BARRIER);
     536      686666 :   SetFeedbackExtra(HeapObjectReference::Weak(*receiver_map));
     537      686667 : }
     538             : 
     539         126 : bool FeedbackNexus::ConfigureMegamorphic() {
     540             :   DisallowHeapAllocation no_gc;
     541             :   Isolate* isolate = GetIsolate();
     542             :   MaybeObject sentinel =
     543             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     544         252 :   if (GetFeedback() != sentinel) {
     545         126 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     546         126 :     SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     547         126 :     return true;
     548             :   }
     549             : 
     550             :   return false;
     551             : }
     552             : 
     553       47827 : bool FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) {
     554             :   DisallowHeapAllocation no_gc;
     555             :   Isolate* isolate = GetIsolate();
     556             :   bool changed = false;
     557             :   MaybeObject sentinel =
     558             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     559       95655 :   if (GetFeedback() != sentinel) {
     560       43398 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     561             :     changed = true;
     562             :   }
     563             : 
     564       47828 :   Smi extra = Smi::FromInt(static_cast<int>(property_type));
     565       52258 :   if (changed || GetFeedbackExtra() != MaybeObject::FromSmi(extra)) {
     566       43398 :     SetFeedbackExtra(extra, SKIP_WRITE_BARRIER);
     567             :     changed = true;
     568             :   }
     569       47827 :   return changed;
     570             : }
     571             : 
     572      103509 : Map FeedbackNexus::GetFirstMap() const {
     573             :   MapHandles maps;
     574      103509 :   ExtractMaps(&maps);
     575      103509 :   if (maps.size() > 0) return *maps.at(0);
     576           4 :   return Map();
     577             : }
     578             : 
     579    13174959 : InlineCacheState FeedbackNexus::ic_state() const {
     580             :   Isolate* isolate = GetIsolate();
     581    13174959 :   MaybeObject feedback = GetFeedback();
     582             : 
     583    13174968 :   switch (kind()) {
     584             :     case FeedbackSlotKind::kLiteral:
     585       52370 :       if (feedback->IsSmi()) return UNINITIALIZED;
     586        7591 :       return MONOMORPHIC;
     587             : 
     588             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     589             :     case FeedbackSlotKind::kStoreGlobalStrict:
     590             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     591             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     592     6421997 :       if (feedback->IsSmi()) return MONOMORPHIC;
     593             : 
     594     6421757 :       if (feedback == MaybeObject::FromObject(
     595             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     596             :         DCHECK(kind() == FeedbackSlotKind::kStoreGlobalSloppy ||
     597             :                kind() == FeedbackSlotKind::kStoreGlobalStrict);
     598             :         return PREMONOMORPHIC;
     599             :       }
     600             : 
     601             :       DCHECK(feedback->IsWeakOrCleared());
     602     6421730 :       MaybeObject extra = GetFeedbackExtra();
     603    12424143 :       if (!feedback->IsCleared() ||
     604             :           extra != MaybeObject::FromObject(
     605             :                        *FeedbackVector::UninitializedSentinel(isolate))) {
     606             :         return MONOMORPHIC;
     607             :       }
     608     5997680 :       return UNINITIALIZED;
     609             :     }
     610             : 
     611             :     case FeedbackSlotKind::kStoreNamedSloppy:
     612             :     case FeedbackSlotKind::kStoreNamedStrict:
     613             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     614             :     case FeedbackSlotKind::kStoreKeyedStrict:
     615             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     616             :     case FeedbackSlotKind::kStoreOwnNamed:
     617             :     case FeedbackSlotKind::kLoadProperty:
     618             :     case FeedbackSlotKind::kLoadKeyed:
     619             :     case FeedbackSlotKind::kHasKeyed: {
     620     5009590 :       if (feedback == MaybeObject::FromObject(
     621             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     622             :         return UNINITIALIZED;
     623             :       }
     624     3055846 :       if (feedback == MaybeObject::FromObject(
     625             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     626             :         return MEGAMORPHIC;
     627             :       }
     628     2389581 :       if (feedback == MaybeObject::FromObject(
     629             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     630             :         return PREMONOMORPHIC;
     631             :       }
     632      921286 :       if (feedback->IsWeakOrCleared()) {
     633             :         // Don't check if the map is cleared.
     634             :         return MONOMORPHIC;
     635             :       }
     636             :       HeapObject heap_object;
     637      218071 :       if (feedback->GetHeapObjectIfStrong(&heap_object)) {
     638      218071 :         if (heap_object->IsWeakFixedArray()) {
     639             :           // Determine state purely by our structure, don't check if the maps
     640             :           // are cleared.
     641             :           return POLYMORPHIC;
     642             :         }
     643       16923 :         if (heap_object->IsName()) {
     644             :           DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     645             :                  IsKeyedHasICKind(kind()));
     646       33846 :           Object extra = GetFeedbackExtra()->GetHeapObjectAssumeStrong();
     647             :           WeakFixedArray extra_array = WeakFixedArray::cast(extra);
     648       16923 :           return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
     649             :         }
     650             :       }
     651           0 :       UNREACHABLE();
     652             :     }
     653             :     case FeedbackSlotKind::kCall: {
     654             :       HeapObject heap_object;
     655     1031449 :       if (feedback == MaybeObject::FromObject(
     656             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     657             :         return GENERIC;
     658     2700849 :       } else if (feedback->IsWeakOrCleared() ||
     659      678521 :                  (feedback->GetHeapObjectIfStrong(&heap_object) &&
     660             :                   heap_object->IsAllocationSite())) {
     661             :         return MONOMORPHIC;
     662             :       }
     663             : 
     664      676853 :       CHECK_EQ(feedback, MaybeObject::FromObject(
     665             :                              *FeedbackVector::UninitializedSentinel(isolate)));
     666             :       return UNINITIALIZED;
     667             :     }
     668             :     case FeedbackSlotKind::kBinaryOp: {
     669      273233 :       BinaryOperationHint hint = GetBinaryOperationFeedback();
     670      273233 :       if (hint == BinaryOperationHint::kNone) {
     671             :         return UNINITIALIZED;
     672      257856 :       } else if (hint == BinaryOperationHint::kAny) {
     673             :         return GENERIC;
     674             :       }
     675             : 
     676      254516 :       return MONOMORPHIC;
     677             :     }
     678             :     case FeedbackSlotKind::kCompareOp: {
     679      151557 :       CompareOperationHint hint = GetCompareOperationFeedback();
     680      151557 :       if (hint == CompareOperationHint::kNone) {
     681             :         return UNINITIALIZED;
     682      137676 :       } else if (hint == CompareOperationHint::kAny) {
     683             :         return GENERIC;
     684             :       }
     685             : 
     686      101634 :       return MONOMORPHIC;
     687             :     }
     688             :     case FeedbackSlotKind::kForIn: {
     689             :       ForInHint hint = GetForInFeedback();
     690        1353 :       if (hint == ForInHint::kNone) {
     691             :         return UNINITIALIZED;
     692        1320 :       } else if (hint == ForInHint::kAny) {
     693             :         return GENERIC;
     694             :       }
     695         484 :       return MONOMORPHIC;
     696             :     }
     697             :     case FeedbackSlotKind::kInstanceOf: {
     698        4807 :       if (feedback == MaybeObject::FromObject(
     699             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     700             :         return UNINITIALIZED;
     701        1890 :       } else if (feedback ==
     702             :                  MaybeObject::FromObject(
     703             :                      *FeedbackVector::MegamorphicSentinel(isolate))) {
     704             :         return MEGAMORPHIC;
     705             :       }
     706        1666 :       return MONOMORPHIC;
     707             :     }
     708             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     709      227678 :       if (feedback == MaybeObject::FromObject(
     710             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     711             :         return UNINITIALIZED;
     712      223476 :       } else if (feedback->IsWeakOrCleared()) {
     713             :         // Don't check if the map is cleared.
     714             :         return MONOMORPHIC;
     715             :       }
     716             : 
     717       16354 :       return MEGAMORPHIC;
     718             :     }
     719             :     case FeedbackSlotKind::kTypeProfile: {
     720           0 :       if (feedback == MaybeObject::FromObject(
     721             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     722             :         return UNINITIALIZED;
     723             :       }
     724           0 :       return MONOMORPHIC;
     725             :     }
     726             : 
     727             :     case FeedbackSlotKind::kCloneObject: {
     728         959 :       if (feedback == MaybeObject::FromObject(
     729             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     730             :         return UNINITIALIZED;
     731             :       }
     732         280 :       if (feedback == MaybeObject::FromObject(
     733             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     734             :         return MEGAMORPHIC;
     735             :       }
     736         280 :       if (feedback->IsWeakOrCleared()) {
     737             :         return MONOMORPHIC;
     738             :       }
     739             : 
     740             :       DCHECK(feedback->GetHeapObjectAssumeStrong()->IsWeakFixedArray());
     741         180 :       return POLYMORPHIC;
     742             :     }
     743             : 
     744             :     case FeedbackSlotKind::kInvalid:
     745             :     case FeedbackSlotKind::kKindsNumber:
     746           0 :       UNREACHABLE();
     747             :       break;
     748             :   }
     749             :   return UNINITIALIZED;
     750             : }
     751             : 
     752     5678275 : void FeedbackNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
     753             :   DCHECK(IsGlobalICKind(kind()));
     754             :   Isolate* isolate = GetIsolate();
     755     5678275 :   SetFeedback(HeapObjectReference::Weak(*cell));
     756    11356559 :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     757     5678280 :                    SKIP_WRITE_BARRIER);
     758     5678279 : }
     759             : 
     760       56686 : bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index,
     761             :                                             int context_slot_index,
     762             :                                             bool immutable) {
     763             :   DCHECK(IsGlobalICKind(kind()));
     764             :   DCHECK_LE(0, script_context_index);
     765             :   DCHECK_LE(0, context_slot_index);
     766      170058 :   if (!ContextIndexBits::is_valid(script_context_index) ||
     767      113372 :       !SlotIndexBits::is_valid(context_slot_index) ||
     768             :       !ImmutabilityBit::is_valid(immutable)) {
     769             :     return false;
     770             :   }
     771       56686 :   int config = ContextIndexBits::encode(script_context_index) |
     772      113372 :                SlotIndexBits::encode(context_slot_index) |
     773       56686 :                ImmutabilityBit::encode(immutable);
     774             : 
     775             :   SetFeedback(Smi::From31BitPattern(config));
     776             :   Isolate* isolate = GetIsolate();
     777      113372 :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     778       56686 :                    SKIP_WRITE_BARRIER);
     779       56686 :   return true;
     780             : }
     781             : 
     782       44655 : void FeedbackNexus::ConfigureHandlerMode(const MaybeObjectHandle& handler) {
     783             :   DCHECK(IsGlobalICKind(kind()));
     784             :   DCHECK(IC::IsHandler(*handler));
     785       44655 :   SetFeedback(HeapObjectReference::ClearedValue(GetIsolate()));
     786       44655 :   SetFeedbackExtra(*handler);
     787       44655 : }
     788             : 
     789         441 : void FeedbackNexus::ConfigureCloneObject(Handle<Map> source_map,
     790             :                                          Handle<Map> result_map) {
     791             :   Isolate* isolate = GetIsolate();
     792         441 :   MaybeObject maybe_feedback = GetFeedback();
     793             :   Handle<HeapObject> feedback(maybe_feedback->IsStrongOrWeak()
     794             :                                   ? maybe_feedback->GetHeapObject()
     795             :                                   : HeapObject(),
     796         441 :                               isolate);
     797         441 :   switch (ic_state()) {
     798             :     case UNINITIALIZED:
     799             :       // Cache the first map seen which meets the fast case requirements.
     800         315 :       SetFeedback(HeapObjectReference::Weak(*source_map));
     801         315 :       SetFeedbackExtra(*result_map);
     802         315 :       break;
     803             :     case MONOMORPHIC:
     804         108 :       if (maybe_feedback->IsCleared() || feedback.is_identical_to(source_map) ||
     805             :           Map::cast(*feedback)->is_deprecated()) {
     806             :         // Remain in MONOMORPHIC state if previous feedback has been collected.
     807           0 :         SetFeedback(HeapObjectReference::Weak(*source_map));
     808           0 :         SetFeedbackExtra(*result_map);
     809             :       } else {
     810             :         // Transition to POLYMORPHIC.
     811             :         Handle<WeakFixedArray> array =
     812          36 :             EnsureArrayOfSize(2 * kCloneObjectPolymorphicEntrySize);
     813          36 :         array->Set(0, maybe_feedback);
     814          72 :         array->Set(1, GetFeedbackExtra());
     815          72 :         array->Set(2, HeapObjectReference::Weak(*source_map));
     816          36 :         array->Set(3, MaybeObject::FromObject(*result_map));
     817          36 :         SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     818             :       }
     819             :       break;
     820             :     case POLYMORPHIC: {
     821             :       const int kMaxElements =
     822          90 :           FLAG_max_polymorphic_map_count * kCloneObjectPolymorphicEntrySize;
     823             :       Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(feedback);
     824             :       int i = 0;
     825         333 :       for (; i < array->length(); i += kCloneObjectPolymorphicEntrySize) {
     826             :         MaybeObject feedback = array->Get(i);
     827         252 :         if (feedback->IsCleared()) break;
     828             :         Handle<Map> cached_map(Map::cast(feedback->GetHeapObject()), isolate);
     829         486 :         if (cached_map.is_identical_to(source_map) ||
     830             :             cached_map->is_deprecated())
     831             :           break;
     832             :       }
     833             : 
     834          90 :       if (i >= array->length()) {
     835          81 :         if (i == kMaxElements) {
     836             :           // Transition to MEGAMORPHIC.
     837             :           MaybeObject sentinel = MaybeObject::FromObject(
     838          27 :               *FeedbackVector::MegamorphicSentinel(isolate));
     839          27 :           SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     840          27 :           SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     841             :           break;
     842             :         }
     843             : 
     844             :         // Grow polymorphic feedback array.
     845             :         Handle<WeakFixedArray> new_array = EnsureArrayOfSize(
     846          54 :             array->length() + kCloneObjectPolymorphicEntrySize);
     847         594 :         for (int j = 0; j < array->length(); ++j) {
     848         270 :           new_array->Set(j, array->Get(j));
     849             :         }
     850          54 :         array = new_array;
     851             :       }
     852             : 
     853         126 :       array->Set(i, HeapObjectReference::Weak(*source_map));
     854         126 :       array->Set(i + 1, MaybeObject::FromObject(*result_map));
     855          63 :       break;
     856             :     }
     857             : 
     858             :     default:
     859           0 :       UNREACHABLE();
     860             :   }
     861         441 : }
     862             : 
     863      505272 : int FeedbackNexus::GetCallCount() {
     864             :   DCHECK(IsCallICKind(kind()));
     865             : 
     866     1010544 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     867      505272 :   CHECK(call_count->IsSmi());
     868      505272 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     869      505272 :   return CallCountField::decode(value);
     870             : }
     871             : 
     872        1948 : void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) {
     873             :   DCHECK(IsCallICKind(kind()));
     874             : 
     875        3896 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     876        1948 :   CHECK(call_count->IsSmi());
     877        1948 :   uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count));
     878             :   uint32_t value = CallCountField::encode(CallCountField::decode(count));
     879        1948 :   int result = static_cast<int>(value | SpeculationModeField::encode(mode));
     880        1948 :   SetFeedbackExtra(Smi::FromInt(result), SKIP_WRITE_BARRIER);
     881        1948 : }
     882             : 
     883      464390 : SpeculationMode FeedbackNexus::GetSpeculationMode() {
     884             :   DCHECK(IsCallICKind(kind()));
     885             : 
     886      928780 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     887      464390 :   CHECK(call_count->IsSmi());
     888      464390 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     889      464390 :   return SpeculationModeField::decode(value);
     890             : }
     891             : 
     892      505244 : float FeedbackNexus::ComputeCallFrequency() {
     893             :   DCHECK(IsCallICKind(kind()));
     894             : 
     895      505244 :   double const invocation_count = vector()->invocation_count();
     896      505244 :   double const call_count = GetCallCount();
     897      505244 :   if (invocation_count == 0) {
     898             :     // Prevent division by 0.
     899             :     return 0.0f;
     900             :   }
     901      188602 :   return static_cast<float>(call_count / invocation_count);
     902             : }
     903             : 
     904     1941665 : void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
     905             :                                          Handle<Map> receiver_map,
     906             :                                          const MaybeObjectHandle& handler) {
     907             :   DCHECK(handler.is_null() || IC::IsHandler(*handler));
     908     1941665 :   if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) {
     909        3257 :     SetFeedback(HeapObjectReference::Weak(*receiver_map));
     910        3257 :     SetFeedbackExtra(*name);
     911             :   } else {
     912     1938408 :     if (name.is_null()) {
     913     1924441 :       SetFeedback(HeapObjectReference::Weak(*receiver_map));
     914     1924449 :       SetFeedbackExtra(*handler);
     915             :     } else {
     916       13967 :       Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2);
     917             :       SetFeedback(*name);
     918       27934 :       array->Set(0, HeapObjectReference::Weak(*receiver_map));
     919       27934 :       array->Set(1, *handler);
     920             :     }
     921             :   }
     922     1941672 : }
     923             : 
     924      226319 : void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
     925             :                                          MapHandles const& maps,
     926             :                                          MaybeObjectHandles* handlers) {
     927             :   DCHECK_EQ(handlers->size(), maps.size());
     928      226319 :   int receiver_count = static_cast<int>(maps.size());
     929             :   DCHECK_GT(receiver_count, 1);
     930             :   Handle<WeakFixedArray> array;
     931      226319 :   if (name.is_null()) {
     932      222275 :     array = EnsureArrayOfSize(receiver_count * 2);
     933      444552 :     SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(GetIsolate()),
     934      222276 :                      SKIP_WRITE_BARRIER);
     935             :   } else {
     936        4044 :     array = EnsureExtraArrayOfSize(receiver_count * 2);
     937             :     SetFeedback(*name);
     938             :   }
     939             : 
     940     1372103 :   for (int current = 0; current < receiver_count; ++current) {
     941     1145782 :     Handle<Map> map = maps[current];
     942     1145782 :     array->Set(current * 2, HeapObjectReference::Weak(*map));
     943             :     DCHECK(IC::IsHandler(*handlers->at(current)));
     944     1145779 :     array->Set(current * 2 + 1, *handlers->at(current));
     945             :   }
     946      226321 : }
     947             : 
     948     1059681 : int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
     949             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     950             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     951             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
     952             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
     953             : 
     954             :   Isolate* isolate = GetIsolate();
     955     1059681 :   MaybeObject feedback = GetFeedback();
     956     1059681 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
     957             :   HeapObject heap_object;
     958     1654477 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
     959     1965182 :        heap_object->IsWeakFixedArray()) ||
     960             :       is_named_feedback) {
     961             :     int found = 0;
     962             :     WeakFixedArray array;
     963      160225 :     if (is_named_feedback) {
     964             :       array =
     965       12088 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
     966             :     } else {
     967             :       array = WeakFixedArray::cast(heap_object);
     968             :     }
     969             :     const int increment = 2;
     970             :     HeapObject heap_object;
     971      554264 :     for (int i = 0; i < array->length(); i += increment) {
     972             :       DCHECK(array->Get(i)->IsWeakOrCleared());
     973      394039 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
     974             :         Map map = Map::cast(heap_object);
     975      650794 :         maps->push_back(handle(map, isolate));
     976      325397 :         found++;
     977             :       }
     978             :     }
     979             :     return found;
     980      899456 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
     981             :     Map map = Map::cast(heap_object);
     982      720907 :     maps->push_back(handle(map, isolate));
     983             :     return 1;
     984      973575 :   } else if (feedback->GetHeapObjectIfStrong(&heap_object) &&
     985             :              heap_object ==
     986             :                  heap_object->GetReadOnlyRoots().premonomorphic_symbol()) {
     987       16190 :     if (GetFeedbackExtra()->GetHeapObjectIfWeak(&heap_object)) {
     988             :       Map map = Map::cast(heap_object);
     989       14810 :       maps->push_back(handle(map, isolate));
     990             :       return 1;
     991             :     }
     992             :   }
     993             : 
     994             :   return 0;
     995             : }
     996             : 
     997      375536 : MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
     998             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     999             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
    1000             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
    1001             :          IsKeyedHasICKind(kind()));
    1002             : 
    1003      375536 :   MaybeObject feedback = GetFeedback();
    1004             :   Isolate* isolate = GetIsolate();
    1005      375538 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
    1006             :   HeapObject heap_object;
    1007      501198 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
    1008      627621 :        heap_object->IsWeakFixedArray()) ||
    1009             :       is_named_feedback) {
    1010             :     WeakFixedArray array;
    1011      125662 :     if (is_named_feedback) {
    1012             :       array =
    1013        4420 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
    1014             :     } else {
    1015             :       array = WeakFixedArray::cast(heap_object);
    1016             :     }
    1017             :     const int increment = 2;
    1018             :     HeapObject heap_object;
    1019      436729 :     for (int i = 0; i < array->length(); i += increment) {
    1020             :       DCHECK(array->Get(i)->IsWeakOrCleared());
    1021      311626 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
    1022             :         Map array_map = Map::cast(heap_object);
    1023      243644 :         if (array_map == *map && !array->Get(i + increment - 1)->IsCleared()) {
    1024             :           MaybeObject handler = array->Get(i + increment - 1);
    1025             :           DCHECK(IC::IsHandler(handler));
    1026             :           return handle(handler, isolate);
    1027             :         }
    1028             :       }
    1029             :     }
    1030      249874 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1031             :     Map cell_map = Map::cast(heap_object);
    1032      159864 :     if (cell_map == *map && !GetFeedbackExtra()->IsCleared()) {
    1033       12589 :       MaybeObject handler = GetFeedbackExtra();
    1034             :       DCHECK(IC::IsHandler(handler));
    1035             :       return handle(handler, isolate);
    1036             :     }
    1037             :   }
    1038             : 
    1039      362389 :   return MaybeObjectHandle();
    1040             : }
    1041             : 
    1042      508789 : bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
    1043             :                                  int length) const {
    1044             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
    1045             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
    1046             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
    1047             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
    1048             : 
    1049      508789 :   MaybeObject feedback = GetFeedback();
    1050             :   Isolate* isolate = GetIsolate();
    1051             :   int count = 0;
    1052      508790 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
    1053             :   HeapObject heap_object;
    1054      737375 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
    1055      875857 :        heap_object->IsWeakFixedArray()) ||
    1056             :       is_named_feedback) {
    1057             :     WeakFixedArray array;
    1058      146841 :     if (is_named_feedback) {
    1059             :       array =
    1060       10240 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
    1061             :     } else {
    1062             :       array = WeakFixedArray::cast(heap_object);
    1063             :     }
    1064             :     const int increment = 2;
    1065             :     HeapObject heap_object;
    1066      529746 :     for (int i = 0; i < array->length(); i += increment) {
    1067             :       // Be sure to skip handlers whose maps have been cleared.
    1068             :       DCHECK(array->Get(i)->IsWeakOrCleared());
    1069      697248 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
    1070             :           !array->Get(i + increment - 1)->IsCleared()) {
    1071             :         MaybeObject handler = array->Get(i + increment - 1);
    1072             :         DCHECK(IC::IsHandler(handler));
    1073      628662 :         code_list->push_back(handle(handler, isolate));
    1074      314331 :         count++;
    1075             :       }
    1076             :     }
    1077      361948 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1078      177103 :     MaybeObject extra = GetFeedbackExtra();
    1079      177104 :     if (!extra->IsCleared()) {
    1080             :       DCHECK(IC::IsHandler(extra));
    1081      352104 :       code_list->push_back(handle(extra, isolate));
    1082             :       count++;
    1083             :     }
    1084             :   }
    1085      508790 :   return count == length;
    1086             : }
    1087             : 
    1088       50032 : Name FeedbackNexus::GetName() const {
    1089       50032 :   if (IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
    1090             :       IsKeyedHasICKind(kind())) {
    1091       50032 :     MaybeObject feedback = GetFeedback();
    1092       50032 :     if (IsPropertyNameFeedback(feedback)) {
    1093             :       return Name::cast(feedback->GetHeapObjectAssumeStrong());
    1094             :     }
    1095             :   }
    1096       22105 :   return Name();
    1097             : }
    1098             : 
    1099       46301 : KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
    1100             :   DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedHasICKind(kind()));
    1101             :   MapHandles maps;
    1102             :   MaybeObjectHandles handlers;
    1103             : 
    1104       46301 :   if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
    1105             : 
    1106       44042 :   ExtractMaps(&maps);
    1107       44042 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1108       60795 :   for (MaybeObjectHandle const& handler : handlers) {
    1109       17648 :     KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
    1110       17648 :     if (mode != STANDARD_LOAD) return mode;
    1111             :   }
    1112             : 
    1113             :   return STANDARD_LOAD;
    1114             : }
    1115             : 
    1116             : namespace {
    1117             : 
    1118             : bool BuiltinHasKeyedAccessStoreMode(int builtin_index) {
    1119             :   DCHECK(Builtins::IsBuiltinId(builtin_index));
    1120       20188 :   switch (builtin_index) {
    1121             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1122             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1123             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1124             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1125             :     case Builtins::kStoreFastElementIC_Standard:
    1126             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1127             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1128             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1129             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1130             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1131             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1132             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1133             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1134             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1135             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1136             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1137             :     case Builtins::kElementsTransitionAndStore_Standard:
    1138             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1139             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1140             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1141             :       return true;
    1142             :     default:
    1143             :       return false;
    1144             :   }
    1145             :   UNREACHABLE();
    1146             : }
    1147             : 
    1148       20179 : KeyedAccessStoreMode KeyedAccessStoreModeForBuiltin(int builtin_index) {
    1149             :   DCHECK(BuiltinHasKeyedAccessStoreMode(builtin_index));
    1150       20179 :   switch (builtin_index) {
    1151             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1152             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1153             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1154             :     case Builtins::kStoreFastElementIC_Standard:
    1155             :     case Builtins::kElementsTransitionAndStore_Standard:
    1156             :       return STANDARD_STORE;
    1157             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1158             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1159             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1160             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1161             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1162        4701 :       return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1163             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1164             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1165             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1166             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1167             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1168         296 :       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
    1169             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1170             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1171             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1172             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1173             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1174         683 :       return STORE_NO_TRANSITION_HANDLE_COW;
    1175             :     default:
    1176           0 :       UNREACHABLE();
    1177             :   }
    1178             : }
    1179             : 
    1180             : }  // namespace
    1181             : 
    1182       73920 : KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
    1183             :   DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
    1184             :   KeyedAccessStoreMode mode = STANDARD_STORE;
    1185             :   MapHandles maps;
    1186             :   MaybeObjectHandles handlers;
    1187             : 
    1188       73920 :   if (GetKeyType() == PROPERTY) return mode;
    1189             : 
    1190       73121 :   ExtractMaps(&maps);
    1191       73120 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1192       73148 :   for (const MaybeObjectHandle& maybe_code_handler : handlers) {
    1193             :     // The first handler that isn't the slow handler will have the bits we need.
    1194             :     Handle<Code> handler;
    1195       20206 :     if (maybe_code_handler.object()->IsStoreHandler()) {
    1196             :       Handle<StoreHandler> data_handler =
    1197             :           Handle<StoreHandler>::cast(maybe_code_handler.object());
    1198             :       handler = handle(Code::cast(data_handler->smi_handler()),
    1199             :                        vector()->GetIsolate());
    1200       11702 :     } else if (maybe_code_handler.object()->IsSmi()) {
    1201             :       // Skip proxy handlers.
    1202             :       DCHECK_EQ(*(maybe_code_handler.object()),
    1203             :                 *StoreHandler::StoreProxy(GetIsolate()));
    1204             :       continue;
    1205             :     } else {
    1206             :       // Element store without prototype chain check.
    1207             :       handler = Handle<Code>::cast(maybe_code_handler.object());
    1208             :     }
    1209             : 
    1210       20188 :     if (handler->is_builtin()) {
    1211             :       const int builtin_index = handler->builtin_index();
    1212       20188 :       if (!BuiltinHasKeyedAccessStoreMode(builtin_index)) continue;
    1213             : 
    1214       20179 :       mode = KeyedAccessStoreModeForBuiltin(builtin_index);
    1215             :       break;
    1216             :     }
    1217             :   }
    1218             : 
    1219             :   return mode;
    1220             : }
    1221             : 
    1222      142330 : IcCheckType FeedbackNexus::GetKeyType() const {
    1223             :   DCHECK(IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
    1224             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
    1225      142330 :   MaybeObject feedback = GetFeedback();
    1226      142332 :   if (feedback == MaybeObject::FromObject(
    1227             :                       *FeedbackVector::MegamorphicSentinel(GetIsolate()))) {
    1228             :     return static_cast<IcCheckType>(
    1229       16632 :         Smi::ToInt(GetFeedbackExtra()->cast<Object>()));
    1230             :   }
    1231      134016 :   return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
    1232             : }
    1233             : 
    1234      967534 : BinaryOperationHint FeedbackNexus::GetBinaryOperationFeedback() const {
    1235             :   DCHECK_EQ(kind(), FeedbackSlotKind::kBinaryOp);
    1236     1935068 :   int feedback = GetFeedback().ToSmi().value();
    1237      967534 :   return BinaryOperationHintFromFeedback(feedback);
    1238             : }
    1239             : 
    1240      526601 : CompareOperationHint FeedbackNexus::GetCompareOperationFeedback() const {
    1241             :   DCHECK_EQ(kind(), FeedbackSlotKind::kCompareOp);
    1242     1053202 :   int feedback = GetFeedback().ToSmi().value();
    1243      526601 :   return CompareOperationHintFromFeedback(feedback);
    1244             : }
    1245             : 
    1246        2924 : ForInHint FeedbackNexus::GetForInFeedback() const {
    1247             :   DCHECK_EQ(kind(), FeedbackSlotKind::kForIn);
    1248        8554 :   int feedback = GetFeedback().ToSmi().value();
    1249        2924 :   return ForInHintFromFeedback(feedback);
    1250             : }
    1251             : 
    1252        2835 : MaybeHandle<JSObject> FeedbackNexus::GetConstructorFeedback() const {
    1253             :   DCHECK_EQ(kind(), FeedbackSlotKind::kInstanceOf);
    1254             :   Isolate* isolate = GetIsolate();
    1255        2835 :   MaybeObject feedback = GetFeedback();
    1256             :   HeapObject heap_object;
    1257        2835 :   if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1258          31 :     return handle(JSObject::cast(heap_object), isolate);
    1259             :   }
    1260        2804 :   return MaybeHandle<JSObject>();
    1261             : }
    1262             : 
    1263             : namespace {
    1264             : 
    1265          64 : bool InList(Handle<ArrayList> types, Handle<String> type) {
    1266         124 :   for (int i = 0; i < types->Length(); i++) {
    1267             :     Object obj = types->Get(i);
    1268          76 :     if (String::cast(obj)->Equals(*type)) {
    1269             :       return true;
    1270             :     }
    1271             :   }
    1272             :   return false;
    1273             : }
    1274             : }  // anonymous namespace
    1275             : 
    1276         228 : void FeedbackNexus::Collect(Handle<String> type, int position) {
    1277             :   DCHECK(IsTypeProfileKind(kind()));
    1278             :   DCHECK_GE(position, 0);
    1279             :   Isolate* isolate = GetIsolate();
    1280             : 
    1281         228 :   MaybeObject const feedback = GetFeedback();
    1282             : 
    1283             :   // Map source position to collection of types
    1284             :   Handle<SimpleNumberDictionary> types;
    1285             : 
    1286         228 :   if (feedback == MaybeObject::FromObject(
    1287             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1288          68 :     types = SimpleNumberDictionary::New(isolate, 1);
    1289             :   } else {
    1290             :     types = handle(
    1291             :         SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1292             :         isolate);
    1293             :   }
    1294             : 
    1295             :   Handle<ArrayList> position_specific_types;
    1296             : 
    1297         456 :   int entry = types->FindEntry(isolate, position);
    1298         228 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1299         164 :     position_specific_types = ArrayList::New(isolate, 1);
    1300             :     types = SimpleNumberDictionary::Set(
    1301             :         isolate, types, position,
    1302         328 :         ArrayList::Add(isolate, position_specific_types, type));
    1303             :   } else {
    1304             :     DCHECK(types->ValueAt(entry)->IsArrayList());
    1305             :     position_specific_types =
    1306         128 :         handle(ArrayList::cast(types->ValueAt(entry)), isolate);
    1307          64 :     if (!InList(position_specific_types, type)) {  // Add type
    1308             :       types = SimpleNumberDictionary::Set(
    1309             :           isolate, types, position,
    1310          96 :           ArrayList::Add(isolate, position_specific_types, type));
    1311             :     }
    1312             :   }
    1313             :   SetFeedback(*types);
    1314         228 : }
    1315             : 
    1316         108 : std::vector<int> FeedbackNexus::GetSourcePositions() const {
    1317             :   DCHECK(IsTypeProfileKind(kind()));
    1318             :   std::vector<int> source_positions;
    1319             :   Isolate* isolate = GetIsolate();
    1320             : 
    1321         108 :   MaybeObject const feedback = GetFeedback();
    1322             : 
    1323         108 :   if (feedback == MaybeObject::FromObject(
    1324             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1325             :     return source_positions;
    1326             :   }
    1327             : 
    1328             :   Handle<SimpleNumberDictionary> types(
    1329             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1330             :       isolate);
    1331             : 
    1332         768 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1333             :        index < types->length(); index += SimpleNumberDictionary::kEntrySize) {
    1334             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1335             :     Object key = types->get(key_index);
    1336         352 :     if (key->IsSmi()) {
    1337         148 :       int position = Smi::cast(key)->value();
    1338         148 :       source_positions.push_back(position);
    1339             :     }
    1340             :   }
    1341             :   return source_positions;
    1342             : }
    1343             : 
    1344         148 : std::vector<Handle<String>> FeedbackNexus::GetTypesForSourcePositions(
    1345             :     uint32_t position) const {
    1346             :   DCHECK(IsTypeProfileKind(kind()));
    1347             :   Isolate* isolate = GetIsolate();
    1348             : 
    1349         148 :   MaybeObject const feedback = GetFeedback();
    1350             :   std::vector<Handle<String>> types_for_position;
    1351         148 :   if (feedback == MaybeObject::FromObject(
    1352             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1353             :     return types_for_position;
    1354             :   }
    1355             : 
    1356             :   Handle<SimpleNumberDictionary> types(
    1357             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1358             :       isolate);
    1359             : 
    1360         148 :   int entry = types->FindEntry(isolate, position);
    1361         148 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1362             :     return types_for_position;
    1363             :   }
    1364             :   DCHECK(types->ValueAt(entry)->IsArrayList());
    1365             :   Handle<ArrayList> position_specific_types =
    1366         296 :       Handle<ArrayList>(ArrayList::cast(types->ValueAt(entry)), isolate);
    1367         540 :   for (int i = 0; i < position_specific_types->Length(); i++) {
    1368             :     Object t = position_specific_types->Get(i);
    1369         196 :     types_for_position.push_back(Handle<String>(String::cast(t), isolate));
    1370             :   }
    1371             : 
    1372             :   return types_for_position;
    1373             : }
    1374             : 
    1375             : namespace {
    1376             : 
    1377           0 : Handle<JSObject> ConvertToJSObject(Isolate* isolate,
    1378             :                                    Handle<SimpleNumberDictionary> feedback) {
    1379             :   Handle<JSObject> type_profile =
    1380           0 :       isolate->factory()->NewJSObject(isolate->object_function());
    1381             : 
    1382           0 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1383             :        index < feedback->length();
    1384             :        index += SimpleNumberDictionary::kEntrySize) {
    1385             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1386             :     Object key = feedback->get(key_index);
    1387           0 :     if (key->IsSmi()) {
    1388           0 :       int value_index = index + SimpleNumberDictionary::kEntryValueIndex;
    1389             : 
    1390             :       Handle<ArrayList> position_specific_types(
    1391             :           ArrayList::cast(feedback->get(value_index)), isolate);
    1392             : 
    1393             :       int position = Smi::ToInt(key);
    1394           0 :       JSObject::AddDataElement(
    1395             :           type_profile, position,
    1396             :           isolate->factory()->NewJSArrayWithElements(
    1397             :               ArrayList::Elements(isolate, position_specific_types)),
    1398           0 :           PropertyAttributes::NONE);
    1399             :     }
    1400             :   }
    1401           0 :   return type_profile;
    1402             : }
    1403             : }  // namespace
    1404             : 
    1405           0 : JSObject FeedbackNexus::GetTypeProfile() const {
    1406             :   DCHECK(IsTypeProfileKind(kind()));
    1407             :   Isolate* isolate = GetIsolate();
    1408             : 
    1409           0 :   MaybeObject const feedback = GetFeedback();
    1410             : 
    1411           0 :   if (feedback == MaybeObject::FromObject(
    1412             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1413           0 :     return *isolate->factory()->NewJSObject(isolate->object_function());
    1414             :   }
    1415             : 
    1416           0 :   return *ConvertToJSObject(isolate,
    1417             :                             handle(SimpleNumberDictionary::cast(
    1418             :                                        feedback->GetHeapObjectAssumeStrong()),
    1419             :                                    isolate));
    1420             : }
    1421             : 
    1422         212 : void FeedbackNexus::ResetTypeProfile() {
    1423             :   DCHECK(IsTypeProfileKind(kind()));
    1424             :   SetFeedback(*FeedbackVector::UninitializedSentinel(GetIsolate()));
    1425         212 : }
    1426             : 
    1427             : }  // namespace internal
    1428      120216 : }  // namespace v8

Generated by: LCOV version 1.10