diff --git a/src/compiler/js-heap-broker.cc b/src/compiler/js-heap-broker.cc index eb2b861e36..40d009f435 100644 --- a/src/compiler/js-heap-broker.cc +++ b/src/compiler/js-heap-broker.cc @@ -4667,12 +4667,12 @@ bool ElementAccessFeedback::HasOnlyStringMaps(JSHeapBroker* broker) const { } MinimorphicLoadPropertyAccessFeedback::MinimorphicLoadPropertyAccessFeedback( - NameRef const& name, FeedbackSlotKind slot_kind, bool is_monomorphic, - Handle handler, bool has_migration_target_maps) + NameRef const& name, FeedbackSlotKind slot_kind, Handle handler, + MaybeHandle maybe_map, bool has_migration_target_maps) : ProcessedFeedback(kMinimorphicPropertyAccess, slot_kind), name_(name), - is_monomorphic_(is_monomorphic), handler_(handler), + maybe_map_(maybe_map), has_migration_target_maps_(has_migration_target_maps) { DCHECK(IsLoadICKind(slot_kind)); } @@ -4810,9 +4810,13 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess( static_name.has_value() ? static_name : GetNameFeedback(nexus); MaybeObjectHandle handler = TryGetMinimorphicHandler(maps_and_handlers, kind); if (!handler.is_null()) { + MaybeHandle maybe_map; + if (nexus.ic_state() == MONOMORPHIC) { + DCHECK_EQ(maps.size(), 1); + maybe_map = maps[0]; + } return *zone()->New( - *name, kind, nexus.ic_state() == MONOMORPHIC, handler.object(), - HasMigrationTargets(maps)); + *name, kind, handler.object(), maybe_map, HasMigrationTargets(maps)); } FilterRelevantReceiverMaps(isolate(), &maps); diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc index 2fd99244d1..2a4524f386 100644 --- a/src/compiler/js-native-context-specialization.cc +++ b/src/compiler/js-native-context-specialization.cc @@ -1071,13 +1071,10 @@ Reduction JSNativeContextSpecialization::ReduceMinimorphicPropertyAccess( if (feedback.has_migration_target_maps()) { flags |= CheckMapsFlag::kTryMigrateInstance; } - effect = graph()->NewNode( - simplified()->DynamicCheckMaps( - flags, feedback.handler(), source, - feedback.is_monomorphic() - ? DynamicCheckMapsParameters::ICState::kMonomorphic - : DynamicCheckMapsParameters::ICState::kPolymorphic), - receiver, effect, control); + effect = + graph()->NewNode(simplified()->DynamicCheckMaps(flags, feedback.handler(), + feedback.map(), source), + receiver, effect, control); value = access_builder.BuildMinimorphicLoadDataField( feedback.name(), access_info, receiver, &effect, &control); diff --git a/src/compiler/processed-feedback.h b/src/compiler/processed-feedback.h index cd916f9b47..282923e0c3 100644 --- a/src/compiler/processed-feedback.h +++ b/src/compiler/processed-feedback.h @@ -177,19 +177,20 @@ class MinimorphicLoadPropertyAccessFeedback : public ProcessedFeedback { public: MinimorphicLoadPropertyAccessFeedback(NameRef const& name, FeedbackSlotKind slot_kind, - bool is_monomorphic, Handle handler, + MaybeHandle maybe_map, bool has_migration_target_maps); NameRef const& name() const { return name_; } - bool is_monomorphic() const { return is_monomorphic_; } + bool is_monomorphic() const { return !maybe_map_.is_null(); } Handle handler() const { return handler_; } + MaybeHandle map() const { return maybe_map_; } bool has_migration_target_maps() const { return has_migration_target_maps_; } private: NameRef const name_; - bool const is_monomorphic_; Handle const handler_; + MaybeHandle const maybe_map_; bool const has_migration_target_maps_; }; diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc index bedfb6acaa..04bf710ea1 100644 --- a/src/compiler/simplified-operator.cc +++ b/src/compiler/simplified-operator.cc @@ -289,19 +289,26 @@ CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) { bool operator==(DynamicCheckMapsParameters const& lhs, DynamicCheckMapsParameters const& rhs) { - return lhs.handler().address() == rhs.handler().address() && - lhs.feedback() == rhs.feedback() && lhs.state() == rhs.state(); + // FeedbackSource is sufficient as an equality check. FeedbackSource uniquely + // determines all other properties (handler, flags and the monomorphic map + DCHECK_IMPLIES(lhs.feedback() == rhs.feedback(), + lhs.flags() == rhs.flags() && lhs.state() == rhs.state() && + lhs.handler().address() == rhs.handler().address() && + lhs.map().address() == rhs.map().address()); + return lhs.feedback() == rhs.feedback(); } size_t hash_value(DynamicCheckMapsParameters const& p) { FeedbackSource::Hash feedback_hash; - return base::hash_combine(p.handler().address(), feedback_hash(p.feedback()), - p.state()); + // FeedbackSource is sufficient for hashing. FeedbackSource uniquely + // determines all other properties (handler, flags and the monomorphic map + return base::hash_combine(feedback_hash(p.feedback())); } std::ostream& operator<<(std::ostream& os, DynamicCheckMapsParameters const& p) { - return os << p.handler() << ", " << p.feedback() << "," << p.state(); + return os << p.handler() << ", " << p.feedback() << "," << p.state() << "," + << p.flags() << "," << p.map().address(); } DynamicCheckMapsParameters const& DynamicCheckMapsParametersOf( @@ -1474,11 +1481,10 @@ const Operator* SimplifiedOperatorBuilder::CheckMaps( } const Operator* SimplifiedOperatorBuilder::DynamicCheckMaps( - CheckMapsFlags flags, Handle handler, - const FeedbackSource& feedback, - DynamicCheckMapsParameters::ICState ic_state) { - DynamicCheckMapsParameters const parameters(flags, handler, feedback, - ic_state); + CheckMapsFlags flags, Handle handler, MaybeHandle maybe_map, + const FeedbackSource& feedback) { + DynamicCheckMapsParameters const parameters(flags, handler, maybe_map, + feedback); return zone()->New>( // -- IrOpcode::kDynamicCheckMaps, // opcode Operator::kNoThrow | Operator::kNoWrite, // flags diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index c4b5740c10..2a2f461a0e 100644 --- a/src/compiler/simplified-operator.h +++ b/src/compiler/simplified-operator.h @@ -432,19 +432,26 @@ class DynamicCheckMapsParameters final { enum ICState { kMonomorphic, kPolymorphic }; DynamicCheckMapsParameters(CheckMapsFlags flags, Handle handler, - const FeedbackSource& feedback, ICState state) - : flags_(flags), handler_(handler), feedback_(feedback), state_(state) {} + MaybeHandle maybe_map, + const FeedbackSource& feedback) + : flags_(flags), + handler_(handler), + maybe_map_(maybe_map), + feedback_(feedback) {} CheckMapsFlags flags() const { return flags_; } Handle handler() const { return handler_; } + MaybeHandle map() const { return maybe_map_; } FeedbackSource const& feedback() const { return feedback_; } - ICState const& state() const { return state_; } + ICState state() const { + return maybe_map_.is_null() ? ICState::kPolymorphic : ICState::kMonomorphic; + } private: CheckMapsFlags const flags_; Handle const handler_; + MaybeHandle const maybe_map_; FeedbackSource const feedback_; - ICState const state_; }; bool operator==(DynamicCheckMapsParameters const&, @@ -875,10 +882,9 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final const Operator* CheckInternalizedString(); const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet, const FeedbackSource& = FeedbackSource()); - const Operator* DynamicCheckMaps( - CheckMapsFlags flags, Handle handler, - const FeedbackSource& feedback, - DynamicCheckMapsParameters::ICState ic_state); + const Operator* DynamicCheckMaps(CheckMapsFlags flags, Handle handler, + MaybeHandle map, + const FeedbackSource& feedback); const Operator* CheckNotTaggedHole(); const Operator* CheckNumber(const FeedbackSource& feedback); const Operator* CheckReceiver();