LCOV - code coverage report
Current view: top level - src - feedback-vector.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 400 468 85.5 %
Date: 2019-04-19 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    14649110 : FeedbackSlot FeedbackVectorSpec::AddSlot(FeedbackSlotKind kind) {
      19             :   int slot = slots();
      20    14649110 :   int entries_per_slot = FeedbackMetadata::GetSlotSize(kind);
      21             :   append(kind);
      22    39575090 :   for (int i = 1; i < entries_per_slot; i++) {
      23             :     append(FeedbackSlotKind::kInvalid);
      24             :   }
      25    14648978 :   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     2152194 : static bool IsPropertyNameFeedback(MaybeObject feedback) {
      45     2152194 :   HeapObject heap_object;
      46     2152194 :   if (!feedback->GetHeapObjectIfStrong(&heap_object)) return false;
      47     1082159 :   if (heap_object->IsString()) {
      48             :     DCHECK(heap_object->IsInternalizedString());
      49             :     return true;
      50             :   }
      51     1051422 :   if (!heap_object->IsSymbol()) return false;
      52             :   Symbol symbol = Symbol::cast(heap_object);
      53             :   ReadOnlyRoots roots = symbol->GetReadOnlyRoots();
      54       37645 :   return symbol != roots.uninitialized_symbol() &&
      55      649870 :          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    43978147 :   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    51964370 :   int new_data = VectorICComputer::encode(data, slot.ToInt(), kind);
      73             :   set(index, new_data);
      74           0 : }
      75             : 
      76             : // static
      77     2111028 : Handle<FeedbackMetadata> FeedbackMetadata::New(Isolate* isolate,
      78             :                                                const FeedbackVectorSpec* spec) {
      79             :   Factory* factory = isolate->factory();
      80             : 
      81     2111028 :   const int slot_count = spec == nullptr ? 0 : spec->slots();
      82             :   const int closure_feedback_cell_count =
      83     2111028 :       spec == nullptr ? 0 : spec->closure_feedback_cells();
      84     2111028 :   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     1613500 :       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    53577876 :   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     1613506 :   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    22859226 : FeedbackSlotKind FeedbackVector::GetKind(FeedbackSlot slot) const {
     197             :   DCHECK(!is_empty());
     198    22859226 :   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     3102041 : Handle<ClosureFeedbackCellArray> ClosureFeedbackCellArray::New(
     211             :     Isolate* isolate, Handle<SharedFunctionInfo> shared) {
     212             :   Factory* factory = isolate->factory();
     213             : 
     214             :   int num_feedback_cells =
     215             :       shared->feedback_metadata()->closure_feedback_cell_count();
     216             : 
     217             :   Handle<ClosureFeedbackCellArray> feedback_cell_array =
     218     3102041 :       factory->NewClosureFeedbackCellArray(num_feedback_cells);
     219             : 
     220    11352711 :   for (int i = 0; i < num_feedback_cells; i++) {
     221             :     Handle<FeedbackCell> cell =
     222     4125333 :         factory->NewNoClosuresCell(factory->undefined_value());
     223     8250666 :     feedback_cell_array->set(i, *cell);
     224             :   }
     225     3102045 :   return feedback_cell_array;
     226             : }
     227             : 
     228             : // static
     229     3101996 : Handle<FeedbackVector> FeedbackVector::New(
     230             :     Isolate* isolate, Handle<SharedFunctionInfo> shared,
     231             :     Handle<ClosureFeedbackCellArray> closure_feedback_cell_array) {
     232             :   Factory* factory = isolate->factory();
     233             : 
     234             :   const int slot_count = shared->feedback_metadata()->slot_count();
     235             : 
     236             :   Handle<FeedbackVector> vector = factory->NewFeedbackVector(
     237     3101996 :       shared, closure_feedback_cell_array, AllocationType::kOld);
     238             : 
     239             :   DCHECK_EQ(vector->length(), slot_count);
     240             : 
     241             :   DCHECK_EQ(vector->shared_function_info(), *shared);
     242             :   DCHECK_EQ(
     243             :       vector->optimized_code_weak_or_smi(),
     244             :       MaybeObject::FromSmi(Smi::FromEnum(
     245             :           FLAG_log_function_events ? OptimizationMarker::kLogFirstExecution
     246             :                                    : OptimizationMarker::kNone)));
     247             :   DCHECK_EQ(vector->invocation_count(), 0);
     248             :   DCHECK_EQ(vector->profiler_ticks(), 0);
     249             :   DCHECK_EQ(vector->deopt_count(), 0);
     250             : 
     251             :   // Ensure we can skip the write barrier
     252             :   Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
     253             :   DCHECK_EQ(ReadOnlyRoots(isolate).uninitialized_symbol(),
     254             :             *uninitialized_sentinel);
     255    45063877 :   for (int i = 0; i < slot_count;) {
     256             :     FeedbackSlot slot(i);
     257             :     FeedbackSlotKind kind = shared->feedback_metadata()->GetKind(slot);
     258             :     int index = FeedbackVector::GetIndex(slot);
     259    20980929 :     int entry_size = FeedbackMetadata::GetSlotSize(kind);
     260             : 
     261             :     Object extra_value = *uninitialized_sentinel;
     262    20980917 :     switch (kind) {
     263             :       case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     264             :       case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     265             :       case FeedbackSlotKind::kStoreGlobalSloppy:
     266             :       case FeedbackSlotKind::kStoreGlobalStrict:
     267    18957919 :         vector->set(index, HeapObjectReference::ClearedValue(isolate),
     268     6319306 :                     SKIP_WRITE_BARRIER);
     269     6319307 :         break;
     270             :       case FeedbackSlotKind::kForIn:
     271             :       case FeedbackSlotKind::kCompareOp:
     272             :       case FeedbackSlotKind::kBinaryOp:
     273     5554134 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     274     2777068 :         break;
     275             :       case FeedbackSlotKind::kLiteral:
     276      800511 :         vector->set(index, Smi::kZero, SKIP_WRITE_BARRIER);
     277      400258 :         break;
     278             :       case FeedbackSlotKind::kCall:
     279    11696728 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     280             :         extra_value = Smi::kZero;
     281     5848362 :         break;
     282             :       case FeedbackSlotKind::kCloneObject:
     283             :       case FeedbackSlotKind::kLoadProperty:
     284             :       case FeedbackSlotKind::kLoadKeyed:
     285             :       case FeedbackSlotKind::kHasKeyed:
     286             :       case FeedbackSlotKind::kStoreNamedSloppy:
     287             :       case FeedbackSlotKind::kStoreNamedStrict:
     288             :       case FeedbackSlotKind::kStoreOwnNamed:
     289             :       case FeedbackSlotKind::kStoreKeyedSloppy:
     290             :       case FeedbackSlotKind::kStoreKeyedStrict:
     291             :       case FeedbackSlotKind::kStoreInArrayLiteral:
     292             :       case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     293             :       case FeedbackSlotKind::kTypeProfile:
     294             :       case FeedbackSlotKind::kInstanceOf:
     295    11271943 :         vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
     296     5635965 :         break;
     297             : 
     298             :       case FeedbackSlotKind::kInvalid:
     299             :       case FeedbackSlotKind::kKindsNumber:
     300           0 :         UNREACHABLE();
     301             :         break;
     302             :     }
     303    56537562 :     for (int j = 1; j < entry_size; j++) {
     304    53334909 :       vector->set(index + j, extra_value, SKIP_WRITE_BARRIER);
     305             :     }
     306    20980944 :     i += entry_size;
     307             :   }
     308             : 
     309             :   Handle<FeedbackVector> result = Handle<FeedbackVector>::cast(vector);
     310     3102004 :   if (!isolate->is_best_effort_code_coverage() ||
     311             :       isolate->is_collecting_type_profile()) {
     312        1200 :     AddToVectorsForProfilingTools(isolate, result);
     313             :   }
     314     3102004 :   return result;
     315             : }
     316             : 
     317             : // static
     318        1200 : void FeedbackVector::AddToVectorsForProfilingTools(
     319             :     Isolate* isolate, Handle<FeedbackVector> vector) {
     320             :   DCHECK(!isolate->is_best_effort_code_coverage() ||
     321             :          isolate->is_collecting_type_profile());
     322        1200 :   if (!vector->shared_function_info()->IsSubjectToDebugging()) return;
     323             :   Handle<ArrayList> list = Handle<ArrayList>::cast(
     324             :       isolate->factory()->feedback_vectors_for_profiling_tools());
     325        1200 :   list = ArrayList::Add(isolate, list, vector);
     326        1200 :   isolate->SetFeedbackVectorsForProfilingTools(*list);
     327             : }
     328             : 
     329             : // static
     330       23076 : void FeedbackVector::SetOptimizedCode(Handle<FeedbackVector> vector,
     331             :                                       Handle<Code> code) {
     332             :   DCHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
     333       46152 :   vector->set_optimized_code_weak_or_smi(HeapObjectReference::Weak(*code));
     334       23076 : }
     335             : 
     336           0 : void FeedbackVector::ClearOptimizedCode() {
     337             :   DCHECK(has_optimized_code());
     338             :   SetOptimizationMarker(OptimizationMarker::kNone);
     339           0 : }
     340             : 
     341      769744 : void FeedbackVector::ClearOptimizationMarker() {
     342             :   DCHECK(!has_optimized_code());
     343             :   SetOptimizationMarker(OptimizationMarker::kNone);
     344      769743 : }
     345             : 
     346      499545 : void FeedbackVector::SetOptimizationMarker(OptimizationMarker marker) {
     347     1271550 :   set_optimized_code_weak_or_smi(MaybeObject::FromSmi(Smi::FromEnum(marker)));
     348      499545 : }
     349             : 
     350     4404804 : void FeedbackVector::EvictOptimizedCodeMarkedForDeoptimization(
     351             :     SharedFunctionInfo shared, const char* reason) {
     352             :   MaybeObject slot = optimized_code_weak_or_smi();
     353     4404804 :   if (slot->IsSmi()) {
     354     3957619 :     return;
     355             :   }
     356             : 
     357      447432 :   if (slot->IsCleared()) {
     358             :     ClearOptimizationMarker();
     359             :     return;
     360             :   }
     361             : 
     362      447185 :   Code code = Code::cast(slot->GetHeapObject());
     363      447185 :   if (code->marked_for_deoptimization()) {
     364        2014 :     if (FLAG_trace_deopt) {
     365             :       PrintF("[evicting optimizing code marked for deoptimization (%s) for ",
     366           0 :              reason);
     367           0 :       shared->ShortPrint();
     368           0 :       PrintF("]\n");
     369             :     }
     370        2014 :     if (!code->deopt_already_counted()) {
     371             :       increment_deopt_count();
     372        1217 :       code->set_deopt_already_counted(true);
     373             :     }
     374             :     ClearOptimizedCode();
     375             :   }
     376             : }
     377             : 
     378       52596 : bool FeedbackVector::ClearSlots(Isolate* isolate) {
     379             :   MaybeObject uninitialized_sentinel = MaybeObject::FromObject(
     380             :       FeedbackVector::RawUninitializedSentinel(isolate));
     381             : 
     382             :   bool feedback_updated = false;
     383             :   FeedbackMetadataIterator iter(metadata());
     384      214504 :   while (iter.HasNext()) {
     385       80954 :     FeedbackSlot slot = iter.Next();
     386             : 
     387             :     MaybeObject obj = Get(slot);
     388       80954 :     if (obj != uninitialized_sentinel) {
     389       55810 :       FeedbackNexus nexus(*this, slot);
     390       55810 :       feedback_updated |= nexus.Clear();
     391             :     }
     392             :   }
     393       52596 :   return feedback_updated;
     394             : }
     395             : 
     396      415730 : void FeedbackVector::AssertNoLegacyTypes(MaybeObject object) {
     397             : #ifdef DEBUG
     398             :   HeapObject heap_object;
     399             :   if (object->GetHeapObject(&heap_object)) {
     400             :     // Instead of FixedArray, the Feedback and the Extra should contain
     401             :     // WeakFixedArrays. The only allowed FixedArray subtype is HashTable.
     402             :     DCHECK_IMPLIES(heap_object->IsFixedArray(), heap_object->IsHashTable());
     403             :   }
     404             : #endif
     405      415730 : }
     406             : 
     407      224401 : Handle<WeakFixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
     408             :   Isolate* isolate = GetIsolate();
     409             :   HeapObject heap_object;
     410      535730 :   if (GetFeedback()->GetHeapObjectIfStrong(&heap_object) &&
     411      311132 :       heap_object->IsWeakFixedArray() &&
     412             :       WeakFixedArray::cast(heap_object)->length() == length) {
     413             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     414             :   }
     415      217866 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     416             :   SetFeedback(*array);
     417      217870 :   return array;
     418             : }
     419             : 
     420       17957 : Handle<WeakFixedArray> FeedbackNexus::EnsureExtraArrayOfSize(int length) {
     421             :   Isolate* isolate = GetIsolate();
     422             :   HeapObject heap_object;
     423       40237 :   if (GetFeedbackExtra()->GetHeapObjectIfStrong(&heap_object) &&
     424       22210 :       heap_object->IsWeakFixedArray() &&
     425             :       WeakFixedArray::cast(heap_object)->length() == length) {
     426             :     return handle(WeakFixedArray::cast(heap_object), isolate);
     427             :   }
     428       17758 :   Handle<WeakFixedArray> array = isolate->factory()->NewWeakFixedArray(length);
     429       17758 :   SetFeedbackExtra(*array);
     430       17758 :   return array;
     431             : }
     432             : 
     433       45756 : void FeedbackNexus::ConfigureUninitialized() {
     434             :   Isolate* isolate = GetIsolate();
     435       45756 :   switch (kind()) {
     436             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     437             :     case FeedbackSlotKind::kStoreGlobalStrict:
     438             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     439             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     440       16132 :       SetFeedback(HeapObjectReference::ClearedValue(isolate),
     441        8066 :                   SKIP_WRITE_BARRIER);
     442       16132 :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     443        8066 :                        SKIP_WRITE_BARRIER);
     444        8066 :       break;
     445             :     }
     446             :     case FeedbackSlotKind::kCloneObject:
     447             :     case FeedbackSlotKind::kCall: {
     448             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     449             :                   SKIP_WRITE_BARRIER);
     450        6434 :       SetFeedbackExtra(Smi::kZero, SKIP_WRITE_BARRIER);
     451        6434 :       break;
     452             :     }
     453             :     case FeedbackSlotKind::kInstanceOf: {
     454             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     455             :                   SKIP_WRITE_BARRIER);
     456           0 :       break;
     457             :     }
     458             :     case FeedbackSlotKind::kStoreNamedSloppy:
     459             :     case FeedbackSlotKind::kStoreNamedStrict:
     460             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     461             :     case FeedbackSlotKind::kStoreKeyedStrict:
     462             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     463             :     case FeedbackSlotKind::kStoreOwnNamed:
     464             :     case FeedbackSlotKind::kLoadProperty:
     465             :     case FeedbackSlotKind::kLoadKeyed:
     466             :     case FeedbackSlotKind::kHasKeyed:
     467             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     468             :       SetFeedback(*FeedbackVector::UninitializedSentinel(isolate),
     469             :                   SKIP_WRITE_BARRIER);
     470       62512 :       SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     471       31256 :                        SKIP_WRITE_BARRIER);
     472       31256 :       break;
     473             :     }
     474             :     default:
     475           0 :       UNREACHABLE();
     476             :   }
     477       45756 : }
     478             : 
     479       55810 : bool FeedbackNexus::Clear() {
     480             :   bool feedback_updated = false;
     481             : 
     482             :   switch (kind()) {
     483             :     case FeedbackSlotKind::kTypeProfile:
     484             :       // We don't clear these kinds ever.
     485             :       break;
     486             : 
     487             :     case FeedbackSlotKind::kCompareOp:
     488             :     case FeedbackSlotKind::kForIn:
     489             :     case FeedbackSlotKind::kBinaryOp:
     490             :       // We don't clear these, either.
     491             :       break;
     492             : 
     493             :     case FeedbackSlotKind::kLiteral:
     494             :       SetFeedback(Smi::kZero, SKIP_WRITE_BARRIER);
     495             :       feedback_updated = true;
     496          13 :       break;
     497             : 
     498             :     case FeedbackSlotKind::kStoreNamedSloppy:
     499             :     case FeedbackSlotKind::kStoreNamedStrict:
     500             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     501             :     case FeedbackSlotKind::kStoreKeyedStrict:
     502             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     503             :     case FeedbackSlotKind::kStoreOwnNamed:
     504             :     case FeedbackSlotKind::kLoadProperty:
     505             :     case FeedbackSlotKind::kLoadKeyed:
     506             :     case FeedbackSlotKind::kHasKeyed:
     507             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     508             :     case FeedbackSlotKind::kStoreGlobalStrict:
     509             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     510             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof:
     511             :     case FeedbackSlotKind::kCall:
     512             :     case FeedbackSlotKind::kInstanceOf:
     513             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral:
     514             :     case FeedbackSlotKind::kCloneObject:
     515       47770 :       if (!IsCleared()) {
     516       45756 :         ConfigureUninitialized();
     517             :         feedback_updated = true;
     518             :       }
     519             :       break;
     520             : 
     521             :     case FeedbackSlotKind::kInvalid:
     522             :     case FeedbackSlotKind::kKindsNumber:
     523           0 :       UNREACHABLE();
     524             :       break;
     525             :   }
     526       55810 :   return feedback_updated;
     527             : }
     528             : 
     529      676238 : void FeedbackNexus::ConfigurePremonomorphic(Handle<Map> receiver_map) {
     530             :   SetFeedback(*FeedbackVector::PremonomorphicSentinel(GetIsolate()),
     531             :               SKIP_WRITE_BARRIER);
     532      676241 :   SetFeedbackExtra(HeapObjectReference::Weak(*receiver_map));
     533      676244 : }
     534             : 
     535         126 : bool FeedbackNexus::ConfigureMegamorphic() {
     536             :   DisallowHeapAllocation no_gc;
     537             :   Isolate* isolate = GetIsolate();
     538             :   MaybeObject sentinel =
     539             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     540         252 :   if (GetFeedback() != sentinel) {
     541         126 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     542         126 :     SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     543         126 :     return true;
     544             :   }
     545             : 
     546             :   return false;
     547             : }
     548             : 
     549       47423 : bool FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) {
     550             :   DisallowHeapAllocation no_gc;
     551             :   Isolate* isolate = GetIsolate();
     552             :   bool changed = false;
     553             :   MaybeObject sentinel =
     554             :       MaybeObject::FromObject(*FeedbackVector::MegamorphicSentinel(isolate));
     555       94846 :   if (GetFeedback() != sentinel) {
     556       42994 :     SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     557             :     changed = true;
     558             :   }
     559             : 
     560       47424 :   Smi extra = Smi::FromInt(static_cast<int>(property_type));
     561       51854 :   if (changed || GetFeedbackExtra() != MaybeObject::FromSmi(extra)) {
     562       42994 :     SetFeedbackExtra(extra, SKIP_WRITE_BARRIER);
     563             :     changed = true;
     564             :   }
     565       47424 :   return changed;
     566             : }
     567             : 
     568      103743 : Map FeedbackNexus::GetFirstMap() const {
     569             :   MapHandles maps;
     570      103743 :   ExtractMaps(&maps);
     571      103743 :   if (maps.size() > 0) return *maps.at(0);
     572           4 :   return Map();
     573             : }
     574             : 
     575    12707504 : InlineCacheState FeedbackNexus::ic_state() const {
     576             :   Isolate* isolate = GetIsolate();
     577    12707504 :   MaybeObject feedback = GetFeedback();
     578             : 
     579    12707521 :   switch (kind()) {
     580             :     case FeedbackSlotKind::kLiteral:
     581       53061 :       if (feedback->IsSmi()) return UNINITIALIZED;
     582        7833 :       return MONOMORPHIC;
     583             : 
     584             :     case FeedbackSlotKind::kStoreGlobalSloppy:
     585             :     case FeedbackSlotKind::kStoreGlobalStrict:
     586             :     case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
     587             :     case FeedbackSlotKind::kLoadGlobalInsideTypeof: {
     588     5921224 :       if (feedback->IsSmi()) return MONOMORPHIC;
     589             : 
     590     5921017 :       if (feedback == MaybeObject::FromObject(
     591             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     592             :         DCHECK(kind() == FeedbackSlotKind::kStoreGlobalSloppy ||
     593             :                kind() == FeedbackSlotKind::kStoreGlobalStrict);
     594             :         return PREMONOMORPHIC;
     595             :       }
     596             : 
     597             :       DCHECK(feedback->IsWeakOrCleared());
     598     5920986 :       MaybeObject extra = GetFeedbackExtra();
     599    11421304 :       if (!feedback->IsCleared() ||
     600             :           extra != MaybeObject::FromObject(
     601             :                        *FeedbackVector::UninitializedSentinel(isolate))) {
     602             :         return MONOMORPHIC;
     603             :       }
     604     5495569 :       return UNINITIALIZED;
     605             :     }
     606             : 
     607             :     case FeedbackSlotKind::kStoreNamedSloppy:
     608             :     case FeedbackSlotKind::kStoreNamedStrict:
     609             :     case FeedbackSlotKind::kStoreKeyedSloppy:
     610             :     case FeedbackSlotKind::kStoreKeyedStrict:
     611             :     case FeedbackSlotKind::kStoreInArrayLiteral:
     612             :     case FeedbackSlotKind::kStoreOwnNamed:
     613             :     case FeedbackSlotKind::kLoadProperty:
     614             :     case FeedbackSlotKind::kLoadKeyed:
     615             :     case FeedbackSlotKind::kHasKeyed: {
     616     5035826 :       if (feedback == MaybeObject::FromObject(
     617             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     618             :         return UNINITIALIZED;
     619             :       }
     620     3067476 :       if (feedback == MaybeObject::FromObject(
     621             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     622             :         return MEGAMORPHIC;
     623             :       }
     624     2408251 :       if (feedback == MaybeObject::FromObject(
     625             :                           *FeedbackVector::PremonomorphicSentinel(isolate))) {
     626             :         return PREMONOMORPHIC;
     627             :       }
     628      930309 :       if (feedback->IsWeakOrCleared()) {
     629             :         // Don't check if the map is cleared.
     630             :         return MONOMORPHIC;
     631             :       }
     632             :       HeapObject heap_object;
     633      218727 :       if (feedback->GetHeapObjectIfStrong(&heap_object)) {
     634      218728 :         if (heap_object->IsWeakFixedArray()) {
     635             :           // Determine state purely by our structure, don't check if the maps
     636             :           // are cleared.
     637             :           return POLYMORPHIC;
     638             :         }
     639       16821 :         if (heap_object->IsName()) {
     640             :           DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     641             :                  IsKeyedHasICKind(kind()));
     642       33642 :           Object extra = GetFeedbackExtra()->GetHeapObjectAssumeStrong();
     643             :           WeakFixedArray extra_array = WeakFixedArray::cast(extra);
     644       16821 :           return extra_array->length() > 2 ? POLYMORPHIC : MONOMORPHIC;
     645             :         }
     646             :       }
     647           0 :       UNREACHABLE();
     648             :     }
     649             :     case FeedbackSlotKind::kCall: {
     650             :       HeapObject heap_object;
     651     1039828 :       if (feedback == MaybeObject::FromObject(
     652             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     653             :         return GENERIC;
     654     2718355 :       } else if (feedback->IsWeakOrCleared() ||
     655      679149 :                  (feedback->GetHeapObjectIfStrong(&heap_object) &&
     656             :                   heap_object->IsAllocationSite())) {
     657             :         return MONOMORPHIC;
     658             :       }
     659             : 
     660      677401 :       CHECK_EQ(feedback, MaybeObject::FromObject(
     661             :                              *FeedbackVector::UninitializedSentinel(isolate)));
     662             :       return UNINITIALIZED;
     663             :     }
     664             :     case FeedbackSlotKind::kBinaryOp: {
     665             :       BinaryOperationHint hint = GetBinaryOperationFeedback();
     666      271009 :       if (hint == BinaryOperationHint::kNone) {
     667             :         return UNINITIALIZED;
     668      255833 :       } else if (hint == BinaryOperationHint::kAny) {
     669             :         return GENERIC;
     670             :       }
     671             : 
     672      252575 :       return MONOMORPHIC;
     673             :     }
     674             :     case FeedbackSlotKind::kCompareOp: {
     675      151103 :       CompareOperationHint hint = GetCompareOperationFeedback();
     676      151103 :       if (hint == CompareOperationHint::kNone) {
     677             :         return UNINITIALIZED;
     678      137235 :       } else if (hint == CompareOperationHint::kAny) {
     679             :         return GENERIC;
     680             :       }
     681             : 
     682      101335 :       return MONOMORPHIC;
     683             :     }
     684             :     case FeedbackSlotKind::kForIn: {
     685             :       ForInHint hint = GetForInFeedback();
     686        1378 :       if (hint == ForInHint::kNone) {
     687             :         return UNINITIALIZED;
     688        1333 :       } else if (hint == ForInHint::kAny) {
     689             :         return GENERIC;
     690             :       }
     691         499 :       return MONOMORPHIC;
     692             :     }
     693             :     case FeedbackSlotKind::kInstanceOf: {
     694        4878 :       if (feedback == MaybeObject::FromObject(
     695             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     696             :         return UNINITIALIZED;
     697        1924 :       } else if (feedback ==
     698             :                  MaybeObject::FromObject(
     699             :                      *FeedbackVector::MegamorphicSentinel(isolate))) {
     700             :         return MEGAMORPHIC;
     701             :       }
     702        1700 :       return MONOMORPHIC;
     703             :     }
     704             :     case FeedbackSlotKind::kStoreDataPropertyInLiteral: {
     705      228247 :       if (feedback == MaybeObject::FromObject(
     706             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     707             :         return UNINITIALIZED;
     708      223930 :       } else if (feedback->IsWeakOrCleared()) {
     709             :         // Don't check if the map is cleared.
     710             :         return MONOMORPHIC;
     711             :       }
     712             : 
     713       16341 :       return MEGAMORPHIC;
     714             :     }
     715             :     case FeedbackSlotKind::kTypeProfile: {
     716           0 :       if (feedback == MaybeObject::FromObject(
     717             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     718             :         return UNINITIALIZED;
     719             :       }
     720           0 :       return MONOMORPHIC;
     721             :     }
     722             : 
     723             :     case FeedbackSlotKind::kCloneObject: {
     724         978 :       if (feedback == MaybeObject::FromObject(
     725             :                           *FeedbackVector::UninitializedSentinel(isolate))) {
     726             :         return UNINITIALIZED;
     727             :       }
     728         280 :       if (feedback == MaybeObject::FromObject(
     729             :                           *FeedbackVector::MegamorphicSentinel(isolate))) {
     730             :         return MEGAMORPHIC;
     731             :       }
     732         280 :       if (feedback->IsWeakOrCleared()) {
     733             :         return MONOMORPHIC;
     734             :       }
     735             : 
     736             :       DCHECK(feedback->GetHeapObjectAssumeStrong()->IsWeakFixedArray());
     737         180 :       return POLYMORPHIC;
     738             :     }
     739             : 
     740             :     case FeedbackSlotKind::kInvalid:
     741             :     case FeedbackSlotKind::kKindsNumber:
     742           0 :       UNREACHABLE();
     743             :       break;
     744             :   }
     745             :   return UNINITIALIZED;
     746             : }
     747             : 
     748     5734954 : void FeedbackNexus::ConfigurePropertyCellMode(Handle<PropertyCell> cell) {
     749             :   DCHECK(IsGlobalICKind(kind()));
     750             :   Isolate* isolate = GetIsolate();
     751     5734954 :   SetFeedback(HeapObjectReference::Weak(*cell));
     752    11469914 :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     753     5734957 :                    SKIP_WRITE_BARRIER);
     754     5734957 : }
     755             : 
     756       61358 : bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index,
     757             :                                             int context_slot_index,
     758             :                                             bool immutable) {
     759             :   DCHECK(IsGlobalICKind(kind()));
     760             :   DCHECK_LE(0, script_context_index);
     761             :   DCHECK_LE(0, context_slot_index);
     762      184074 :   if (!ContextIndexBits::is_valid(script_context_index) ||
     763      122717 :       !SlotIndexBits::is_valid(context_slot_index) ||
     764             :       !ImmutabilityBit::is_valid(immutable)) {
     765             :     return false;
     766             :   }
     767       61359 :   int config = ContextIndexBits::encode(script_context_index) |
     768      122718 :                SlotIndexBits::encode(context_slot_index) |
     769       61359 :                ImmutabilityBit::encode(immutable);
     770             : 
     771             :   SetFeedback(Smi::From31BitPattern(config));
     772             :   Isolate* isolate = GetIsolate();
     773      122718 :   SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(isolate),
     774       61359 :                    SKIP_WRITE_BARRIER);
     775       61359 :   return true;
     776             : }
     777             : 
     778       44704 : void FeedbackNexus::ConfigureHandlerMode(const MaybeObjectHandle& handler) {
     779             :   DCHECK(IsGlobalICKind(kind()));
     780             :   DCHECK(IC::IsHandler(*handler));
     781       44704 :   SetFeedback(HeapObjectReference::ClearedValue(GetIsolate()));
     782       44704 :   SetFeedbackExtra(*handler);
     783       44704 : }
     784             : 
     785         450 : void FeedbackNexus::ConfigureCloneObject(Handle<Map> source_map,
     786             :                                          Handle<Map> result_map) {
     787             :   Isolate* isolate = GetIsolate();
     788         450 :   MaybeObject maybe_feedback = GetFeedback();
     789             :   Handle<HeapObject> feedback(maybe_feedback->IsStrongOrWeak()
     790             :                                   ? maybe_feedback->GetHeapObject()
     791             :                                   : HeapObject(),
     792         450 :                               isolate);
     793         450 :   switch (ic_state()) {
     794             :     case UNINITIALIZED:
     795             :       // Cache the first map seen which meets the fast case requirements.
     796         324 :       SetFeedback(HeapObjectReference::Weak(*source_map));
     797         324 :       SetFeedbackExtra(*result_map);
     798         324 :       break;
     799             :     case MONOMORPHIC:
     800         108 :       if (maybe_feedback->IsCleared() || feedback.is_identical_to(source_map) ||
     801             :           Map::cast(*feedback)->is_deprecated()) {
     802             :         // Remain in MONOMORPHIC state if previous feedback has been collected.
     803           0 :         SetFeedback(HeapObjectReference::Weak(*source_map));
     804           0 :         SetFeedbackExtra(*result_map);
     805             :       } else {
     806             :         // Transition to POLYMORPHIC.
     807             :         Handle<WeakFixedArray> array =
     808          36 :             EnsureArrayOfSize(2 * kCloneObjectPolymorphicEntrySize);
     809          36 :         array->Set(0, maybe_feedback);
     810          72 :         array->Set(1, GetFeedbackExtra());
     811          72 :         array->Set(2, HeapObjectReference::Weak(*source_map));
     812          36 :         array->Set(3, MaybeObject::FromObject(*result_map));
     813          36 :         SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     814             :       }
     815             :       break;
     816             :     case POLYMORPHIC: {
     817             :       const int kMaxElements =
     818          90 :           FLAG_max_polymorphic_map_count * kCloneObjectPolymorphicEntrySize;
     819             :       Handle<WeakFixedArray> array = Handle<WeakFixedArray>::cast(feedback);
     820             :       int i = 0;
     821         333 :       for (; i < array->length(); i += kCloneObjectPolymorphicEntrySize) {
     822             :         MaybeObject feedback = array->Get(i);
     823         252 :         if (feedback->IsCleared()) break;
     824             :         Handle<Map> cached_map(Map::cast(feedback->GetHeapObject()), isolate);
     825         486 :         if (cached_map.is_identical_to(source_map) ||
     826             :             cached_map->is_deprecated())
     827             :           break;
     828             :       }
     829             : 
     830          90 :       if (i >= array->length()) {
     831          81 :         if (i == kMaxElements) {
     832             :           // Transition to MEGAMORPHIC.
     833             :           MaybeObject sentinel = MaybeObject::FromObject(
     834          27 :               *FeedbackVector::MegamorphicSentinel(isolate));
     835          27 :           SetFeedback(sentinel, SKIP_WRITE_BARRIER);
     836          27 :           SetFeedbackExtra(HeapObjectReference::ClearedValue(isolate));
     837             :           break;
     838             :         }
     839             : 
     840             :         // Grow polymorphic feedback array.
     841             :         Handle<WeakFixedArray> new_array = EnsureArrayOfSize(
     842          54 :             array->length() + kCloneObjectPolymorphicEntrySize);
     843         594 :         for (int j = 0; j < array->length(); ++j) {
     844         270 :           new_array->Set(j, array->Get(j));
     845             :         }
     846          54 :         array = new_array;
     847             :       }
     848             : 
     849         126 :       array->Set(i, HeapObjectReference::Weak(*source_map));
     850         126 :       array->Set(i + 1, MaybeObject::FromObject(*result_map));
     851          63 :       break;
     852             :     }
     853             : 
     854             :     default:
     855           0 :       UNREACHABLE();
     856             :   }
     857         450 : }
     858             : 
     859      509403 : int FeedbackNexus::GetCallCount() {
     860             :   DCHECK(IsCallICKind(kind()));
     861             : 
     862     1018806 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     863      509403 :   CHECK(call_count->IsSmi());
     864      509403 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     865      509403 :   return CallCountField::decode(value);
     866             : }
     867             : 
     868        1963 : void FeedbackNexus::SetSpeculationMode(SpeculationMode mode) {
     869             :   DCHECK(IsCallICKind(kind()));
     870             : 
     871        3926 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     872        1963 :   CHECK(call_count->IsSmi());
     873        1963 :   uint32_t count = static_cast<uint32_t>(Smi::ToInt(call_count));
     874             :   uint32_t value = CallCountField::encode(CallCountField::decode(count));
     875        1963 :   int result = static_cast<int>(value | SpeculationModeField::encode(mode));
     876        1963 :   SetFeedbackExtra(Smi::FromInt(result), SKIP_WRITE_BARRIER);
     877        1963 : }
     878             : 
     879      466526 : SpeculationMode FeedbackNexus::GetSpeculationMode() {
     880             :   DCHECK(IsCallICKind(kind()));
     881             : 
     882      933052 :   Object call_count = GetFeedbackExtra()->cast<Object>();
     883      466526 :   CHECK(call_count->IsSmi());
     884      466526 :   uint32_t value = static_cast<uint32_t>(Smi::ToInt(call_count));
     885      466526 :   return SpeculationModeField::decode(value);
     886             : }
     887             : 
     888      509375 : float FeedbackNexus::ComputeCallFrequency() {
     889             :   DCHECK(IsCallICKind(kind()));
     890             : 
     891      509375 :   double const invocation_count = vector()->invocation_count();
     892      509375 :   double const call_count = GetCallCount();
     893      509375 :   if (invocation_count == 0) {
     894             :     // Prevent division by 0.
     895             :     return 0.0f;
     896             :   }
     897      191900 :   return static_cast<float>(call_count / invocation_count);
     898             : }
     899             : 
     900     1963094 : void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
     901             :                                          Handle<Map> receiver_map,
     902             :                                          const MaybeObjectHandle& handler) {
     903             :   DCHECK(handler.is_null() || IC::IsHandler(*handler));
     904     1963094 :   if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) {
     905        3352 :     SetFeedback(HeapObjectReference::Weak(*receiver_map));
     906        3352 :     SetFeedbackExtra(*name);
     907             :   } else {
     908     1959742 :     if (name.is_null()) {
     909     1945843 :       SetFeedback(HeapObjectReference::Weak(*receiver_map));
     910     1945869 :       SetFeedbackExtra(*handler);
     911             :     } else {
     912       13899 :       Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2);
     913             :       SetFeedback(*name);
     914       27798 :       array->Set(0, HeapObjectReference::Weak(*receiver_map));
     915       27798 :       array->Set(1, *handler);
     916             :     }
     917             :   }
     918     1963118 : }
     919             : 
     920      228370 : void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
     921             :                                          MapHandles const& maps,
     922             :                                          MaybeObjectHandles* handlers) {
     923             :   DCHECK_EQ(handlers->size(), maps.size());
     924      228370 :   int receiver_count = static_cast<int>(maps.size());
     925             :   DCHECK_GT(receiver_count, 1);
     926             :   Handle<WeakFixedArray> array;
     927      228370 :   if (name.is_null()) {
     928      224312 :     array = EnsureArrayOfSize(receiver_count * 2);
     929      448628 :     SetFeedbackExtra(*FeedbackVector::UninitializedSentinel(GetIsolate()),
     930      224314 :                      SKIP_WRITE_BARRIER);
     931             :   } else {
     932        4058 :     array = EnsureExtraArrayOfSize(receiver_count * 2);
     933             :     SetFeedback(*name);
     934             :   }
     935             : 
     936     1382512 :   for (int current = 0; current < receiver_count; ++current) {
     937     1154140 :     Handle<Map> map = maps[current];
     938     1154140 :     array->Set(current * 2, HeapObjectReference::Weak(*map));
     939             :     DCHECK(IC::IsHandler(*handlers->at(current)));
     940     1154140 :     array->Set(current * 2 + 1, *handlers->at(current));
     941             :   }
     942      228372 : }
     943             : 
     944     1075913 : int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
     945             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     946             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     947             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
     948             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
     949             : 
     950             :   Isolate* isolate = GetIsolate();
     951     1075913 :   MaybeObject feedback = GetFeedback();
     952     1075919 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
     953             :   HeapObject heap_object;
     954     1682683 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
     955     1996814 :        heap_object->IsWeakFixedArray()) ||
     956             :       is_named_feedback) {
     957             :     int found = 0;
     958             :     WeakFixedArray array;
     959      161032 :     if (is_named_feedback) {
     960             :       array =
     961       12032 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
     962             :     } else {
     963             :       array = WeakFixedArray::cast(heap_object);
     964             :     }
     965             :     const int increment = 2;
     966             :     HeapObject heap_object;
     967      557165 :     for (int i = 0; i < array->length(); i += increment) {
     968             :       DCHECK(array->Get(i)->IsWeakOrCleared());
     969      396133 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
     970             :         Map map = Map::cast(heap_object);
     971      654974 :         maps->push_back(handle(map, isolate));
     972      327487 :         found++;
     973             :       }
     974             :     }
     975             :     return found;
     976      914882 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
     977             :     Map map = Map::cast(heap_object);
     978      724509 :     maps->push_back(handle(map, isolate));
     979             :     return 1;
     980      998364 :   } else if (feedback->GetHeapObjectIfStrong(&heap_object) &&
     981             :              heap_object ==
     982             :                  heap_object->GetReadOnlyRoots().premonomorphic_symbol()) {
     983       16298 :     if (GetFeedbackExtra()->GetHeapObjectIfWeak(&heap_object)) {
     984             :       Map map = Map::cast(heap_object);
     985       14880 :       maps->push_back(handle(map, isolate));
     986             :       return 1;
     987             :     }
     988             :   }
     989             : 
     990             :   return 0;
     991             : }
     992             : 
     993      376995 : MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
     994             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
     995             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
     996             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
     997             :          IsKeyedHasICKind(kind()));
     998             : 
     999      376995 :   MaybeObject feedback = GetFeedback();
    1000             :   Isolate* isolate = GetIsolate();
    1001      376998 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
    1002             :   HeapObject heap_object;
    1003      501733 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
    1004      631436 :        heap_object->IsWeakFixedArray()) ||
    1005             :       is_named_feedback) {
    1006             :     WeakFixedArray array;
    1007      124737 :     if (is_named_feedback) {
    1008             :       array =
    1009        4364 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
    1010             :     } else {
    1011             :       array = WeakFixedArray::cast(heap_object);
    1012             :     }
    1013             :     const int increment = 2;
    1014             :     HeapObject heap_object;
    1015      433024 :     for (int i = 0; i < array->length(); i += increment) {
    1016             :       DCHECK(array->Get(i)->IsWeakOrCleared());
    1017      308849 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object)) {
    1018             :         Map array_map = Map::cast(heap_object);
    1019      240841 :         if (array_map == *map && !array->Get(i + increment - 1)->IsCleared()) {
    1020             :           MaybeObject handler = array->Get(i + increment - 1);
    1021             :           DCHECK(IC::IsHandler(handler));
    1022             :           return handle(handler, isolate);
    1023             :         }
    1024             :       }
    1025             :     }
    1026      252258 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1027             :     Map cell_map = Map::cast(heap_object);
    1028      160023 :     if (cell_map == *map && !GetFeedbackExtra()->IsCleared()) {
    1029       13130 :       MaybeObject handler = GetFeedbackExtra();
    1030             :       DCHECK(IC::IsHandler(handler));
    1031             :       return handle(handler, isolate);
    1032             :     }
    1033             :   }
    1034             : 
    1035      363303 :   return MaybeObjectHandle();
    1036             : }
    1037             : 
    1038      511831 : bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
    1039             :                                  int length) const {
    1040             :   DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
    1041             :          IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
    1042             :          IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
    1043             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
    1044             : 
    1045      511831 :   MaybeObject feedback = GetFeedback();
    1046             :   Isolate* isolate = GetIsolate();
    1047             :   int count = 0;
    1048      511831 :   bool is_named_feedback = IsPropertyNameFeedback(feedback);
    1049             :   HeapObject heap_object;
    1050      740993 :   if ((feedback->GetHeapObjectIfStrong(&heap_object) &&
    1051      882510 :        heap_object->IsWeakFixedArray()) ||
    1052             :       is_named_feedback) {
    1053             :     WeakFixedArray array;
    1054      146252 :     if (is_named_feedback) {
    1055             :       array =
    1056       10202 :           WeakFixedArray::cast(GetFeedbackExtra()->GetHeapObjectAssumeStrong());
    1057             :     } else {
    1058             :       array = WeakFixedArray::cast(heap_object);
    1059             :     }
    1060             :     const int increment = 2;
    1061             :     HeapObject heap_object;
    1062      527389 :     for (int i = 0; i < array->length(); i += increment) {
    1063             :       // Be sure to skip handlers whose maps have been cleared.
    1064             :       DCHECK(array->Get(i)->IsWeakOrCleared());
    1065      693675 :       if (array->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
    1066             :           !array->Get(i + increment - 1)->IsCleared()) {
    1067             :         MaybeObject handler = array->Get(i + increment - 1);
    1068             :         DCHECK(IC::IsHandler(handler));
    1069      625053 :         code_list->push_back(handle(handler, isolate));
    1070      312527 :         count++;
    1071             :       }
    1072             :     }
    1073      365579 :   } else if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1074      176838 :     MaybeObject extra = GetFeedbackExtra();
    1075      176839 :     if (!extra->IsCleared()) {
    1076             :       DCHECK(IC::IsHandler(extra));
    1077      351706 :       code_list->push_back(handle(extra, isolate));
    1078             :       count++;
    1079             :     }
    1080             :   }
    1081      511834 :   return count == length;
    1082             : }
    1083             : 
    1084       49909 : Name FeedbackNexus::GetName() const {
    1085       49909 :   if (IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
    1086             :       IsKeyedHasICKind(kind())) {
    1087       49909 :     MaybeObject feedback = GetFeedback();
    1088       49909 :     if (IsPropertyNameFeedback(feedback)) {
    1089             :       return Name::cast(feedback->GetHeapObjectAssumeStrong());
    1090             :     }
    1091             :   }
    1092       21379 :   return Name();
    1093             : }
    1094             : 
    1095       45148 : KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
    1096             :   DCHECK(IsKeyedLoadICKind(kind()) || IsKeyedHasICKind(kind()));
    1097             :   MapHandles maps;
    1098             :   MaybeObjectHandles handlers;
    1099             : 
    1100       45148 :   if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
    1101             : 
    1102       42907 :   ExtractMaps(&maps);
    1103       42907 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1104       60562 :   for (MaybeObjectHandle const& handler : handlers) {
    1105       18525 :     KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
    1106       18525 :     if (mode != STANDARD_LOAD) return mode;
    1107             :   }
    1108             : 
    1109             :   return STANDARD_LOAD;
    1110             : }
    1111             : 
    1112             : namespace {
    1113             : 
    1114             : bool BuiltinHasKeyedAccessStoreMode(int builtin_index) {
    1115             :   DCHECK(Builtins::IsBuiltinId(builtin_index));
    1116       20234 :   switch (builtin_index) {
    1117             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1118             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1119             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1120             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1121             :     case Builtins::kStoreFastElementIC_Standard:
    1122             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1123             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1124             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1125             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1126             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1127             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1128             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1129             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1130             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1131             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1132             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1133             :     case Builtins::kElementsTransitionAndStore_Standard:
    1134             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1135             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1136             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1137             :       return true;
    1138             :     default:
    1139             :       return false;
    1140             :   }
    1141             :   UNREACHABLE();
    1142             : }
    1143             : 
    1144       20197 : KeyedAccessStoreMode KeyedAccessStoreModeForBuiltin(int builtin_index) {
    1145             :   DCHECK(BuiltinHasKeyedAccessStoreMode(builtin_index));
    1146       20197 :   switch (builtin_index) {
    1147             :     case Builtins::kKeyedStoreIC_SloppyArguments_Standard:
    1148             :     case Builtins::kStoreInArrayLiteralIC_Slow_Standard:
    1149             :     case Builtins::kKeyedStoreIC_Slow_Standard:
    1150             :     case Builtins::kStoreFastElementIC_Standard:
    1151             :     case Builtins::kElementsTransitionAndStore_Standard:
    1152             :       return STANDARD_STORE;
    1153             :     case Builtins::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW:
    1154             :     case Builtins::kStoreInArrayLiteralIC_Slow_GrowNoTransitionHandleCOW:
    1155             :     case Builtins::kKeyedStoreIC_Slow_GrowNoTransitionHandleCOW:
    1156             :     case Builtins::kStoreFastElementIC_GrowNoTransitionHandleCOW:
    1157             :     case Builtins::kElementsTransitionAndStore_GrowNoTransitionHandleCOW:
    1158        4667 :       return STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1159             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB:
    1160             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionIgnoreOOB:
    1161             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionIgnoreOOB:
    1162             :     case Builtins::kStoreFastElementIC_NoTransitionIgnoreOOB:
    1163             :     case Builtins::kElementsTransitionAndStore_NoTransitionIgnoreOOB:
    1164         296 :       return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS;
    1165             :     case Builtins::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW:
    1166             :     case Builtins::kStoreInArrayLiteralIC_Slow_NoTransitionHandleCOW:
    1167             :     case Builtins::kKeyedStoreIC_Slow_NoTransitionHandleCOW:
    1168             :     case Builtins::kStoreFastElementIC_NoTransitionHandleCOW:
    1169             :     case Builtins::kElementsTransitionAndStore_NoTransitionHandleCOW:
    1170         741 :       return STORE_NO_TRANSITION_HANDLE_COW;
    1171             :     default:
    1172           0 :       UNREACHABLE();
    1173             :   }
    1174             : }
    1175             : 
    1176             : }  // namespace
    1177             : 
    1178       76603 : KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
    1179             :   DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
    1180             :   KeyedAccessStoreMode mode = STANDARD_STORE;
    1181             :   MapHandles maps;
    1182             :   MaybeObjectHandles handlers;
    1183             : 
    1184       76603 :   if (GetKeyType() == PROPERTY) return mode;
    1185             : 
    1186       75812 :   ExtractMaps(&maps);
    1187       75812 :   FindHandlers(&handlers, static_cast<int>(maps.size()));
    1188       75867 :   for (const MaybeObjectHandle& maybe_code_handler : handlers) {
    1189             :     // The first handler that isn't the slow handler will have the bits we need.
    1190             :     Handle<Code> handler;
    1191       20252 :     if (maybe_code_handler.object()->IsStoreHandler()) {
    1192             :       Handle<StoreHandler> data_handler =
    1193             :           Handle<StoreHandler>::cast(maybe_code_handler.object());
    1194             :       handler = handle(Code::cast(data_handler->smi_handler()),
    1195             :                        vector()->GetIsolate());
    1196       11600 :     } else if (maybe_code_handler.object()->IsSmi()) {
    1197             :       // Skip proxy handlers.
    1198             :       DCHECK_EQ(*(maybe_code_handler.object()),
    1199             :                 *StoreHandler::StoreProxy(GetIsolate()));
    1200             :       continue;
    1201             :     } else {
    1202             :       // Element store without prototype chain check.
    1203             :       handler = Handle<Code>::cast(maybe_code_handler.object());
    1204             :     }
    1205             : 
    1206       20234 :     if (handler->is_builtin()) {
    1207             :       const int builtin_index = handler->builtin_index();
    1208       20234 :       if (!BuiltinHasKeyedAccessStoreMode(builtin_index)) continue;
    1209             : 
    1210       20197 :       mode = KeyedAccessStoreModeForBuiltin(builtin_index);
    1211             :       break;
    1212             :     }
    1213             :   }
    1214             : 
    1215             :   return mode;
    1216             : }
    1217             : 
    1218      143141 : IcCheckType FeedbackNexus::GetKeyType() const {
    1219             :   DCHECK(IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) ||
    1220             :          IsStoreInArrayLiteralICKind(kind()) || IsKeyedHasICKind(kind()));
    1221      143141 :   MaybeObject feedback = GetFeedback();
    1222      143141 :   if (feedback == MaybeObject::FromObject(
    1223             :                       *FeedbackVector::MegamorphicSentinel(GetIsolate()))) {
    1224             :     return static_cast<IcCheckType>(
    1225       11202 :         Smi::ToInt(GetFeedbackExtra()->cast<Object>()));
    1226             :   }
    1227      137540 :   return IsPropertyNameFeedback(feedback) ? PROPERTY : ELEMENT;
    1228             : }
    1229             : 
    1230      676251 : BinaryOperationHint FeedbackNexus::GetBinaryOperationFeedback() const {
    1231             :   DCHECK_EQ(kind(), FeedbackSlotKind::kBinaryOp);
    1232     1894520 :   int feedback = GetFeedback().ToSmi().value();
    1233      676251 :   return BinaryOperationHintFromFeedback(feedback);
    1234             : }
    1235             : 
    1236      527087 : CompareOperationHint FeedbackNexus::GetCompareOperationFeedback() const {
    1237             :   DCHECK_EQ(kind(), FeedbackSlotKind::kCompareOp);
    1238     1054174 :   int feedback = GetFeedback().ToSmi().value();
    1239      527087 :   return CompareOperationHintFromFeedback(feedback);
    1240             : }
    1241             : 
    1242        2930 : ForInHint FeedbackNexus::GetForInFeedback() const {
    1243             :   DCHECK_EQ(kind(), FeedbackSlotKind::kForIn);
    1244        8616 :   int feedback = GetFeedback().ToSmi().value();
    1245        2930 :   return ForInHintFromFeedback(feedback);
    1246             : }
    1247             : 
    1248        2887 : MaybeHandle<JSObject> FeedbackNexus::GetConstructorFeedback() const {
    1249             :   DCHECK_EQ(kind(), FeedbackSlotKind::kInstanceOf);
    1250             :   Isolate* isolate = GetIsolate();
    1251        2887 :   MaybeObject feedback = GetFeedback();
    1252             :   HeapObject heap_object;
    1253        2887 :   if (feedback->GetHeapObjectIfWeak(&heap_object)) {
    1254          36 :     return handle(JSObject::cast(heap_object), isolate);
    1255             :   }
    1256        2851 :   return MaybeHandle<JSObject>();
    1257             : }
    1258             : 
    1259             : namespace {
    1260             : 
    1261          64 : bool InList(Handle<ArrayList> types, Handle<String> type) {
    1262         124 :   for (int i = 0; i < types->Length(); i++) {
    1263             :     Object obj = types->Get(i);
    1264          76 :     if (String::cast(obj)->Equals(*type)) {
    1265             :       return true;
    1266             :     }
    1267             :   }
    1268             :   return false;
    1269             : }
    1270             : }  // anonymous namespace
    1271             : 
    1272         228 : void FeedbackNexus::Collect(Handle<String> type, int position) {
    1273             :   DCHECK(IsTypeProfileKind(kind()));
    1274             :   DCHECK_GE(position, 0);
    1275             :   Isolate* isolate = GetIsolate();
    1276             : 
    1277         228 :   MaybeObject const feedback = GetFeedback();
    1278             : 
    1279             :   // Map source position to collection of types
    1280             :   Handle<SimpleNumberDictionary> types;
    1281             : 
    1282         228 :   if (feedback == MaybeObject::FromObject(
    1283             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1284          68 :     types = SimpleNumberDictionary::New(isolate, 1);
    1285             :   } else {
    1286             :     types = handle(
    1287             :         SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1288             :         isolate);
    1289             :   }
    1290             : 
    1291             :   Handle<ArrayList> position_specific_types;
    1292             : 
    1293         456 :   int entry = types->FindEntry(isolate, position);
    1294         228 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1295         164 :     position_specific_types = ArrayList::New(isolate, 1);
    1296             :     types = SimpleNumberDictionary::Set(
    1297             :         isolate, types, position,
    1298         328 :         ArrayList::Add(isolate, position_specific_types, type));
    1299             :   } else {
    1300             :     DCHECK(types->ValueAt(entry)->IsArrayList());
    1301             :     position_specific_types =
    1302          64 :         handle(ArrayList::cast(types->ValueAt(entry)), isolate);
    1303          64 :     if (!InList(position_specific_types, type)) {  // Add type
    1304             :       types = SimpleNumberDictionary::Set(
    1305             :           isolate, types, position,
    1306          96 :           ArrayList::Add(isolate, position_specific_types, type));
    1307             :     }
    1308             :   }
    1309             :   SetFeedback(*types);
    1310         228 : }
    1311             : 
    1312         108 : std::vector<int> FeedbackNexus::GetSourcePositions() const {
    1313             :   DCHECK(IsTypeProfileKind(kind()));
    1314             :   std::vector<int> source_positions;
    1315             :   Isolate* isolate = GetIsolate();
    1316             : 
    1317         108 :   MaybeObject const feedback = GetFeedback();
    1318             : 
    1319         108 :   if (feedback == MaybeObject::FromObject(
    1320             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1321             :     return source_positions;
    1322             :   }
    1323             : 
    1324             :   Handle<SimpleNumberDictionary> types(
    1325             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1326             :       isolate);
    1327             : 
    1328         768 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1329             :        index < types->length(); index += SimpleNumberDictionary::kEntrySize) {
    1330             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1331             :     Object key = types->get(key_index);
    1332         352 :     if (key->IsSmi()) {
    1333         148 :       int position = Smi::cast(key)->value();
    1334         148 :       source_positions.push_back(position);
    1335             :     }
    1336             :   }
    1337             :   return source_positions;
    1338             : }
    1339             : 
    1340         148 : std::vector<Handle<String>> FeedbackNexus::GetTypesForSourcePositions(
    1341             :     uint32_t position) const {
    1342             :   DCHECK(IsTypeProfileKind(kind()));
    1343             :   Isolate* isolate = GetIsolate();
    1344             : 
    1345         148 :   MaybeObject const feedback = GetFeedback();
    1346             :   std::vector<Handle<String>> types_for_position;
    1347         148 :   if (feedback == MaybeObject::FromObject(
    1348             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1349             :     return types_for_position;
    1350             :   }
    1351             : 
    1352             :   Handle<SimpleNumberDictionary> types(
    1353             :       SimpleNumberDictionary::cast(feedback->GetHeapObjectAssumeStrong()),
    1354             :       isolate);
    1355             : 
    1356         148 :   int entry = types->FindEntry(isolate, position);
    1357         148 :   if (entry == SimpleNumberDictionary::kNotFound) {
    1358             :     return types_for_position;
    1359             :   }
    1360             :   DCHECK(types->ValueAt(entry)->IsArrayList());
    1361             :   Handle<ArrayList> position_specific_types =
    1362             :       Handle<ArrayList>(ArrayList::cast(types->ValueAt(entry)), isolate);
    1363         540 :   for (int i = 0; i < position_specific_types->Length(); i++) {
    1364             :     Object t = position_specific_types->Get(i);
    1365         196 :     types_for_position.push_back(Handle<String>(String::cast(t), isolate));
    1366             :   }
    1367             : 
    1368             :   return types_for_position;
    1369             : }
    1370             : 
    1371             : namespace {
    1372             : 
    1373           0 : Handle<JSObject> ConvertToJSObject(Isolate* isolate,
    1374             :                                    Handle<SimpleNumberDictionary> feedback) {
    1375             :   Handle<JSObject> type_profile =
    1376           0 :       isolate->factory()->NewJSObject(isolate->object_function());
    1377             : 
    1378           0 :   for (int index = SimpleNumberDictionary::kElementsStartIndex;
    1379             :        index < feedback->length();
    1380             :        index += SimpleNumberDictionary::kEntrySize) {
    1381             :     int key_index = index + SimpleNumberDictionary::kEntryKeyIndex;
    1382             :     Object key = feedback->get(key_index);
    1383           0 :     if (key->IsSmi()) {
    1384           0 :       int value_index = index + SimpleNumberDictionary::kEntryValueIndex;
    1385             : 
    1386             :       Handle<ArrayList> position_specific_types(
    1387             :           ArrayList::cast(feedback->get(value_index)), isolate);
    1388             : 
    1389             :       int position = Smi::ToInt(key);
    1390           0 :       JSObject::AddDataElement(
    1391             :           type_profile, position,
    1392             :           isolate->factory()->NewJSArrayWithElements(
    1393             :               ArrayList::Elements(isolate, position_specific_types)),
    1394           0 :           PropertyAttributes::NONE);
    1395             :     }
    1396             :   }
    1397           0 :   return type_profile;
    1398             : }
    1399             : }  // namespace
    1400             : 
    1401           0 : JSObject FeedbackNexus::GetTypeProfile() const {
    1402             :   DCHECK(IsTypeProfileKind(kind()));
    1403             :   Isolate* isolate = GetIsolate();
    1404             : 
    1405           0 :   MaybeObject const feedback = GetFeedback();
    1406             : 
    1407           0 :   if (feedback == MaybeObject::FromObject(
    1408             :                       *FeedbackVector::UninitializedSentinel(isolate))) {
    1409           0 :     return *isolate->factory()->NewJSObject(isolate->object_function());
    1410             :   }
    1411             : 
    1412           0 :   return *ConvertToJSObject(isolate,
    1413             :                             handle(SimpleNumberDictionary::cast(
    1414             :                                        feedback->GetHeapObjectAssumeStrong()),
    1415             :                                    isolate));
    1416             : }
    1417             : 
    1418         212 : void FeedbackNexus::ResetTypeProfile() {
    1419             :   DCHECK(IsTypeProfileKind(kind()));
    1420             :   SetFeedback(*FeedbackVector::UninitializedSentinel(GetIsolate()));
    1421         212 : }
    1422             : 
    1423             : }  // namespace internal
    1424      122036 : }  // namespace v8

Generated by: LCOV version 1.10