diff options
Diffstat (limited to 'deps/v8/src/feedback-vector.cc')
-rw-r--r-- | deps/v8/src/feedback-vector.cc | 150 |
1 files changed, 107 insertions, 43 deletions
diff --git a/deps/v8/src/feedback-vector.cc b/deps/v8/src/feedback-vector.cc index c105effd77..0572b85395 100644 --- a/deps/v8/src/feedback-vector.cc +++ b/deps/v8/src/feedback-vector.cc @@ -193,6 +193,8 @@ const char* FeedbackMetadata::Kind2String(FeedbackSlotKind kind) { return "TypeProfile"; case FeedbackSlotKind::kForIn: return "ForIn"; + case FeedbackSlotKind::kInstanceOf: + return "InstanceOf"; case FeedbackSlotKind::kKindsNumber: break; } @@ -282,6 +284,7 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate, case FeedbackSlotKind::kStoreKeyedStrict: case FeedbackSlotKind::kStoreDataPropertyInLiteral: case FeedbackSlotKind::kTypeProfile: + case FeedbackSlotKind::kInstanceOf: vector->set(index, *uninitialized_sentinel, SKIP_WRITE_BARRIER); break; @@ -297,8 +300,9 @@ Handle<FeedbackVector> FeedbackVector::New(Isolate* isolate, } Handle<FeedbackVector> result = Handle<FeedbackVector>::cast(vector); - if (!isolate->is_best_effort_code_coverage()) { - AddToCodeCoverageList(isolate, result); + if (!isolate->is_best_effort_code_coverage() || + isolate->is_collecting_type_profile()) { + AddToVectorsForProfilingTools(isolate, result); } return result; } @@ -309,21 +313,23 @@ Handle<FeedbackVector> FeedbackVector::Copy(Isolate* isolate, Handle<FeedbackVector> result; result = Handle<FeedbackVector>::cast( isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector))); - if (!isolate->is_best_effort_code_coverage()) { - AddToCodeCoverageList(isolate, result); + if (!isolate->is_best_effort_code_coverage() || + isolate->is_collecting_type_profile()) { + AddToVectorsForProfilingTools(isolate, result); } return result; } // static -void FeedbackVector::AddToCodeCoverageList(Isolate* isolate, - Handle<FeedbackVector> vector) { - DCHECK(!isolate->is_best_effort_code_coverage()); +void FeedbackVector::AddToVectorsForProfilingTools( + Isolate* isolate, Handle<FeedbackVector> vector) { + DCHECK(!isolate->is_best_effort_code_coverage() || + isolate->is_collecting_type_profile()); if (!vector->shared_function_info()->IsSubjectToDebugging()) return; - Handle<ArrayList> list = - Handle<ArrayList>::cast(isolate->factory()->code_coverage_list()); + Handle<ArrayList> list = Handle<ArrayList>::cast( + isolate->factory()->feedback_vectors_for_profiling_tools()); list = ArrayList::Add(list, vector); - isolate->SetCodeCoverageList(*list); + isolate->SetFeedbackVectorsForProfilingTools(*list); } // static @@ -445,9 +451,17 @@ bool FeedbackVector::ClearSlots(Isolate* isolate) { // Set(slot, Smi::kZero); break; } - case FeedbackSlotKind::kCreateClosure: { - case FeedbackSlotKind::kTypeProfile: - break; + case FeedbackSlotKind::kInstanceOf: { + InstanceOfICNexus nexus(this, slot); + if (!nexus.IsCleared()) { + nexus.Clear(); + feedback_updated = true; + } + break; + } + case FeedbackSlotKind::kCreateClosure: + case FeedbackSlotKind::kTypeProfile: { + break; } case FeedbackSlotKind::kLiteral: { Set(slot, Smi::kZero, SKIP_WRITE_BARRIER); @@ -510,12 +524,22 @@ void FeedbackNexus::ConfigurePremonomorphic() { SKIP_WRITE_BARRIER); } -void FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) { +bool FeedbackNexus::ConfigureMegamorphic(IcCheckType property_type) { + DisallowHeapAllocation no_gc; Isolate* isolate = GetIsolate(); - SetFeedback(*FeedbackVector::MegamorphicSentinel(isolate), - SKIP_WRITE_BARRIER); - SetFeedbackExtra(Smi::FromInt(static_cast<int>(property_type)), - SKIP_WRITE_BARRIER); + bool changed = false; + Symbol* sentinel = *FeedbackVector::MegamorphicSentinel(isolate); + if (GetFeedback() != sentinel) { + SetFeedback(sentinel, SKIP_WRITE_BARRIER); + changed = true; + } + + Smi* extra = Smi::FromInt(static_cast<int>(property_type)); + if (changed || GetFeedbackExtra() != extra) { + SetFeedbackExtra(extra, SKIP_WRITE_BARRIER); + changed = true; + } + return changed; } InlineCacheState LoadICNexus::StateFromFeedback() const { @@ -705,7 +729,7 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps, ObjectHandles* handlers) { int receiver_count = static_cast<int>(maps.size()); - DCHECK(receiver_count > 1); + DCHECK_GT(receiver_count, 1); Handle<FixedArray> array; if (name.is_null()) { array = EnsureArrayOfSize(receiver_count * 2); @@ -833,7 +857,7 @@ Name* KeyedLoadICNexus::FindFirstName() const { if (IsPropertyNameFeedback(feedback)) { return Name::cast(feedback); } - return NULL; + return nullptr; } Name* KeyedStoreICNexus::FindFirstName() const { @@ -841,7 +865,23 @@ Name* KeyedStoreICNexus::FindFirstName() const { if (IsPropertyNameFeedback(feedback)) { return Name::cast(feedback); } - return NULL; + return nullptr; +} + +KeyedAccessLoadMode KeyedLoadICNexus::GetKeyedAccessLoadMode() const { + MapHandles maps; + ObjectHandles handlers; + + if (GetKeyType() == PROPERTY) return STANDARD_LOAD; + + ExtractMaps(&maps); + FindHandlers(&handlers, static_cast<int>(maps.size())); + for (Handle<Object> const& handler : handlers) { + KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler); + if (mode != STANDARD_LOAD) return mode; + } + + return STANDARD_LOAD; } KeyedAccessStoreMode KeyedStoreICNexus::GetKeyedAccessStoreMode() const { @@ -952,6 +992,32 @@ ForInHint ForInICNexus::GetForInFeedback() const { return ForInHintFromFeedback(feedback); } +void InstanceOfICNexus::ConfigureUninitialized() { + SetFeedback(*FeedbackVector::UninitializedSentinel(GetIsolate()), + SKIP_WRITE_BARRIER); +} + +InlineCacheState InstanceOfICNexus::StateFromFeedback() const { + Isolate* isolate = GetIsolate(); + Object* feedback = GetFeedback(); + + if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) { + return UNINITIALIZED; + } else if (feedback == *FeedbackVector::MegamorphicSentinel(isolate)) { + return MEGAMORPHIC; + } + return MONOMORPHIC; +} + +MaybeHandle<JSObject> InstanceOfICNexus::GetConstructorFeedback() const { + Isolate* isolate = GetIsolate(); + Object* feedback = GetFeedback(); + if (feedback->IsWeakCell() && !WeakCell::cast(feedback)->cleared()) { + return handle(JSObject::cast(WeakCell::cast(feedback)->value()), isolate); + } + return MaybeHandle<JSObject>(); +} + InlineCacheState StoreDataPropertyInLiteralICNexus::StateFromFeedback() const { Isolate* isolate = GetIsolate(); Object* feedback = GetFeedback(); @@ -1004,26 +1070,26 @@ void CollectTypeProfileNexus::Collect(Handle<String> type, int position) { Object* const feedback = GetFeedback(); // Map source position to collection of types - Handle<UnseededNumberDictionary> types; + Handle<NumberDictionary> types; if (feedback == *FeedbackVector::UninitializedSentinel(isolate)) { - types = UnseededNumberDictionary::New(isolate, 1); + types = NumberDictionary::New(isolate, 1); } else { - types = handle(UnseededNumberDictionary::cast(feedback)); + types = handle(NumberDictionary::cast(feedback)); } Handle<ArrayList> position_specific_types; int entry = types->FindEntry(position); - if (entry == UnseededNumberDictionary::kNotFound) { + if (entry == NumberDictionary::kNotFound) { position_specific_types = ArrayList::New(isolate, 1); - types = UnseededNumberDictionary::Set( + types = NumberDictionary::Set( types, position, ArrayList::Add(position_specific_types, type)); } else { DCHECK(types->ValueAt(entry)->IsArrayList()); position_specific_types = handle(ArrayList::cast(types->ValueAt(entry))); if (!InList(position_specific_types, type)) { // Add type - types = UnseededNumberDictionary::Set( + types = NumberDictionary::Set( types, position, ArrayList::Add(position_specific_types, type)); } } @@ -1044,12 +1110,12 @@ std::vector<int> CollectTypeProfileNexus::GetSourcePositions() const { return source_positions; } - Handle<UnseededNumberDictionary> types = Handle<UnseededNumberDictionary>( - UnseededNumberDictionary::cast(feedback), isolate); + Handle<NumberDictionary> types = + Handle<NumberDictionary>(NumberDictionary::cast(feedback), isolate); - for (int index = UnseededNumberDictionary::kElementsStartIndex; - index < types->length(); index += UnseededNumberDictionary::kEntrySize) { - int key_index = index + UnseededNumberDictionary::kEntryKeyIndex; + for (int index = NumberDictionary::kElementsStartIndex; + index < types->length(); index += NumberDictionary::kEntrySize) { + int key_index = index + NumberDictionary::kEntryKeyIndex; Object* key = types->get(key_index); if (key->IsSmi()) { int position = Smi::cast(key)->value(); @@ -1069,11 +1135,11 @@ std::vector<Handle<String>> CollectTypeProfileNexus::GetTypesForSourcePositions( return types_for_position; } - Handle<UnseededNumberDictionary> types = Handle<UnseededNumberDictionary>( - UnseededNumberDictionary::cast(feedback), isolate); + Handle<NumberDictionary> types = + Handle<NumberDictionary>(NumberDictionary::cast(feedback), isolate); int entry = types->FindEntry(position); - if (entry == UnseededNumberDictionary::kNotFound) { + if (entry == NumberDictionary::kNotFound) { return types_for_position; } DCHECK(types->ValueAt(entry)->IsArrayList()); @@ -1090,17 +1156,16 @@ std::vector<Handle<String>> CollectTypeProfileNexus::GetTypesForSourcePositions( namespace { Handle<JSObject> ConvertToJSObject(Isolate* isolate, - Handle<UnseededNumberDictionary> feedback) { + Handle<NumberDictionary> feedback) { Handle<JSObject> type_profile = isolate->factory()->NewJSObject(isolate->object_function()); - for (int index = UnseededNumberDictionary::kElementsStartIndex; - index < feedback->length(); - index += UnseededNumberDictionary::kEntrySize) { - int key_index = index + UnseededNumberDictionary::kEntryKeyIndex; + for (int index = NumberDictionary::kElementsStartIndex; + index < feedback->length(); index += NumberDictionary::kEntrySize) { + int key_index = index + NumberDictionary::kEntryKeyIndex; Object* key = feedback->get(key_index); if (key->IsSmi()) { - int value_index = index + UnseededNumberDictionary::kEntryValueIndex; + int value_index = index + NumberDictionary::kEntryValueIndex; Handle<ArrayList> position_specific_types( ArrayList::cast(feedback->get(value_index))); @@ -1127,8 +1192,7 @@ JSObject* CollectTypeProfileNexus::GetTypeProfile() const { return *isolate->factory()->NewJSObject(isolate->object_function()); } - return *ConvertToJSObject(isolate, - handle(UnseededNumberDictionary::cast(feedback))); + return *ConvertToJSObject(isolate, handle(NumberDictionary::cast(feedback))); } } // namespace internal |