LCOV - code coverage report
Current view: top level - src - feedback-vector.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 460 531 86.6 %
Date: 2019-02-19 Functions: 55 63 87.3 %

          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    17256639 : FeedbackSlot FeedbackVectorSpec::AddSlot(FeedbackSlotKind kind) {
      19             :   int slot = slots();
      20    17256639 :   int entries_per_slot = FeedbackMetadata::GetSlotSize(kind);
      21             :   append(kind);
      22    29481244 :   for (int i = 1; i < entries_per_slot; i++) {
      23             :     append(FeedbackSlotKind::kInvalid);
      24             :   }
      25    17256484 :   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     1984913 : static bool IsPropertyNameFeedback(MaybeObject feedback) {
      45     1984913 :   HeapObject heap_object;
      46     1984913 :   if (!feedback->GetHeapObjectIfStrong(&heap_object)) return false;
      47     1014231 :   if (heap_object->IsString()) {
      48             :     DCHECK(heap_object->IsInternalizedString());
      49             :     return true;
      50             :   }
      51      987804 :   if (!heap_object->IsSymbol()) return false;
      52      558009 :   Symbol symbol = Symbol::cast(heap_object);
      53      558009 :   ReadOnlyRoots roots = symbol->GetReadOnlyRoots();
      54       36668 :   return symbol != roots.uninitialized_symbol() &&
      55      586330 :          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         451 : FeedbackSlotKind FeedbackMetadata::GetKind(FeedbackSlot slot) const {
      64             :   int index = VectorICComputer::index(0, slot.ToInt());
      65             :   int data = get(index);
      66    47845319 :   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    56146086 :   int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
      73             :   set(index, new_data);
      74           0 : }
      75             : 
      76             : // static
      77     2081398 : Handle<FeedbackMetadata> FeedbackMetadata::New(Isolate* isolate,
      78             :                                                const FeedbackVectorSpec* spec) {
      79             :   Factory* factory = isolate->factory();
      80             : 
      81     2081398 :   const int slot_count = spec == nullptr ? 0 : spec->slots();
      82     2081398 :   if (slot_count == 0) {
      83             :     return factory->empty_feedback_metadata();
      84             :   }
      85             : #ifdef DEBUG
      86             :   for (int i = 0; i < slot_count;) {
      87             :     DCHECK(spec);
      88             :     FeedbackSlotKind kind = spec->GetKind(FeedbackSlot(i));
      89             :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
      90             :     for (int j = 1; j < entry_size; j++) {
      91             :       FeedbackSlotKind kind = spec->GetKind(FeedbackSlot(i + j));
      92             :       DCHECK_EQ(FeedbackSlotKind::kInvalid, kind);
      93             :     }
      94             :     i += entry_size;
      95             :   }
      96             : #endif
      97             : 
      98     1588374 :   Handle<FeedbackMetadata> metadata = factory->NewFeedbackMetadata(slot_count);
      99             : 
     100             :   // Initialize the slots. The raw data section has already been pre-zeroed in
     101             :   // NewFeedbackMetadata.
     102    29661420 :   for (int i = 0; i < slot_count; i++) {
     103             :     DCHECK(spec);
     104             :     FeedbackSlot slot(i);
     105             :     FeedbackSlotKind kind = spec->GetKind(slot);
     106             :     metadata->SetKind(slot, kind);
     107             :   }
     108             : 
     109     1588380 :   return metadata;
     110             : }
     111             : 
     112           0 : bool FeedbackMetadata::SpecDiffersFrom(
     113             :     const FeedbackVectorSpec* other_spec) const {
     114           0 :   if (other_spec->slots() != slot_count()) {
     115             :     return true;
     116             :   }
     117             : 
     118             :   int slots = slot_count();
     119           0 :   for (int i = 0; i < slots;) {
     120             :     FeedbackSlot slot(i);
     121             :     FeedbackSlotKind kind = GetKind(slot);
     122           0 :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
     123             : 
     124           0 :     if (kind != other_spec->GetKind(slot)) {
     125             :       return true;
     126             :     }
     127           0 :     i += entry_size;
     128             :   }
     129             :   return false;
     130             : }
     131             : 
     132           0 : const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) {
     133           0 :   switch (kind) {
     134             :     case FeedbackSlotKind::kInvalid:
     135             :       return "Invalid";
     136             :     case FeedbackSlotKind::kCall:
     137           0 :       return "Call";
     138             :     case FeedbackSlotKind::kLoadProperty:
     139           0 :       return "LoadProperty";
     140             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     141           0 :       return "LoadGlobalInsideTypeof";
     142             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     143           0 :       return "LoadGlobalNotInsideTypeof";
     144             :     case FeedbackSlotKind::kLoadKeyed:
     145           0 :       return "LoadKeyed";
     146             :     case FeedbackSlotKind::kStoreNamedSloppy:
     147           0 :       return "StoreNamedSloppy";
     148             :     case FeedbackSlotKind::kStoreNamedStrict:
     149           0 :       return "StoreNamedStrict";
     150             :     case FeedbackSlotKind::kStoreOwnNamed:
     151           0 :       return "StoreOwnNamed";
     152             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     153           0 :       return "StoreGlobalSloppy";
     154             :     case FeedbackSlotKind::kStoreGlobalStrict:
     155           0 :       return "StoreGlobalStrict";
     156             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     157           0 :       return "StoreKeyedSloppy";
     158             :     case FeedbackSlotKind::kStoreKeyedStrict:
     159           0 :       return "StoreKeyedStrict";
     160             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     161           0 :       return "StoreInArrayLiteral";
     162             :     case FeedbackSlotKind::kBinaryOp:
     163           0 :       return "BinaryOp";
     164             :     case FeedbackSlotKind::kCompareOp:
     165           0 :       return "CompareOp";
     166             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     167           0 :       return "StoreDataPropertyInLiteral";
     168             :     case FeedbackSlotKind::kCreateClosure:
     169           0 :       return "kCreateClosure";
     170             :     case FeedbackSlotKind::kLiteral:
     171           0 :       return "Literal";
     172             :     case FeedbackSlotKind::kTypeProfile:
     173           0 :       return "TypeProfile";
     174             :     case FeedbackSlotKind::kForIn:
     175           0 :       return "ForIn";
     176             :     case FeedbackSlotKind::kInstanceOf:
     177           0 :       return "InstanceOf";
     178             :     case FeedbackSlotKind::kCloneObject:
     179           0 :       return "CloneObject";
     180             :     case FeedbackSlotKind::kKindsNumber:
     181             :       break;
     182             :   }
     183           0 :   UNREACHABLE();
     184             : }
     185             : 
     186         452 : bool FeedbackMetadata::HasTypeProfileSlot() const {
     187             :   FeedbackSlot slot =
     188             :       FeedbackVector::ToSlot(FeedbackVectorSpec::kTypeProfileSlotIndex);
     189         872 :   return slot.ToInt() < slot_count() &&
     190         452 :          GetKind(slot) == FeedbackSlotKind::kTypeProfile;
     191             : }
     192             : 
     193    23299545 : FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
     194             :   DCHECK(!is_empty());
     195    23299552 :   return metadata()->GetKind(slot);
     196             : }
     197             : 
     198         440 : FeedbackSlot FeedbackVector::GetTypeProfileSlot() const {
     199             :   DCHECK(metadata()->HasTypeProfileSlot());
     200             :   FeedbackSlot slot =
     201             :       FeedbackVector::ToSlot(FeedbackVectorSpec::kTypeProfileSlotIndex);
     202             :   DCHECK_EQ(FeedbackSlotKind::kTypeProfile, GetKind(slot));
     203         440 :   return slot;
     204             : }
     205             : 
     206             : // static
     207     3062179 : Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate,
     208             :                                            Handle<SharedFunctionInfo> shared) {
     209             :   Factory* factory = isolate->factory();
     210             : 
     211     6124362 :   const int slot_count = shared->feedback_metadata()->slot_count();
     212             : 
     213     3062181 :   Handle<FeedbackVector> vector = factory->NewFeedbackVector(shared, TENURED);
     214             : 
     215             :   DCHECK_EQ(vector->length(), slot_count);
     216             : 
     217             :   DCHECK_EQ(vector->shared_function_info(), *shared);
     218             :   DCHECK_EQ(
     219             :       vector->optimized_code_weak_or_smi(),
     220             :       MaybeObject::FromSmi(Smi::FromEnum(
     221             :           FLAG_log_function_events ? OptimizationMarker::kLogFirstExecution
     222             :                                    : OptimizationMarker::kNone)));
     223             :   DCHECK_EQ(vector->invocation_count(), 0);
     224             :   DCHECK_EQ(vector->profiler_ticks(), 0);
     225             :   DCHECK_EQ(vector->deopt_count(), 0);
     226             : 
     227             :   // Ensure we can skip the write barrier
     228             :   Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
     229             :   DCHECK_EQ(ReadOnlyRoots(isolate).uninitialized_symbol(),
     230             :             *uninitialized_sentinel);
     231             :   Handle<Oddball> undefined_value = factory->undefined_value();
     232    30588160 :   for (int i = 0; i < slot_count;) {
     233             :     FeedbackSlot slot(i);
     234    48927590 :     FeedbackSlotKind kind = shared->feedback_metadata()->GetKind(slot);
     235             :     int index = FeedbackVector::GetIndex(slot);
     236    24463799 :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
     237             : 
     238             :     Object extra_value = *uninitialized_sentinel;
     239    24463800 :     switch (kind) {
     240             :       case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     241             :       case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     242             :       case FeedbackSlotKind::kStoreGlobalSloppy:
     243             :       case FeedbackSlotKind::kStoreGlobalStrict:
     244             :         vector->set(index, HeapObjectReference::ClearedValue(isolate),
     245    12368202 :                     SKIP_WRITE_BARRIER);
     246     6184101 :         break;
     247             :       case FeedbackSlotKind::kForIn:
     248             :       case FeedbackSlotKind::kCompareOp:
     249             :       case FeedbackSlotKind::kBinaryOp:
     250     5392688 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     251     2696344 :         break;
     252             :       case FeedbackSlotKind::kCreateClosure: {
     253     4026398 :         Handle<FeedbackCell> cell = factory->NewNoClosuresCell(undefined_value);
     254     8052790 :         vector->set(index, *cell);
     255             :         break;
     256             :       }
     257             :       case FeedbackSlotKind::kLiteral:
     258      776130 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     259      388065 :         break;
     260             :       case FeedbackSlotKind::kCall:
     261    11491165 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     262             :         extra_value = Smi::kZero;
     263     5745582 :         break;
     264             :       case FeedbackSlotKind::kCloneObject:
     265             :       case FeedbackSlotKind::kLoadProperty:
     266             :       case FeedbackSlotKind::kLoadKeyed:
     267             :       case FeedbackSlotKind::kStoreNamedSloppy:
     268             :       case FeedbackSlotKind::kStoreNamedStrict:
     269             :       case FeedbackSlotKind::kStoreOwnNamed:
     270             :       case FeedbackSlotKind::kStoreKeyedSloppy:
     271             :       case FeedbackSlotKind::kStoreKeyedStrict:
     272             :       case FeedbackSlotKind::kStoreInArrayLiteral:
     273             :       case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     274             :       case FeedbackSlotKind::kTypeProfile:
     275             :       case FeedbackSlotKind::kInstanceOf:
     276    10846668 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     277     5423334 :         break;
     278             : 
     279             :       case FeedbackSlotKind::kInvalid:
     280             :       case FeedbackSlotKind::kKindsNumber:
     281           0 :         UNREACHABLE();
     282             :         break;
     283             :     }
     284    41792512 :     for (int j = 1; j < entry_size; j++) {
     285    51986119 :       vector->set(index + j, extra_value, SKIP_WRITE_BARRIER);
     286             :     }
     287    24463804 :     i += entry_size;
     288             :   }
     289             : 
     290     3062184 :   Handle<FeedbackVector> result = Handle<FeedbackVector>::cast(vector);
     291     6123244 :   if (!isolate->is_best_effort_code_coverage() ||
     292             :       isolate->is_collecting_type_profile()) {
     293        1192 :     AddToVectorsForProfilingTools(isolate, result);
     294             :   }
     295     3062184 :   return result;
     296             : }
     297             : 
     298             : // static
     299        1192 : void FeedbackVector::AddToVectorsForProfilingTools(
     300             :     Isolate* isolate, Handle<FeedbackVector> vector) {
     301             :   DCHECK(!isolate->is_best_effort_code_coverage() ||
     302             :          isolate->is_collecting_type_profile());
     303        1192 :   if (!vector->shared_function_info()->IsSubjectToDebugging()) return;
     304             :   Handle<ArrayList> list = Handle<ArrayList>::cast(
     305        1192 :       isolate->factory()->feedback_vectors_for_profiling_tools());
     306        1192 :   list = ArrayList::Add(isolate, list, vector);
     307        1192 :   isolate->SetFeedbackVectorsForProfilingTools(*list);
     308             : }
     309             : 
     310             : // static
     311       22993 : void FeedbackVector::SetOptimizedCode(Handle<FeedbackVector> vector,
     312             :                                       Handle<Code> code) {
     313             :   DCHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
     314       45986 :   vector->set_optimized_code_weak_or_smi(HeapObjectReference::Weak(*code));
     315       22993 : }
     316             : 
     317           0 : void FeedbackVector::ClearOptimizedCode() {
     318             :   DCHECK(has_optimized_code());
     319             :   SetOptimizationMarker(OptimizationMarker::kNone);
     320           0 : }
     321             : 
     322      754277 : void FeedbackVector::ClearOptimizationMarker() {
     323             :   DCHECK(!has_optimized_code());
     324             :   SetOptimizationMarker(OptimizationMarker::kNone);
     325      754277 : }
     326             : 
     327      492048 : void FeedbackVector::SetOptimizationMarker(OptimizationMarker marker) {
     328     1248573 :   set_optimized_code_weak_or_smi(MaybeObject::FromSmi(Smi::FromEnum(marker)));
     329      492048 : }
     330             : 
     331     4392397 : void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
     332             :     SharedFunctionInfo shared, const char* reason) {
     333     4392397 :   MaybeObject slot = optimized_code_weak_or_smi();
     334     4392397 :   if (slot->IsSmi()) {
     335     3949759 :     return;
     336             :   }
     337             : 
     338      442901 :   if (slot->IsCleared()) {
     339             :     ClearOptimizationMarker();
     340             :     return;
     341             :   }
     342             : 
     343      885276 :   Code code = Code::cast(slot->GetHeapObject());
     344      442638 :   if (code->marked_for_deoptimization()) {
     345        1985 :     if (FLAG_trace_deopt) {
     346             :       PrintF("[evicting optimizing code marked for deoptimization (%s) for ",
     347           0 :              reason);
     348           0 :       shared->ShortPrint();
     349           0 :       PrintF("]\n");
     350             :     }
     351        1985 :     if (!code->deopt_already_counted()) {
     352             :       increment_deopt_count();
     353        1218 :       code->set_deopt_already_counted(true);
     354             :     }
     355             :     ClearOptimizedCode();
     356             :   }
     357             : }
     358             : 
     359       52330 : bool FeedbackVector::ClearSlots(Isolate* isolate) {
     360             :   MaybeObject uninitialized_sentinel = MaybeObject::FromObject(
     361       52330 :       FeedbackVector::RawUninitializedSentinel(isolate));
     362             : 
     363             :   bool feedback_updated = false;
     364             :   FeedbackMetadataIterator iter(metadata());
     365      132976 :   while (iter.HasNext()) {
     366       80646 :     FeedbackSlot slot = iter.Next();
     367             : 
     368             :     MaybeObject obj = Get(slot);
     369       80646 :     if (obj != uninitialized_sentinel) {
     370             :       FeedbackNexus nexus(*this, slot);
     371       55515 :       feedback_updated |= nexus.Clear();
     372             :     }
     373             :   }
     374       52330 :   return feedback_updated;
     375             : }
     376             : 
     377      411050 : void FeedbackVector::AssertNoLegacyTypes(MaybeObject object) {
     378             : #ifdef DEBUG
     379             :   HeapObject heap_object;
     380             :   if (object->GetHeapObject(&heap_object)) {
     381             :     // Instead of FixedArray, the Feedback and the Extra should contain
     382             :     // WeakFixedArrays. The only allowed FixedArray subtype is HashTable.
     383             :     DCHECK_IMPLIES(heap_object->IsFixedArray(), heap_object->IsHashTable());
     384             :   }
     385             : #endif
     386      411050 : }
     387             : 
     388      224704 : Handle<WeakFixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
     389      224704 :   Isolate* isolate = GetIsolate();
     390      224707 :   HeapObject heap_object;
     391      534326 :   if (GetFeedback()->GetHeapObjectIfStrong(&heap_object) &&
     392      309431 :       heap_object->IsWeakFixedArray() &&
     393             :       WeakFixedArray::cast(heap_object)->length() == length) {
     394             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     395             :   }
     396      218252 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     397             :   SetFeedback(*array);
     398      218254 :   return array;
     399             : }
     400             : 
     401       16559 : Handle<WeakFixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
     402       16559 :   Isolate* isolate = GetIsolate();
     403       16559 :   HeapObject heap_object;
     404       36909 :   if (GetFeedbackExtra()->GetHeapObjectIfStrong(&heap_object) &&
     405       20336 :       heap_object->IsWeakFixedArray() &&
     406             :       WeakFixedArray::cast(heap_object)->length() == length) {
     407             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     408             :   }
     409       16340 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     410       16340 :   SetFeedbackExtra(*array);
     411       16340 :   return array;
     412             : }
     413             : 
     414       90754 : void FeedbackNexus::ConfigureUninitialized() {
     415       45377 :   Isolate* isolate = GetIsolate();
     416       45377 :   switch (kind()) {
     417             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     418             :     case FeedbackSlotKind::kStoreGlobalStrict:
     419             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     420             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     421             :       SetFeedback(HeapObjectReference::ClearedValue(isolate),
     422        8066 :                   SKIP_WRITE_BARRIER);
     423             :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     424        8066 :                        SKIP_WRITE_BARRIER);
     425        8066 :       break;
     426             :     }
     427             :     case FeedbackSlotKind::kCloneObject:
     428             :     case FeedbackSlotKind::kCall: {
     429             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     430             :                   SKIP_WRITE_BARRIER);
     431        6428 :       SetFeedbackExtra(Smi::kZero, SKIP_WRITE_BARRIER);
     432        6428 :       break;
     433             :     }
     434             :     case FeedbackSlotKind::kInstanceOf: {
     435             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     436             :                   SKIP_WRITE_BARRIER);
     437           0 :       break;
     438             :     }
     439             :     case FeedbackSlotKind::kStoreNamedSloppy:
     440             :     case FeedbackSlotKind::kStoreNamedStrict:
     441             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     442             :     case FeedbackSlotKind::kStoreKeyedStrict:
     443             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     444             :     case FeedbackSlotKind::kStoreOwnNamed:
     445             :     case FeedbackSlotKind::kLoadProperty:
     446             :     case FeedbackSlotKind::kLoadKeyed:
     447             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     448             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     449             :                   SKIP_WRITE_BARRIER);
     450             :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     451       30883 :                        SKIP_WRITE_BARRIER);
     452       30883 :       break;
     453             :     }
     454             :     default:
     455           0 :       UNREACHABLE();
     456             :   }
     457       45377 : }
     458             : 
     459       55515 : bool FeedbackNexus::Clear() {
     460             :   bool feedback_updated = false;
     461             : 
     462             :   switch (kind()) {
     463             :     case FeedbackSlotKind::kCreateClosure:
     464             :     case FeedbackSlotKind::kTypeProfile:
     465             :       // We don't clear these kinds ever.
     466             :       break;
     467             : 
     468             :     case FeedbackSlotKind::kCompareOp:
     469             :     case FeedbackSlotKind::kForIn:
     470             :     case FeedbackSlotKind::kBinaryOp:
     471             :       // We don't clear these, either.
     472             :       break;
     473             : 
     474             :     case FeedbackSlotKind::kLiteral:
     475             :       SetFeedback(Smi::kZero, SKIP_WRITE_BARRIER);
     476             :       feedback_updated = true;
     477          13 :       break;
     478             : 
     479             :     case FeedbackSlotKind::kStoreNamedSloppy:
     480             :     case FeedbackSlotKind::kStoreNamedStrict:
     481             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     482             :     case FeedbackSlotKind::kStoreKeyedStrict:
     483             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     484             :     case FeedbackSlotKind::kStoreOwnNamed:
     485             :     case FeedbackSlotKind::kLoadProperty:
     486             :     case FeedbackSlotKind::kLoadKeyed:
     487             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     488             :     case FeedbackSlotKind::kStoreGlobalStrict:
     489             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     490             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     491             :     case FeedbackSlotKind::kCall:
     492             :     case FeedbackSlotKind::kInstanceOf:
     493             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     494             :     case FeedbackSlotKind::kCloneObject:
     495       47391 :       if (!IsCleared()) {
     496       45377 :         ConfigureUninitialized();
     497             :         feedback_updated = true;
     498             :       }
     499             :       break;
     500             : 
     501             :     case FeedbackSlotKind::kInvalid:
     502             :     case FeedbackSlotKind::kKindsNumber:
     503           0 :       UNREACHABLE();
     504             :       break;
     505             :   }
     506       55515 :   return feedback_updated;
     507             : }
     508             : 
     509      645123 : void FeedbackNexus::ConfigurePremonomorphic(Handle<Map> receiver_map) {
     510      645123 :   SetFeedback(*FeedbackVector::PremonomorphicSentinel(GetIsolate()),
     511             :               SKIP_WRITE_BARRIER);
     512      645124 :   SetFeedbackExtra(HeapObjectReference::Weak(*receiver_map));
     513      645128 : }
     514             : 
     515         126 : bool FeedbackNexus::ConfigureMegamorphic() {
     516             :   DisallowHeapAllocation no_gc;
     517         126 :   Isolate* isolate = GetIsolate();
     518             :   MaybeObject sentinel =
     519             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     520         252 :   if (GetFeedback() != sentinel) {
     521         126 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     522         126 :     SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     523         126 :     return true;
     524             :   }
     525             : 
     526             :   return false;
     527             : }
     528             : 
     529       45174 : bool FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) {
     530             :   DisallowHeapAllocation no_gc;
     531       45174 :   Isolate* isolate = GetIsolate();
     532             :   bool changed = false;
     533             :   MaybeObject sentinel =
     534             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     535       90348 :   if (GetFeedback() != sentinel) {
     536       41491 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     537             :     changed = true;
     538             :   }
     539             : 
     540       45174 :   Smi extra = Smi::FromInt(static_cast<int>(property_type));
     541       48857 :   if (changed || GetFeedbackExtra() != MaybeObject::FromSmi(extra)) {
     542       41491 :     SetFeedbackExtra(extra, SKIP_WRITE_BARRIER);
     543             :     changed = true;
     544             :   }
     545       45174 :   return changed;
     546             : }
     547             : 
     548      103754 : Map FeedbackNexus::GetFirstMap() const {
     549             :   MapHandles maps;
     550      103754 :   ExtractMaps(&maps);
     551      207508 :   if (maps.size() > 0) return *maps.at(0);
     552           4 :   return Map();
     553             : }
     554             : 
     555    25906334 : InlineCacheState FeedbackNexus::ic_state() const {
     556    12953163 :   Isolate* isolate = GetIsolate();
     557    12953160 :   MaybeObject feedback = GetFeedback();
     558             : 
     559    12953171 :   switch (kind()) {
     560             :     case FeedbackSlotKind::kCreateClosure:
     561             :       return MONOMORPHIC;
     562             : 
     563             :     case FeedbackSlotKind::kLiteral:
     564       51333 :       if (feedback->IsSmi()) return UNINITIALIZED;
     565        7633 :       return MONOMORPHIC;
     566             : 
     567             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     568             :     case FeedbackSlotKind::kStoreGlobalStrict:
     569             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     570             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     571     6431608 :       if (feedback->IsSmi()) return MONOMORPHIC;
     572             : 
     573     6431318 :       if (feedback == MaybeObject::FromObject(
     574             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     575             :         DCHECK(kind() == FeedbackSlotKind::kStoreGlobalSloppy ||
     576             :                kind() == FeedbackSlotKind::kStoreGlobalStrict);
     577             :         return PREMONOMORPHIC;
     578             :       }
     579             : 
     580             :       DCHECK(feedback->IsWeakOrCleared());
     581     6431287 :       MaybeObject extra = GetFeedbackExtra();
     582    12446627 :       if (!feedback->IsCleared() ||
     583             :           extra != MaybeObject::FromObject(
     584             :                        *FeedbackVector::UninitializedSentinel(isolate))) {
     585             :         return MONOMORPHIC;
     586             :       }
     587     6010637 :       return UNINITIALIZED;
     588             :     }
     589             : 
     590             :     case FeedbackSlotKind::kStoreNamedSloppy:
     591             :     case FeedbackSlotKind::kStoreNamedStrict:
     592             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     593             :     case FeedbackSlotKind::kStoreKeyedStrict:
     594             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     595             :     case FeedbackSlotKind::kStoreOwnNamed:
     596             :     case FeedbackSlotKind::kLoadProperty:
     597             :     case FeedbackSlotKind::kLoadKeyed: {
     598     4780204 :       if (feedback == MaybeObject::FromObject(
     599             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     600             :         return UNINITIALIZED;
     601             :       }
     602     2947330 :       if (feedback == MaybeObject::FromObject(
     603             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     604             :         return MEGAMORPHIC;
     605             :       }
     606     2286626 :       if (feedback == MaybeObject::FromObject(
     607             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     608             :         return PREMONOMORPHIC;
     609             :       }
     610      900322 :       if (feedback->IsWeakOrCleared()) {
     611             :         // Don't check if the map is cleared.
     612             :         return MONOMORPHIC;
     613             :       }
     614      219864 :       HeapObject heap_object;
     615      219864 :       if (feedback->GetHeapObjectIfStrong(&heap_object)) {
     616      219864 :         if (heap_object->IsWeakFixedArray()) {
     617             :           // Determine state purely by our structure, don't check if the maps
     618             :           // are cleared.
     619             :           return POLYMORPHIC;
     620             :         }
     621       15504 :         if (heap_object->IsName()) {
     622             :           DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()));
     623       15504 :           Object extra = GetFeedbackExtra()->GetHeapObjectAssumeStrong();
     624             :           WeakFixedArray extra_array = WeakFixedArray::cast(extra);
     625       15504 :           return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
     626             :         }
     627             :       }
     628           0 :       UNREACHABLE();
     629             :     }
     630             :     case FeedbackSlotKind::kCall: {
     631     1027778 :       HeapObject heap_object;
     632     1027778 :       if (feedback == MaybeObject::FromObject(
     633             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     634             :         return GENERIC;
     635     2681325 :       } else if (feedback->IsWeakOrCleared() ||
     636     1334282 :                  (feedback->GetHeapObjectIfStrong(&heap_object) &&
     637             :                   heap_object->IsAllocationSite())) {
     638             :         return MONOMORPHIC;
     639             :       }
     640             : 
     641     1330784 :       CHECK_EQ(feedback, MaybeObject::FromObject(
     642             :                              *FeedbackVector::UninitializedSentinel(isolate)));
     643             :       return UNINITIALIZED;
     644             :     }
     645             :     case FeedbackSlotKind::kBinaryOp: {
     646      273857 :       BinaryOperationHint hint = GetBinaryOperationFeedback();
     647      273857 :       if (hint == BinaryOperationHint::kNone) {
     648             :         return UNINITIALIZED;
     649      258659 :       } else if (hint == BinaryOperationHint::kAny) {
     650             :         return GENERIC;
     651             :       }
     652             : 
     653      255341 :       return MONOMORPHIC;
     654             :     }
     655             :     case FeedbackSlotKind::kCompareOp: {
     656      153013 :       CompareOperationHint hint = GetCompareOperationFeedback();
     657      153013 :       if (hint == CompareOperationHint::kNone) {
     658             :         return UNINITIALIZED;
     659      139027 :       } else if (hint == CompareOperationHint::kAny) {
     660             :         return GENERIC;
     661             :       }
     662             : 
     663      102756 :       return MONOMORPHIC;
     664             :     }
     665             :     case FeedbackSlotKind::kForIn: {
     666        1380 :       ForInHint hint = GetForInFeedback();
     667        1380 :       if (hint == ForInHint::kNone) {
     668             :         return UNINITIALIZED;
     669        1347 :       } else if (hint == ForInHint::kAny) {
     670             :         return GENERIC;
     671             :       }
     672         483 :       return MONOMORPHIC;
     673             :     }
     674             :     case FeedbackSlotKind::kInstanceOf: {
     675        4885 :       if (feedback == MaybeObject::FromObject(
     676             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     677             :         return UNINITIALIZED;
     678        2030 :       } else if (feedback ==
     679             :                  MaybeObject::FromObject(
     680             :                      *FeedbackVector::MegamorphicSentinel(isolate))) {
     681             :         return MEGAMORPHIC;
     682             :       }
     683        1809 :       return MONOMORPHIC;
     684             :     }
     685             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     686      228167 :       if (feedback == MaybeObject::FromObject(
     687             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     688             :         return UNINITIALIZED;
     689      223965 :       } else if (feedback->IsWeakOrCleared()) {
     690             :         // Don't check if the map is cleared.
     691             :         return MONOMORPHIC;
     692             :       }
     693             : 
     694       16354 :       return MEGAMORPHIC;
     695             :     }
     696             :     case FeedbackSlotKind::kTypeProfile: {
     697           0 :       if (feedback == MaybeObject::FromObject(
     698             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     699             :         return UNINITIALIZED;
     700             :       }
     701           0 :       return MONOMORPHIC;
     702             :     }
     703             : 
     704             :     case FeedbackSlotKind::kCloneObject: {
     705         940 :       if (feedback == MaybeObject::FromObject(
     706             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     707             :         return UNINITIALIZED;
     708             :       }
     709         280 :       if (feedback == MaybeObject::FromObject(
     710             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     711             :         return MEGAMORPHIC;
     712             :       }
     713         280 :       if (feedback->IsWeakOrCleared()) {
     714             :         return MONOMORPHIC;
     715             :       }
     716             : 
     717             :       DCHECK(feedback->GetHeapObjectAssumeStrong()->IsWeakFixedArray());
     718         180 :       return POLYMORPHIC;
     719             :     }
     720             : 
     721             :     case FeedbackSlotKind::kInvalid:
     722             :     case FeedbackSlotKind::kKindsNumber:
     723           0 :       UNREACHABLE();
     724             :       break;
     725             :   }
     726           0 :   return UNINITIALIZED;
     727             : }
     728             : 
     729     5620887 : void FeedbackNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
     730             :   DCHECK(IsGlobalICKind(kind()));
     731     5620887 :   Isolate* isolate = GetIsolate();
     732     5620893 :   SetFeedback(HeapObjectReference::Weak(*cell));
     733             :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     734     5620896 :                    SKIP_WRITE_BARRIER);
     735     5620896 : }
     736             : 
     737       55393 : bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index,
     738             :                                             int context_slot_index,
     739             :                                             bool immutable) {
     740             :   DCHECK(IsGlobalICKind(kind()));
     741             :   DCHECK_LE(0, script_context_index);
     742             :   DCHECK_LE(0, context_slot_index);
     743      166179 :   if (!ContextIndexBits::is_valid(script_context_index) ||
     744      110787 :       !SlotIndexBits::is_valid(context_slot_index) ||
     745             :       !ImmutabilityBit::is_valid(immutable)) {
     746             :     return false;
     747             :   }
     748       55394 :   int config = ContextIndexBits::encode(script_context_index) |
     749      110788 :                SlotIndexBits::encode(context_slot_index) |
     750       55394 :                ImmutabilityBit::encode(immutable);
     751             : 
     752             :   SetFeedback(Smi::From31BitPattern(config));
     753       55393 :   Isolate* isolate = GetIsolate();
     754             :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     755       55394 :                    SKIP_WRITE_BARRIER);
     756       55392 :   return true;
     757             : }
     758             : 
     759       44550 : void FeedbackNexus::ConfigureHandlerMode(const MaybeObjectHandle& handler) {
     760             :   DCHECK(IsGlobalICKind(kind()));
     761             :   DCHECK(IC::IsHandler(*handler));
     762       89100 :   SetFeedback(HeapObjectReference::ClearedValue(GetIsolate()));
     763       44550 :   SetFeedbackExtra(*handler);
     764       44550 : }
     765             : 
     766         432 : void FeedbackNexus::ConfigureCloneObject(Handle<Map> source_map,
     767             :                                          Handle<Map> result_map) {
     768         432 :   Isolate* isolate = GetIsolate();
     769         432 :   MaybeObject maybe_feedback = GetFeedback();
     770             :   Handle<HeapObject> feedback(maybe_feedback->IsStrongOrWeak()
     771             :                                   ? maybe_feedback->GetHeapObject()
     772             :                                   : HeapObject(),
     773         432 :                               isolate);
     774         432 :   switch (ic_state()) {
     775             :     case UNINITIALIZED:
     776             :       // Cache the first map seen which meets the fast case requirements.
     777         306 :       SetFeedback(HeapObjectReference::Weak(*source_map));
     778         306 :       SetFeedbackExtra(*result_map);
     779         306 :       break;
     780             :     case MONOMORPHIC:
     781         144 :       if (maybe_feedback->IsCleared() || feedback.is_identical_to(source_map) ||
     782          72 :           Map::cast(*feedback)->is_deprecated()) {
     783             :         // Remain in MONOMORPHIC state if previous feedback has been collected.
     784           0 :         SetFeedback(HeapObjectReference::Weak(*source_map));
     785           0 :         SetFeedbackExtra(*result_map);
     786             :       } else {
     787             :         // Transition to POLYMORPHIC.
     788             :         Handle<WeakFixedArray> array =
     789          36 :             EnsureArrayOfSize(2 * kCloneObjectPolymorphicEntrySize);
     790          36 :         array->Set(0, maybe_feedback);
     791          72 :         array->Set(1, GetFeedbackExtra());
     792          72 :         array->Set(2, HeapObjectReference::Weak(*source_map));
     793          36 :         array->Set(3, MaybeObject::FromObject(*result_map));
     794          36 :         SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     795             :       }
     796             :       break;
     797             :     case POLYMORPHIC: {
     798             :       const int kMaxElements =
     799          90 :           FLAG_max_polymorphic_map_count * kCloneObjectPolymorphicEntrySize;
     800          90 :       Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(feedback);
     801             :       int i = 0;
     802         666 :       for (; i < array->length(); i += kCloneObjectPolymorphicEntrySize) {
     803         252 :         MaybeObject feedback = array->Get(i);
     804         252 :         if (feedback->IsCleared()) break;
     805         486 :         Handle<Map> cached_map(Map::cast(feedback->GetHeapObject()), isolate);
     806         729 :         if (cached_map.is_identical_to(source_map) ||
     807         729 :             cached_map->is_deprecated())
     808             :           break;
     809             :       }
     810             : 
     811          90 :       if (i >= array->length()) {
     812          81 :         if (i == kMaxElements) {
     813             :           // Transition to MEGAMORPHIC.
     814             :           MaybeObject sentinel = MaybeObject::FromObject(
     815          27 :               *FeedbackVector::MegamorphicSentinel(isolate));
     816          27 :           SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     817          27 :           SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     818             :           break;
     819             :         }
     820             : 
     821             :         // Grow polymorphic feedback array.
     822             :         Handle<WeakFixedArray> new_array = EnsureArrayOfSize(
     823          54 :             array->length() + kCloneObjectPolymorphicEntrySize);
     824         648 :         for (int j = 0; j < array->length(); ++j) {
     825         540 :           new_array->Set(j, array->Get(j));
     826             :         }
     827          54 :         array = new_array;
     828             :       }
     829             : 
     830         126 :       array->Set(i, HeapObjectReference::Weak(*source_map));
     831         126 :       array->Set(i + 1, MaybeObject::FromObject(*result_map));
     832          63 :       break;
     833             :     }
     834             : 
     835             :     default:
     836           0 :       UNREACHABLE();
     837             :   }
     838         432 : }
     839             : 
     840      502175 : int FeedbackNexus::GetCallCount() {
     841             :   DCHECK(IsCallICKind(kind()));
     842             : 
     843     1004350 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     844      502175 :   CHECK(call_count->IsSmi());
     845      502175 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     846      502175 :   return CallCountField::decode(value);
     847             : }
     848             : 
     849        1891 : void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) {
     850             :   DCHECK(IsCallICKind(kind()));
     851             : 
     852        3782 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     853        1891 :   CHECK(call_count->IsSmi());
     854        1891 :   uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count));
     855             :   uint32_t value = CallCountField::encode(CallCountField::decode(count));
     856        1891 :   int result = static_cast<int>(value | SpeculationModeField::encode(mode));
     857        1891 :   SetFeedbackExtra(Smi::FromInt(result), SKIP_WRITE_BARRIER);
     858        1891 : }
     859             : 
     860      462069 : SpeculationMode FeedbackNexus::GetSpeculationMode() {
     861             :   DCHECK(IsCallICKind(kind()));
     862             : 
     863      924138 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     864      462069 :   CHECK(call_count->IsSmi());
     865      462069 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     866      462069 :   return SpeculationModeField::decode(value);
     867             : }
     868             : 
     869      502147 : float FeedbackNexus::ComputeCallFrequency() {
     870             :   DCHECK(IsCallICKind(kind()));
     871             : 
     872     1004294 :   double const invocation_count = vector()->invocation_count();
     873      502147 :   double const call_count = GetCallCount();
     874      502147 :   if (invocation_count == 0) {
     875             :     // Prevent division by 0.
     876             :     return 0.0f;
     877             :   }
     878      191433 :   return static_cast<float>(call_count / invocation_count);
     879             : }
     880             : 
     881     1805926 : void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
     882             :                                          Handle<Map> receiver_map,
     883     1805926 :                                          const MaybeObjectHandle& handler) {
     884             :   DCHECK(handler.is_null() || IC::IsHandler(*handler));
     885     1805926 :   if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) {
     886        3257 :     SetFeedback(HeapObjectReference::Weak(*receiver_map));
     887        3257 :     SetFeedbackExtra(*name);
     888             :   } else {
     889     1802669 :     if (name.is_null()) {
     890     1789679 :       SetFeedback(HeapObjectReference::Weak(*receiver_map));
     891     1789678 :       SetFeedbackExtra(*handler);
     892             :     } else {
     893       12996 :       Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2);
     894             :       SetFeedback(*name);
     895       25992 :       array->Set(0, HeapObjectReference::Weak(*receiver_map));
     896       25992 :       array->Set(1, *handler);
     897             :     }
     898             :   }
     899     1805944 : }
     900             : 
     901      228177 : void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
     902      802648 :                                          MapHandles const& maps,
     903             :                                          MaybeObjectHandles* handlers) {
     904             :   DCHECK_EQ(handlers->size(), maps.size());
     905      228177 :   int receiver_count = static_cast<int>(maps.size());
     906             :   DCHECK_GT(receiver_count, 1);
     907             :   Handle<WeakFixedArray> array;
     908      228177 :   if (name.is_null()) {
     909      224614 :     array = EnsureArrayOfSize(receiver_count * 2);
     910      224617 :     SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(GetIsolate()),
     911      224617 :                      SKIP_WRITE_BARRIER);
     912             :   } else {
     913        3563 :     array = EnsureExtraArrayOfSize(receiver_count * 2);
     914             :     SetFeedback(*name);
     915             :   }
     916             : 
     917      802652 :   for (int current = 0; current < receiver_count; ++current) {
     918     1148942 :     Handle<Map> map = maps[current];
     919     1148944 :     array->Set(current * 2, HeapObjectReference::Weak(*map));
     920             :     DCHECK(IC::IsHandler(*handlers->at(current)));
     921     1148946 :     array->Set(current * 2 + 1, *handlers->at(current));
     922             :   }
     923      228181 : }
     924             : 
     925     1002031 : int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
     926             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     927             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     928             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
     929             :          IsStoreInArrayLiteralICKind(kind()));
     930             : 
     931     1002031 :   Isolate* isolate = GetIsolate();
     932     1002034 :   MaybeObject feedback = GetFeedback();
     933     1002035 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
     934     1002036 :   HeapObject heap_object;
     935     2566987 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
     936     1849757 :        heap_object->IsWeakFixedArray()) ||
     937             :       is_named_feedback) {
     938             :     int found = 0;
     939      159540 :     WeakFixedArray array;
     940      159540 :     if (is_named_feedback) {
     941             :       array =
     942       10454 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
     943             :     } else {
     944      154313 :       array = WeakFixedArray::cast(heap_object);
     945             :     }
     946             :     const int increment = 2;
     947      159540 :     HeapObject heap_object;
     948     1104616 :     for (int i = 0; i < array->length(); i += increment) {
     949             :       DCHECK(array->Get(i)->IsWeakOrCleared());
     950      392768 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
     951             :         Map map = Map::cast(heap_object);
     952      646524 :         maps->push_back(handle(map, isolate));
     953      323262 :         found++;
     954             :       }
     955             :     }
     956             :     return found;
     957      842495 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
     958             :     Map map = Map::cast(heap_object);
     959      741582 :     maps->push_back(handle(map, isolate));
     960             :     return 1;
     961     1415111 :   } else if (feedback->GetHeapObjectIfStrong(&heap_object) &&
     962             :              heap_object ==
     963     1278457 :                  heap_object->GetReadOnlyRoots().premonomorphic_symbol()) {
     964        8204 :     if (GetFeedbackExtra()->GetHeapObjectIfWeak(&heap_object)) {
     965             :       Map map = Map::cast(heap_object);
     966       15056 :       maps->push_back(handle(map, isolate));
     967             :       return 1;
     968             :     }
     969             :   }
     970             : 
     971             :   return 0;
     972             : }
     973             : 
     974      342425 : MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
     975             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     976             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     977             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()));
     978             : 
     979      342425 :   MaybeObject feedback = GetFeedback();
     980      342426 :   Isolate* isolate = GetIsolate();
     981      342427 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
     982      342425 :   HeapObject heap_object;
     983      808969 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
     984      562404 :        heap_object->IsWeakFixedArray()) ||
     985             :       is_named_feedback) {
     986      124119 :     WeakFixedArray array;
     987      124119 :     if (is_named_feedback) {
     988             :       array =
     989        3346 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
     990             :     } else {
     991      122446 :       array = WeakFixedArray::cast(heap_object);
     992             :     }
     993             :     const int increment = 2;
     994      124119 :     HeapObject heap_object;
     995      864022 :     for (int i = 0; i < array->length(); i += increment) {
     996             :       DCHECK(array->Get(i)->IsWeakOrCleared());
     997      308406 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
     998             :         Map array_map = Map::cast(heap_object);
     999      239762 :         if (array_map == *map && !array->Get(i + increment - 1)->IsCleared()) {
    1000         514 :           MaybeObject handler = array->Get(i + increment - 1);
    1001             :           DCHECK(IC::IsHandler(handler));
    1002             :           return handle(handler, isolate);
    1003             :         }
    1004             :       }
    1005             :     }
    1006      218306 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1007             :     Map cell_map = Map::cast(heap_object);
    1008      163350 :     if (cell_map == *map && !GetFeedbackExtra()->IsCleared()) {
    1009       12521 :       MaybeObject handler = GetFeedbackExtra();
    1010             :       DCHECK(IC::IsHandler(handler));
    1011             :       return handle(handler, isolate);
    1012             :     }
    1013             :   }
    1014             : 
    1015      329391 :   return MaybeObjectHandle();
    1016             : }
    1017             : 
    1018      467175 : bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
    1019             :                                  int length) const {
    1020             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
    1021             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
    1022             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
    1023             :          IsStoreInArrayLiteralICKind(kind()));
    1024             : 
    1025      467175 :   MaybeObject feedback = GetFeedback();
    1026      467176 :   Isolate* isolate = GetIsolate();
    1027             :   int count = 0;
    1028      467176 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
    1029      467176 :   HeapObject heap_object;
    1030     1152891 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
    1031      793343 :        heap_object->IsWeakFixedArray()) ||
    1032             :       is_named_feedback) {
    1033      145539 :     WeakFixedArray array;
    1034      145539 :     if (is_named_feedback) {
    1035             :       array =
    1036        9064 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
    1037             :     } else {
    1038      141006 :       array = WeakFixedArray::cast(heap_object);
    1039             :     }
    1040             :     const int increment = 2;
    1041      145538 :     HeapObject heap_object;
    1042     1051490 :     for (int i = 0; i < array->length(); i += increment) {
    1043             :       // Be sure to skip handlers whose maps have been cleared.
    1044             :       DCHECK(array->Get(i)->IsWeakOrCleared());
    1045     1071344 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
    1046      691138 :           !array->Get(i + increment - 1)->IsCleared()) {
    1047      310923 :         MaybeObject handler = array->Get(i + increment - 1);
    1048             :         DCHECK(IC::IsHandler(handler));
    1049      621846 :         code_list->push_back(handle(handler, isolate));
    1050      310923 :         count++;
    1051             :       }
    1052             :     }
    1053      321636 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1054      180914 :     MaybeObject extra = GetFeedbackExtra();
    1055      180916 :     if (!extra->IsCleared()) {
    1056             :       DCHECK(IC::IsHandler(extra));
    1057      360712 :       code_list->push_back(handle(extra, isolate));
    1058             :       count++;
    1059             :     }
    1060             :   }
    1061      467176 :   return count == length;
    1062             : }
    1063             : 
    1064       46788 : Name FeedbackNexus::GetName() const {
    1065       46788 :   if (IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind())) {
    1066       46788 :     MaybeObject feedback = GetFeedback();
    1067       46788 :     if (IsPropertyNameFeedback(feedback)) {
    1068       51670 :       return Name::cast(feedback->GetHeapObjectAssumeStrong());
    1069             :     }
    1070             :   }
    1071       20953 :   return Name();
    1072             : }
    1073             : 
    1074       43845 : KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
    1075             :   DCHECK(IsKeyedLoadICKind(kind()));
    1076             :   MapHandles maps;
    1077             :   MaybeObjectHandles handlers;
    1078             : 
    1079       43845 :   if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
    1080             : 
    1081       42061 :   ExtractMaps(&maps);
    1082       84122 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1083      101626 :   for (MaybeObjectHandle const& handler : handlers) {
    1084       18324 :     KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
    1085       18324 :     if (mode != STANDARD_LOAD) return mode;
    1086             :   }
    1087             : 
    1088             :   return STANDARD_LOAD;
    1089             : }
    1090             : 
    1091             : namespace {
    1092             : 
    1093             : bool BuiltinHasKeyedAccessStoreMode(int builtin_index) {
    1094             :   DCHECK(Builtins::IsBuiltinId(builtin_index));
    1095       19770 :   switch (builtin_index) {
    1096             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1097             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1098             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1099             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1100             :     case Builtins::kStoreFastElementIC_Standard:
    1101             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1102             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1103             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1104             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1105             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1106             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1107             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1108             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1109             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1110             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1111             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1112             :     case Builtins::kElementsTransitionAndStore_Standard:
    1113             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1114             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1115             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1116             :       return true;
    1117             :     default:
    1118             :       return false;
    1119             :   }
    1120             :   UNREACHABLE();
    1121             : }
    1122             : 
    1123       19761 : KeyedAccessStoreMode KeyedAccessStoreModeForBuiltin(int builtin_index) {
    1124             :   DCHECK(BuiltinHasKeyedAccessStoreMode(builtin_index));
    1125       19761 :   switch (builtin_index) {
    1126             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1127             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1128             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1129             :     case Builtins::kStoreFastElementIC_Standard:
    1130             :     case Builtins::kElementsTransitionAndStore_Standard:
    1131             :       return STANDARD_STORE;
    1132             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1133             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1134             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1135             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1136             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1137        4634 :       return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1138             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1139             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1140             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1141             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1142             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1143         296 :       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
    1144             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1145             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1146             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1147             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1148             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1149         682 :       return STORE_NO_TRANSITION_HANDLE_COW;
    1150             :     default:
    1151           0 :       UNREACHABLE();
    1152             :   }
    1153             : }
    1154             : 
    1155             : }  // namespace
    1156             : 
    1157       66981 : KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
    1158             :   DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
    1159             :   KeyedAccessStoreMode mode = STANDARD_STORE;
    1160             :   MapHandles maps;
    1161             :   MaybeObjectHandles handlers;
    1162             : 
    1163       66981 :   if (GetKeyType() == PROPERTY) return mode;
    1164             : 
    1165       66173 :   ExtractMaps(&maps);
    1166      132346 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1167      132373 :   for (const MaybeObjectHandle& maybe_code_handler : handlers) {
    1168             :     // The first handler that isn't the slow handler will have the bits we need.
    1169             :     Handle<Code> handler;
    1170       59364 :     if (maybe_code_handler.object()->IsStoreHandler()) {
    1171             :       Handle<StoreHandler> data_handler =
    1172        8409 :           Handle<StoreHandler>::cast(maybe_code_handler.object());
    1173             :       handler = handle(Code::cast(data_handler->smi_handler()),
    1174       16818 :                        vector()->GetIsolate());
    1175       34137 :     } else if (maybe_code_handler.object()->IsSmi()) {
    1176             :       // Skip proxy handlers.
    1177             :       DCHECK_EQ(*(maybe_code_handler.object()),
    1178             :                 *StoreHandler::StoreProxy(GetIsolate()));
    1179             :       continue;
    1180             :     } else {
    1181             :       // Element store without prototype chain check.
    1182       11361 :       handler = Handle<Code>::cast(maybe_code_handler.object());
    1183             :     }
    1184             : 
    1185       19770 :     if (handler->is_builtin()) {
    1186             :       const int builtin_index = handler->builtin_index();
    1187       19770 :       if (!BuiltinHasKeyedAccessStoreMode(builtin_index)) continue;
    1188             : 
    1189       19761 :       mode = KeyedAccessStoreModeForBuiltin(builtin_index);
    1190             :       break;
    1191             :     }
    1192             :   }
    1193             : 
    1194       66173 :   return mode;
    1195             : }
    1196             : 
    1197      131791 : IcCheckType FeedbackNexus::GetKeyType() const {
    1198             :   DCHECK(IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
    1199             :          IsStoreInArrayLiteralICKind(kind()));
    1200      131791 :   MaybeObject feedback = GetFeedback();
    1201      131791 :   if (feedback == MaybeObject::FromObject(
    1202      131791 :                       *FeedbackVector::MegamorphicSentinel(GetIsolate()))) {
    1203             :     return static_cast<IcCheckType>(
    1204       10602 :         Smi::ToInt(GetFeedbackExtra()->cast<Object>()));
    1205             :   }
    1206      126490 :   return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
    1207             : }
    1208             : 
    1209      958179 : BinaryOperationHint FeedbackNexus::GetBinaryOperationFeedback() const {
    1210             :   DCHECK_EQ(kind(), FeedbackSlotKind::kBinaryOp);
    1211     1916358 :   int feedback = GetFeedback().ToSmi().value();
    1212      958179 :   return BinaryOperationHintFromFeedback(feedback);
    1213             : }
    1214             : 
    1215      526883 : CompareOperationHint FeedbackNexus::GetCompareOperationFeedback() const {
    1216             :   DCHECK_EQ(kind(), FeedbackSlotKind::kCompareOp);
    1217     1053766 :   int feedback = GetFeedback().ToSmi().value();
    1218      526883 :   return CompareOperationHintFromFeedback(feedback);
    1219             : }
    1220             : 
    1221        4328 : ForInHint FeedbackNexus::GetForInFeedback() const {
    1222             :   DCHECK_EQ(kind(), FeedbackSlotKind::kForIn);
    1223        8656 :   int feedback = GetFeedback().ToSmi().value();
    1224        4328 :   return ForInHintFromFeedback(feedback);
    1225             : }
    1226             : 
    1227      436954 : Handle<FeedbackCell> FeedbackNexus::GetFeedbackCell() const {
    1228             :   DCHECK_EQ(FeedbackSlotKind::kCreateClosure, kind());
    1229             :   return handle(FeedbackCell::cast(GetFeedback()->cast<Object>()),
    1230     1310863 :                 vector()->GetIsolate());
    1231             : }
    1232             : 
    1233        2748 : MaybeHandle<JSObject> FeedbackNexus::GetConstructorFeedback() const {
    1234             :   DCHECK_EQ(kind(), FeedbackSlotKind::kInstanceOf);
    1235        2748 :   Isolate* isolate = GetIsolate();
    1236        2748 :   MaybeObject feedback = GetFeedback();
    1237        2748 :   HeapObject heap_object;
    1238        2748 :   if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1239          33 :     return handle(JSObject::cast(heap_object), isolate);
    1240             :   }
    1241        2715 :   return MaybeHandle<JSObject>();
    1242             : }
    1243             : 
    1244             : namespace {
    1245             : 
    1246          64 : bool InList(Handle<ArrayList> types, Handle<String> type) {
    1247         248 :   for (int i = 0; i < types->Length(); i++) {
    1248          76 :     Object obj = types->Get(i);
    1249          76 :     if (String::cast(obj)->Equals(*type)) {
    1250          16 :       return true;
    1251             :     }
    1252             :   }
    1253             :   return false;
    1254             : }
    1255             : }  // anonymous namespace
    1256             : 
    1257         228 : void FeedbackNexus::Collect(Handle<String> type, int position) {
    1258             :   DCHECK(IsTypeProfileKind(kind()));
    1259             :   DCHECK_GE(position, 0);
    1260         228 :   Isolate* isolate = GetIsolate();
    1261             : 
    1262         228 :   MaybeObject const feedback = GetFeedback();
    1263             : 
    1264             :   // Map source position to collection of types
    1265             :   Handle<SimpleNumberDictionary> types;
    1266             : 
    1267         228 :   if (feedback == MaybeObject::FromObject(
    1268             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1269          68 :     types = SimpleNumberDictionary::New(isolate, 1);
    1270             :   } else {
    1271             :     types = handle(
    1272             :         SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1273         320 :         isolate);
    1274             :   }
    1275             : 
    1276             :   Handle<ArrayList> position_specific_types;
    1277             : 
    1278         456 :   int entry = types->FindEntry(isolate, position);
    1279         228 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1280         164 :     position_specific_types = ArrayList::New(isolate, 1);
    1281             :     types = SimpleNumberDictionary::Set(
    1282             :         isolate, types, position,
    1283         328 :         ArrayList::Add(isolate, position_specific_types, type));
    1284             :   } else {
    1285             :     DCHECK(types->ValueAt(entry)->IsArrayList());
    1286             :     position_specific_types =
    1287         128 :         handle(ArrayList::cast(types->ValueAt(entry)), isolate);
    1288          64 :     if (!InList(position_specific_types, type)) {  // Add type
    1289             :       types = SimpleNumberDictionary::Set(
    1290             :           isolate, types, position,
    1291          96 :           ArrayList::Add(isolate, position_specific_types, type));
    1292             :     }
    1293             :   }
    1294             :   SetFeedback(*types);
    1295         228 : }
    1296             : 
    1297         108 : std::vector<int> FeedbackNexus::GetSourcePositions() const {
    1298             :   DCHECK(IsTypeProfileKind(kind()));
    1299             :   std::vector<int> source_positions;
    1300         108 :   Isolate* isolate = GetIsolate();
    1301             : 
    1302         108 :   MaybeObject const feedback = GetFeedback();
    1303             : 
    1304         108 :   if (feedback == MaybeObject::FromObject(
    1305             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1306             :     return source_positions;
    1307             :   }
    1308             : 
    1309             :   Handle<SimpleNumberDictionary> types(
    1310             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1311         128 :       isolate);
    1312             : 
    1313         832 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1314             :        index < types->length(); index += SimpleNumberDictionary::kEntrySize) {
    1315             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1316         352 :     Object key = types->get(key_index);
    1317         352 :     if (key->IsSmi()) {
    1318         148 :       int position = Smi::cast(key)->value();
    1319         148 :       source_positions.push_back(position);
    1320             :     }
    1321             :   }
    1322             :   return source_positions;
    1323             : }
    1324             : 
    1325         148 : std::vector<Handle<String>> FeedbackNexus::GetTypesForSourcePositions(
    1326             :     uint32_t position) const {
    1327             :   DCHECK(IsTypeProfileKind(kind()));
    1328         148 :   Isolate* isolate = GetIsolate();
    1329             : 
    1330         148 :   MaybeObject const feedback = GetFeedback();
    1331             :   std::vector<Handle<String>> types_for_position;
    1332         148 :   if (feedback == MaybeObject::FromObject(
    1333             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1334             :     return types_for_position;
    1335             :   }
    1336             : 
    1337             :   Handle<SimpleNumberDictionary> types(
    1338             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1339         296 :       isolate);
    1340             : 
    1341         148 :   int entry = types->FindEntry(isolate, position);
    1342         148 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1343             :     return types_for_position;
    1344             :   }
    1345             :   DCHECK(types->ValueAt(entry)->IsArrayList());
    1346             :   Handle<ArrayList> position_specific_types =
    1347         296 :       Handle<ArrayList>(ArrayList::cast(types->ValueAt(entry)), isolate);
    1348         688 :   for (int i = 0; i < position_specific_types->Length(); i++) {
    1349         196 :     Object t = position_specific_types->Get(i);
    1350         196 :     types_for_position.push_back(Handle<String>(String::cast(t), isolate));
    1351             :   }
    1352             : 
    1353             :   return types_for_position;
    1354             : }
    1355             : 
    1356             : namespace {
    1357             : 
    1358           0 : Handle<JSObject> ConvertToJSObject(Isolate* isolate,
    1359             :                                    Handle<SimpleNumberDictionary> feedback) {
    1360             :   Handle<JSObject> type_profile =
    1361           0 :       isolate->factory()->NewJSObject(isolate->object_function());
    1362             : 
    1363           0 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1364             :        index < feedback->length();
    1365             :        index += SimpleNumberDictionary::kEntrySize) {
    1366             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1367           0 :     Object key = feedback->get(key_index);
    1368           0 :     if (key->IsSmi()) {
    1369           0 :       int value_index = index + SimpleNumberDictionary::kEntryValueIndex;
    1370             : 
    1371             :       Handle<ArrayList> position_specific_types(
    1372             :           ArrayList::cast(feedback->get(value_index)), isolate);
    1373             : 
    1374           0 :       int position = Smi::ToInt(key);
    1375             :       JSObject::AddDataElement(
    1376             :           type_profile, position,
    1377             :           isolate->factory()->NewJSArrayWithElements(
    1378             :               ArrayList::Elements(isolate, position_specific_types)),
    1379           0 :           PropertyAttributes::NONE);
    1380             :     }
    1381             :   }
    1382           0 :   return type_profile;
    1383             : }
    1384             : }  // namespace
    1385             : 
    1386           0 : JSObject FeedbackNexus::GetTypeProfile() const {
    1387             :   DCHECK(IsTypeProfileKind(kind()));
    1388           0 :   Isolate* isolate = GetIsolate();
    1389             : 
    1390           0 :   MaybeObject const feedback = GetFeedback();
    1391             : 
    1392           0 :   if (feedback == MaybeObject::FromObject(
    1393             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1394           0 :     return *isolate->factory()->NewJSObject(isolate->object_function());
    1395             :   }
    1396             : 
    1397             :   return *ConvertToJSObject(isolate,
    1398             :                             handle(SimpleNumberDictionary::cast(
    1399             :                                        feedback->GetHeapObjectAssumeStrong()),
    1400           0 :                                    isolate));
    1401             : }
    1402             : 
    1403         212 : void FeedbackNexus::ResetTypeProfile() {
    1404             :   DCHECK(IsTypeProfileKind(kind()));
    1405         212 :   SetFeedback(*FeedbackVector::UninitializedSentinel(GetIsolate()));
    1406         212 : }
    1407             : 
    1408             : }  // namespace internal
    1409      178779 : }  // namespace v8

Generated by: LCOV version 1.10