11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#ifdef ENABLE_SLOW_DCHECKS
81cb0ef41Sopenharmony_ci#include <algorithm>
91cb0ef41Sopenharmony_ci#endif
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
121cb0ef41Sopenharmony_ci#include "src/codegen/optimized-compilation-info.h"
131cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
141cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
151cb0ef41Sopenharmony_ci#include "src/ic/handler-configuration-inl.h"
161cb0ef41Sopenharmony_ci#include "src/init/bootstrapper.h"
171cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
181cb0ef41Sopenharmony_ci#include "src/objects/data-handler-inl.h"
191cb0ef41Sopenharmony_ci#include "src/objects/feedback-cell.h"
201cb0ef41Sopenharmony_ci#include "src/objects/js-array-inl.h"
211cb0ef41Sopenharmony_ci#include "src/objects/literal-objects-inl.h"
221cb0ef41Sopenharmony_ci#include "src/objects/map-updater.h"
231cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
241cb0ef41Sopenharmony_ci#include "src/objects/oddball.h"
251cb0ef41Sopenharmony_ci#include "src/objects/property-cell.h"
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cinamespace v8 {
281cb0ef41Sopenharmony_cinamespace internal {
291cb0ef41Sopenharmony_cinamespace compiler {
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci#define TRACE(broker, x) TRACE_BROKER(broker, x)
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci#ifdef V8_STATIC_CONSTEXPR_VARIABLES_NEED_DEFINITIONS
341cb0ef41Sopenharmony_ci// These definitions are here in order to please the linker, which in debug mode
351cb0ef41Sopenharmony_ci// sometimes requires static constants to be defined in .cc files.
361cb0ef41Sopenharmony_ci// This is, however, deprecated (and unnecessary) in C++17.
371cb0ef41Sopenharmony_ciconst uint32_t JSHeapBroker::kMinimalRefsBucketCount;
381cb0ef41Sopenharmony_ciconst uint32_t JSHeapBroker::kInitialRefsBucketCount;
391cb0ef41Sopenharmony_ci#endif
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_civoid JSHeapBroker::IncrementTracingIndentation() { ++trace_indentation_; }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_civoid JSHeapBroker::DecrementTracingIndentation() { --trace_indentation_; }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciJSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
461cb0ef41Sopenharmony_ci                           bool tracing_enabled, CodeKind code_kind)
471cb0ef41Sopenharmony_ci    : isolate_(isolate),
481cb0ef41Sopenharmony_ci#if V8_COMPRESS_POINTERS
491cb0ef41Sopenharmony_ci      cage_base_(isolate),
501cb0ef41Sopenharmony_ci#endif  // V8_COMPRESS_POINTERS
511cb0ef41Sopenharmony_ci      zone_(broker_zone),
521cb0ef41Sopenharmony_ci      // Note that this initialization of {refs_} with the minimal initial
531cb0ef41Sopenharmony_ci      // capacity is redundant in the normal use case (concurrent compilation
541cb0ef41Sopenharmony_ci      // enabled, standard objects to be serialized), as the map is going to be
551cb0ef41Sopenharmony_ci      // replaced immediately with a larger-capacity one.  It doesn't seem to
561cb0ef41Sopenharmony_ci      // affect the performance in a noticeable way though.
571cb0ef41Sopenharmony_ci      refs_(zone()->New<RefsMap>(kMinimalRefsBucketCount, AddressMatcher(),
581cb0ef41Sopenharmony_ci                                 zone())),
591cb0ef41Sopenharmony_ci      root_index_map_(isolate),
601cb0ef41Sopenharmony_ci      array_and_object_prototypes_(zone()),
611cb0ef41Sopenharmony_ci      tracing_enabled_(tracing_enabled),
621cb0ef41Sopenharmony_ci      code_kind_(code_kind),
631cb0ef41Sopenharmony_ci      feedback_(zone()),
641cb0ef41Sopenharmony_ci      property_access_infos_(zone()) {
651cb0ef41Sopenharmony_ci  TRACE(this, "Constructing heap broker");
661cb0ef41Sopenharmony_ci}
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciJSHeapBroker::~JSHeapBroker() { DCHECK_NULL(local_isolate_); }
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_civoid JSHeapBroker::SetPersistentAndCopyCanonicalHandlesForTesting(
711cb0ef41Sopenharmony_ci    std::unique_ptr<PersistentHandles> persistent_handles,
721cb0ef41Sopenharmony_ci    std::unique_ptr<CanonicalHandlesMap> canonical_handles) {
731cb0ef41Sopenharmony_ci  set_persistent_handles(std::move(persistent_handles));
741cb0ef41Sopenharmony_ci  CopyCanonicalHandlesForTesting(std::move(canonical_handles));
751cb0ef41Sopenharmony_ci}
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_civoid JSHeapBroker::CopyCanonicalHandlesForTesting(
781cb0ef41Sopenharmony_ci    std::unique_ptr<CanonicalHandlesMap> canonical_handles) {
791cb0ef41Sopenharmony_ci  DCHECK_NULL(canonical_handles_);
801cb0ef41Sopenharmony_ci  canonical_handles_ = std::make_unique<CanonicalHandlesMap>(
811cb0ef41Sopenharmony_ci      isolate_->heap(), ZoneAllocationPolicy(zone()));
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  CanonicalHandlesMap::IteratableScope it_scope(canonical_handles.get());
841cb0ef41Sopenharmony_ci  for (auto it = it_scope.begin(); it != it_scope.end(); ++it) {
851cb0ef41Sopenharmony_ci    Address* entry = *it.entry();
861cb0ef41Sopenharmony_ci    Object key = it.key();
871cb0ef41Sopenharmony_ci    canonical_handles_->Insert(key, entry);
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci}
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_cistd::string JSHeapBroker::Trace() const {
921cb0ef41Sopenharmony_ci  std::ostringstream oss;
931cb0ef41Sopenharmony_ci  oss << "[" << this << "] ";
941cb0ef41Sopenharmony_ci  for (unsigned i = 0; i < trace_indentation_ * 2; ++i) oss.put(' ');
951cb0ef41Sopenharmony_ci  return oss.str();
961cb0ef41Sopenharmony_ci}
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_civoid JSHeapBroker::AttachLocalIsolate(OptimizedCompilationInfo* info,
991cb0ef41Sopenharmony_ci                                      LocalIsolate* local_isolate) {
1001cb0ef41Sopenharmony_ci  set_canonical_handles(info->DetachCanonicalHandles());
1011cb0ef41Sopenharmony_ci  DCHECK_NULL(local_isolate_);
1021cb0ef41Sopenharmony_ci  local_isolate_ = local_isolate;
1031cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(local_isolate_);
1041cb0ef41Sopenharmony_ci  local_isolate_->heap()->AttachPersistentHandles(
1051cb0ef41Sopenharmony_ci      info->DetachPersistentHandles());
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_civoid JSHeapBroker::DetachLocalIsolate(OptimizedCompilationInfo* info) {
1091cb0ef41Sopenharmony_ci  DCHECK_NULL(ph_);
1101cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(local_isolate_);
1111cb0ef41Sopenharmony_ci  std::unique_ptr<PersistentHandles> ph =
1121cb0ef41Sopenharmony_ci      local_isolate_->heap()->DetachPersistentHandles();
1131cb0ef41Sopenharmony_ci  local_isolate_ = nullptr;
1141cb0ef41Sopenharmony_ci  info->set_canonical_handles(DetachCanonicalHandles());
1151cb0ef41Sopenharmony_ci  info->set_persistent_handles(std::move(ph));
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_civoid JSHeapBroker::StopSerializing() {
1191cb0ef41Sopenharmony_ci  CHECK_EQ(mode_, kSerializing);
1201cb0ef41Sopenharmony_ci  TRACE(this, "Stopping serialization");
1211cb0ef41Sopenharmony_ci  mode_ = kSerialized;
1221cb0ef41Sopenharmony_ci}
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_civoid JSHeapBroker::Retire() {
1251cb0ef41Sopenharmony_ci  CHECK_EQ(mode_, kSerialized);
1261cb0ef41Sopenharmony_ci  TRACE(this, "Retiring");
1271cb0ef41Sopenharmony_ci  mode_ = kRetired;
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_civoid JSHeapBroker::SetTargetNativeContextRef(
1311cb0ef41Sopenharmony_ci    Handle<NativeContext> native_context) {
1321cb0ef41Sopenharmony_ci  DCHECK((mode() == kDisabled && !target_native_context_.has_value()) ||
1331cb0ef41Sopenharmony_ci         (mode() == kSerializing &&
1341cb0ef41Sopenharmony_ci          target_native_context_->object().is_identical_to(native_context)));
1351cb0ef41Sopenharmony_ci  target_native_context_ = MakeRef(this, *native_context);
1361cb0ef41Sopenharmony_ci}
1371cb0ef41Sopenharmony_ci
1381cb0ef41Sopenharmony_civoid JSHeapBroker::CollectArrayAndObjectPrototypes() {
1391cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
1401cb0ef41Sopenharmony_ci  CHECK_EQ(mode(), kSerializing);
1411cb0ef41Sopenharmony_ci  CHECK(array_and_object_prototypes_.empty());
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  Object maybe_context = isolate()->heap()->native_contexts_list();
1441cb0ef41Sopenharmony_ci  while (!maybe_context.IsUndefined(isolate())) {
1451cb0ef41Sopenharmony_ci    Context context = Context::cast(maybe_context);
1461cb0ef41Sopenharmony_ci    Object array_prot = context.get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
1471cb0ef41Sopenharmony_ci    Object object_prot = context.get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
1481cb0ef41Sopenharmony_ci    array_and_object_prototypes_.emplace(JSObject::cast(array_prot), isolate());
1491cb0ef41Sopenharmony_ci    array_and_object_prototypes_.emplace(JSObject::cast(object_prot),
1501cb0ef41Sopenharmony_ci                                         isolate());
1511cb0ef41Sopenharmony_ci    maybe_context = context.next_context_link();
1521cb0ef41Sopenharmony_ci  }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  CHECK(!array_and_object_prototypes_.empty());
1551cb0ef41Sopenharmony_ci}
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ciStringRef JSHeapBroker::GetTypedArrayStringTag(ElementsKind kind) {
1581cb0ef41Sopenharmony_ci  DCHECK(IsTypedArrayElementsKind(kind));
1591cb0ef41Sopenharmony_ci  switch (kind) {
1601cb0ef41Sopenharmony_ci#define TYPED_ARRAY_STRING_TAG(Type, type, TYPE, ctype) \
1611cb0ef41Sopenharmony_ci  case ElementsKind::TYPE##_ELEMENTS:                   \
1621cb0ef41Sopenharmony_ci    return MakeRef(this, isolate()->factory()->Type##Array_string());
1631cb0ef41Sopenharmony_ci    TYPED_ARRAYS(TYPED_ARRAY_STRING_TAG)
1641cb0ef41Sopenharmony_ci#undef TYPED_ARRAY_STRING_TAG
1651cb0ef41Sopenharmony_ci    default:
1661cb0ef41Sopenharmony_ci      UNREACHABLE();
1671cb0ef41Sopenharmony_ci  }
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_cibool JSHeapBroker::IsArrayOrObjectPrototype(const JSObjectRef& object) const {
1711cb0ef41Sopenharmony_ci  return IsArrayOrObjectPrototype(object.object());
1721cb0ef41Sopenharmony_ci}
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_cibool JSHeapBroker::IsArrayOrObjectPrototype(Handle<JSObject> object) const {
1751cb0ef41Sopenharmony_ci  if (mode() == kDisabled) {
1761cb0ef41Sopenharmony_ci    return isolate()->IsInAnyContext(*object,
1771cb0ef41Sopenharmony_ci                                     Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ||
1781cb0ef41Sopenharmony_ci           isolate()->IsInAnyContext(*object,
1791cb0ef41Sopenharmony_ci                                     Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
1801cb0ef41Sopenharmony_ci  }
1811cb0ef41Sopenharmony_ci  CHECK(!array_and_object_prototypes_.empty());
1821cb0ef41Sopenharmony_ci  return array_and_object_prototypes_.find(object) !=
1831cb0ef41Sopenharmony_ci         array_and_object_prototypes_.end();
1841cb0ef41Sopenharmony_ci}
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ciObjectData* JSHeapBroker::TryGetOrCreateData(Object object,
1871cb0ef41Sopenharmony_ci                                             GetOrCreateDataFlags flags) {
1881cb0ef41Sopenharmony_ci  return TryGetOrCreateData(CanonicalPersistentHandle(object), flags);
1891cb0ef41Sopenharmony_ci}
1901cb0ef41Sopenharmony_ci
1911cb0ef41Sopenharmony_ciObjectData* JSHeapBroker::GetOrCreateData(Handle<Object> object,
1921cb0ef41Sopenharmony_ci                                          GetOrCreateDataFlags flags) {
1931cb0ef41Sopenharmony_ci  ObjectData* return_value = TryGetOrCreateData(object, flags | kCrashOnError);
1941cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(return_value);
1951cb0ef41Sopenharmony_ci  return return_value;
1961cb0ef41Sopenharmony_ci}
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ciObjectData* JSHeapBroker::GetOrCreateData(Object object,
1991cb0ef41Sopenharmony_ci                                          GetOrCreateDataFlags flags) {
2001cb0ef41Sopenharmony_ci  return GetOrCreateData(CanonicalPersistentHandle(object), flags);
2011cb0ef41Sopenharmony_ci}
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_cibool JSHeapBroker::StackHasOverflowed() const {
2041cb0ef41Sopenharmony_ci  DCHECK_IMPLIES(local_isolate_ == nullptr,
2051cb0ef41Sopenharmony_ci                 ThreadId::Current() == isolate_->thread_id());
2061cb0ef41Sopenharmony_ci  return (local_isolate_ != nullptr)
2071cb0ef41Sopenharmony_ci             ? StackLimitCheck::HasOverflowed(local_isolate_)
2081cb0ef41Sopenharmony_ci             : StackLimitCheck(isolate_).HasOverflowed();
2091cb0ef41Sopenharmony_ci}
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_cibool JSHeapBroker::ObjectMayBeUninitialized(Handle<Object> object) const {
2121cb0ef41Sopenharmony_ci  return ObjectMayBeUninitialized(*object);
2131cb0ef41Sopenharmony_ci}
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_cibool JSHeapBroker::ObjectMayBeUninitialized(Object object) const {
2161cb0ef41Sopenharmony_ci  if (!object.IsHeapObject()) return false;
2171cb0ef41Sopenharmony_ci  return ObjectMayBeUninitialized(HeapObject::cast(object));
2181cb0ef41Sopenharmony_ci}
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_cibool JSHeapBroker::ObjectMayBeUninitialized(HeapObject object) const {
2211cb0ef41Sopenharmony_ci  return !IsMainThread() && isolate()->heap()->IsPendingAllocation(object);
2221cb0ef41Sopenharmony_ci}
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ciProcessedFeedback::ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind)
2251cb0ef41Sopenharmony_ci    : kind_(kind), slot_kind_(slot_kind) {}
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ciKeyedAccessMode ElementAccessFeedback::keyed_mode() const {
2281cb0ef41Sopenharmony_ci  return keyed_mode_;
2291cb0ef41Sopenharmony_ci}
2301cb0ef41Sopenharmony_ci
2311cb0ef41Sopenharmony_ciZoneVector<ElementAccessFeedback::TransitionGroup> const&
2321cb0ef41Sopenharmony_ciElementAccessFeedback::transition_groups() const {
2331cb0ef41Sopenharmony_ci  return transition_groups_;
2341cb0ef41Sopenharmony_ci}
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ciElementAccessFeedback const& ElementAccessFeedback::Refine(
2371cb0ef41Sopenharmony_ci    JSHeapBroker* broker, ZoneVector<MapRef> const& inferred_maps) const {
2381cb0ef41Sopenharmony_ci  ElementAccessFeedback& refined_feedback =
2391cb0ef41Sopenharmony_ci      *broker->zone()->New<ElementAccessFeedback>(broker->zone(), keyed_mode(),
2401cb0ef41Sopenharmony_ci                                                  slot_kind());
2411cb0ef41Sopenharmony_ci  if (inferred_maps.empty()) return refined_feedback;
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  ZoneRefUnorderedSet<MapRef> inferred(broker->zone());
2441cb0ef41Sopenharmony_ci  inferred.insert(inferred_maps.begin(), inferred_maps.end());
2451cb0ef41Sopenharmony_ci
2461cb0ef41Sopenharmony_ci  for (auto const& group : transition_groups()) {
2471cb0ef41Sopenharmony_ci    DCHECK(!group.empty());
2481cb0ef41Sopenharmony_ci    TransitionGroup new_group(broker->zone());
2491cb0ef41Sopenharmony_ci    for (size_t i = 1; i < group.size(); ++i) {
2501cb0ef41Sopenharmony_ci      MapRef source = MakeRefAssumeMemoryFence(broker, *group[i]);
2511cb0ef41Sopenharmony_ci      if (inferred.find(source) != inferred.end()) {
2521cb0ef41Sopenharmony_ci        new_group.push_back(source.object());
2531cb0ef41Sopenharmony_ci      }
2541cb0ef41Sopenharmony_ci    }
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci    MapRef target = MakeRefAssumeMemoryFence(broker, *group.front());
2571cb0ef41Sopenharmony_ci    bool const keep_target =
2581cb0ef41Sopenharmony_ci        inferred.find(target) != inferred.end() || new_group.size() > 1;
2591cb0ef41Sopenharmony_ci    if (keep_target) {
2601cb0ef41Sopenharmony_ci      new_group.push_back(target.object());
2611cb0ef41Sopenharmony_ci      // The target must be at the front, the order of sources doesn't matter.
2621cb0ef41Sopenharmony_ci      std::swap(new_group[0], new_group[new_group.size() - 1]);
2631cb0ef41Sopenharmony_ci    }
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci    if (!new_group.empty()) {
2661cb0ef41Sopenharmony_ci      DCHECK(new_group.size() == 1 ||
2671cb0ef41Sopenharmony_ci             new_group.front().equals(target.object()));
2681cb0ef41Sopenharmony_ci      refined_feedback.transition_groups_.push_back(std::move(new_group));
2691cb0ef41Sopenharmony_ci    }
2701cb0ef41Sopenharmony_ci  }
2711cb0ef41Sopenharmony_ci  return refined_feedback;
2721cb0ef41Sopenharmony_ci}
2731cb0ef41Sopenharmony_ci
2741cb0ef41Sopenharmony_ciInsufficientFeedback::InsufficientFeedback(FeedbackSlotKind slot_kind)
2751cb0ef41Sopenharmony_ci    : ProcessedFeedback(kInsufficient, slot_kind) {}
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ciGlobalAccessFeedback::GlobalAccessFeedback(PropertyCellRef cell,
2781cb0ef41Sopenharmony_ci                                           FeedbackSlotKind slot_kind)
2791cb0ef41Sopenharmony_ci    : ProcessedFeedback(kGlobalAccess, slot_kind),
2801cb0ef41Sopenharmony_ci      cell_or_context_(cell),
2811cb0ef41Sopenharmony_ci      index_and_immutable_(0 /* doesn't matter */) {
2821cb0ef41Sopenharmony_ci  DCHECK(IsGlobalICKind(slot_kind));
2831cb0ef41Sopenharmony_ci}
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ciGlobalAccessFeedback::GlobalAccessFeedback(FeedbackSlotKind slot_kind)
2861cb0ef41Sopenharmony_ci    : ProcessedFeedback(kGlobalAccess, slot_kind),
2871cb0ef41Sopenharmony_ci      index_and_immutable_(0 /* doesn't matter */) {
2881cb0ef41Sopenharmony_ci  DCHECK(IsGlobalICKind(slot_kind));
2891cb0ef41Sopenharmony_ci}
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ciGlobalAccessFeedback::GlobalAccessFeedback(ContextRef script_context,
2921cb0ef41Sopenharmony_ci                                           int slot_index, bool immutable,
2931cb0ef41Sopenharmony_ci                                           FeedbackSlotKind slot_kind)
2941cb0ef41Sopenharmony_ci    : ProcessedFeedback(kGlobalAccess, slot_kind),
2951cb0ef41Sopenharmony_ci      cell_or_context_(script_context),
2961cb0ef41Sopenharmony_ci      index_and_immutable_(FeedbackNexus::SlotIndexBits::encode(slot_index) |
2971cb0ef41Sopenharmony_ci                           FeedbackNexus::ImmutabilityBit::encode(immutable)) {
2981cb0ef41Sopenharmony_ci  DCHECK_EQ(this->slot_index(), slot_index);
2991cb0ef41Sopenharmony_ci  DCHECK_EQ(this->immutable(), immutable);
3001cb0ef41Sopenharmony_ci  DCHECK(IsGlobalICKind(slot_kind));
3011cb0ef41Sopenharmony_ci}
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_cibool GlobalAccessFeedback::IsMegamorphic() const {
3041cb0ef41Sopenharmony_ci  return !cell_or_context_.has_value();
3051cb0ef41Sopenharmony_ci}
3061cb0ef41Sopenharmony_cibool GlobalAccessFeedback::IsPropertyCell() const {
3071cb0ef41Sopenharmony_ci  return cell_or_context_.has_value() && cell_or_context_->IsPropertyCell();
3081cb0ef41Sopenharmony_ci}
3091cb0ef41Sopenharmony_cibool GlobalAccessFeedback::IsScriptContextSlot() const {
3101cb0ef41Sopenharmony_ci  return cell_or_context_.has_value() && cell_or_context_->IsContext();
3111cb0ef41Sopenharmony_ci}
3121cb0ef41Sopenharmony_ciPropertyCellRef GlobalAccessFeedback::property_cell() const {
3131cb0ef41Sopenharmony_ci  CHECK(IsPropertyCell());
3141cb0ef41Sopenharmony_ci  return cell_or_context_->AsPropertyCell();
3151cb0ef41Sopenharmony_ci}
3161cb0ef41Sopenharmony_ciContextRef GlobalAccessFeedback::script_context() const {
3171cb0ef41Sopenharmony_ci  CHECK(IsScriptContextSlot());
3181cb0ef41Sopenharmony_ci  return cell_or_context_->AsContext();
3191cb0ef41Sopenharmony_ci}
3201cb0ef41Sopenharmony_ciint GlobalAccessFeedback::slot_index() const {
3211cb0ef41Sopenharmony_ci  DCHECK(IsScriptContextSlot());
3221cb0ef41Sopenharmony_ci  return FeedbackNexus::SlotIndexBits::decode(index_and_immutable_);
3231cb0ef41Sopenharmony_ci}
3241cb0ef41Sopenharmony_cibool GlobalAccessFeedback::immutable() const {
3251cb0ef41Sopenharmony_ci  DCHECK(IsScriptContextSlot());
3261cb0ef41Sopenharmony_ci  return FeedbackNexus::ImmutabilityBit::decode(index_and_immutable_);
3271cb0ef41Sopenharmony_ci}
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_cibase::Optional<ObjectRef> GlobalAccessFeedback::GetConstantHint() const {
3301cb0ef41Sopenharmony_ci  if (IsPropertyCell()) {
3311cb0ef41Sopenharmony_ci    bool cell_cached = property_cell().Cache();
3321cb0ef41Sopenharmony_ci    CHECK(cell_cached);  // Can't fail on the main thread.
3331cb0ef41Sopenharmony_ci    return property_cell().value();
3341cb0ef41Sopenharmony_ci  } else if (IsScriptContextSlot() && immutable()) {
3351cb0ef41Sopenharmony_ci    return script_context().get(slot_index());
3361cb0ef41Sopenharmony_ci  } else {
3371cb0ef41Sopenharmony_ci    return base::nullopt;
3381cb0ef41Sopenharmony_ci  }
3391cb0ef41Sopenharmony_ci}
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ciKeyedAccessMode KeyedAccessMode::FromNexus(FeedbackNexus const& nexus) {
3421cb0ef41Sopenharmony_ci  FeedbackSlotKind kind = nexus.kind();
3431cb0ef41Sopenharmony_ci  if (IsKeyedLoadICKind(kind)) {
3441cb0ef41Sopenharmony_ci    return KeyedAccessMode(AccessMode::kLoad, nexus.GetKeyedAccessLoadMode());
3451cb0ef41Sopenharmony_ci  }
3461cb0ef41Sopenharmony_ci  if (IsKeyedHasICKind(kind)) {
3471cb0ef41Sopenharmony_ci    return KeyedAccessMode(AccessMode::kHas, nexus.GetKeyedAccessLoadMode());
3481cb0ef41Sopenharmony_ci  }
3491cb0ef41Sopenharmony_ci  if (IsDefineKeyedOwnICKind(kind)) {
3501cb0ef41Sopenharmony_ci    return KeyedAccessMode(AccessMode::kDefine,
3511cb0ef41Sopenharmony_ci                           nexus.GetKeyedAccessStoreMode());
3521cb0ef41Sopenharmony_ci  }
3531cb0ef41Sopenharmony_ci  if (IsKeyedStoreICKind(kind)) {
3541cb0ef41Sopenharmony_ci    return KeyedAccessMode(AccessMode::kStore, nexus.GetKeyedAccessStoreMode());
3551cb0ef41Sopenharmony_ci  }
3561cb0ef41Sopenharmony_ci  if (IsStoreInArrayLiteralICKind(kind) ||
3571cb0ef41Sopenharmony_ci      IsDefineKeyedOwnPropertyInLiteralKind(kind)) {
3581cb0ef41Sopenharmony_ci    return KeyedAccessMode(AccessMode::kStoreInLiteral,
3591cb0ef41Sopenharmony_ci                           nexus.GetKeyedAccessStoreMode());
3601cb0ef41Sopenharmony_ci  }
3611cb0ef41Sopenharmony_ci  UNREACHABLE();
3621cb0ef41Sopenharmony_ci}
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ciAccessMode KeyedAccessMode::access_mode() const { return access_mode_; }
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_cibool KeyedAccessMode::IsLoad() const {
3671cb0ef41Sopenharmony_ci  return access_mode_ == AccessMode::kLoad || access_mode_ == AccessMode::kHas;
3681cb0ef41Sopenharmony_ci}
3691cb0ef41Sopenharmony_cibool KeyedAccessMode::IsStore() const {
3701cb0ef41Sopenharmony_ci  return access_mode_ == AccessMode::kStore ||
3711cb0ef41Sopenharmony_ci         access_mode_ == AccessMode::kDefine ||
3721cb0ef41Sopenharmony_ci         access_mode_ == AccessMode::kStoreInLiteral;
3731cb0ef41Sopenharmony_ci}
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ciKeyedAccessLoadMode KeyedAccessMode::load_mode() const {
3761cb0ef41Sopenharmony_ci  CHECK(IsLoad());
3771cb0ef41Sopenharmony_ci  return load_store_mode_.load_mode;
3781cb0ef41Sopenharmony_ci}
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_ciKeyedAccessStoreMode KeyedAccessMode::store_mode() const {
3811cb0ef41Sopenharmony_ci  CHECK(IsStore());
3821cb0ef41Sopenharmony_ci  return load_store_mode_.store_mode;
3831cb0ef41Sopenharmony_ci}
3841cb0ef41Sopenharmony_ci
3851cb0ef41Sopenharmony_ciKeyedAccessMode::LoadStoreMode::LoadStoreMode(KeyedAccessLoadMode load_mode)
3861cb0ef41Sopenharmony_ci    : load_mode(load_mode) {}
3871cb0ef41Sopenharmony_ciKeyedAccessMode::LoadStoreMode::LoadStoreMode(KeyedAccessStoreMode store_mode)
3881cb0ef41Sopenharmony_ci    : store_mode(store_mode) {}
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ciKeyedAccessMode::KeyedAccessMode(AccessMode access_mode,
3911cb0ef41Sopenharmony_ci                                 KeyedAccessLoadMode load_mode)
3921cb0ef41Sopenharmony_ci    : access_mode_(access_mode), load_store_mode_(load_mode) {
3931cb0ef41Sopenharmony_ci  CHECK(!IsStore());
3941cb0ef41Sopenharmony_ci  CHECK(IsLoad());
3951cb0ef41Sopenharmony_ci}
3961cb0ef41Sopenharmony_ciKeyedAccessMode::KeyedAccessMode(AccessMode access_mode,
3971cb0ef41Sopenharmony_ci                                 KeyedAccessStoreMode store_mode)
3981cb0ef41Sopenharmony_ci    : access_mode_(access_mode), load_store_mode_(store_mode) {
3991cb0ef41Sopenharmony_ci  CHECK(!IsLoad());
4001cb0ef41Sopenharmony_ci  CHECK(IsStore());
4011cb0ef41Sopenharmony_ci}
4021cb0ef41Sopenharmony_ci
4031cb0ef41Sopenharmony_ciElementAccessFeedback::ElementAccessFeedback(Zone* zone,
4041cb0ef41Sopenharmony_ci                                             KeyedAccessMode const& keyed_mode,
4051cb0ef41Sopenharmony_ci                                             FeedbackSlotKind slot_kind)
4061cb0ef41Sopenharmony_ci    : ProcessedFeedback(kElementAccess, slot_kind),
4071cb0ef41Sopenharmony_ci      keyed_mode_(keyed_mode),
4081cb0ef41Sopenharmony_ci      transition_groups_(zone) {
4091cb0ef41Sopenharmony_ci  DCHECK(IsKeyedLoadICKind(slot_kind) || IsKeyedHasICKind(slot_kind) ||
4101cb0ef41Sopenharmony_ci         IsDefineKeyedOwnPropertyInLiteralKind(slot_kind) ||
4111cb0ef41Sopenharmony_ci         IsKeyedStoreICKind(slot_kind) ||
4121cb0ef41Sopenharmony_ci         IsStoreInArrayLiteralICKind(slot_kind) ||
4131cb0ef41Sopenharmony_ci         IsDefineKeyedOwnICKind(slot_kind));
4141cb0ef41Sopenharmony_ci}
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_cibool ElementAccessFeedback::HasOnlyStringMaps(JSHeapBroker* broker) const {
4171cb0ef41Sopenharmony_ci  for (auto const& group : transition_groups()) {
4181cb0ef41Sopenharmony_ci    for (Handle<Map> map : group) {
4191cb0ef41Sopenharmony_ci      // We assume a memory fence because {map} was read earlier from
4201cb0ef41Sopenharmony_ci      // the feedback vector and was store ordered on insertion into the
4211cb0ef41Sopenharmony_ci      // vector.
4221cb0ef41Sopenharmony_ci      if (!MakeRefAssumeMemoryFence(broker, map).IsStringMap()) return false;
4231cb0ef41Sopenharmony_ci    }
4241cb0ef41Sopenharmony_ci  }
4251cb0ef41Sopenharmony_ci  return true;
4261cb0ef41Sopenharmony_ci}
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ciNamedAccessFeedback::NamedAccessFeedback(NameRef const& name,
4291cb0ef41Sopenharmony_ci                                         ZoneVector<MapRef> const& maps,
4301cb0ef41Sopenharmony_ci                                         FeedbackSlotKind slot_kind)
4311cb0ef41Sopenharmony_ci    : ProcessedFeedback(kNamedAccess, slot_kind), name_(name), maps_(maps) {
4321cb0ef41Sopenharmony_ci  DCHECK(IsLoadICKind(slot_kind) || IsSetNamedICKind(slot_kind) ||
4331cb0ef41Sopenharmony_ci         IsDefineNamedOwnICKind(slot_kind) || IsKeyedLoadICKind(slot_kind) ||
4341cb0ef41Sopenharmony_ci         IsKeyedHasICKind(slot_kind) || IsKeyedStoreICKind(slot_kind) ||
4351cb0ef41Sopenharmony_ci         IsStoreInArrayLiteralICKind(slot_kind) ||
4361cb0ef41Sopenharmony_ci         IsDefineKeyedOwnPropertyInLiteralKind(slot_kind) ||
4371cb0ef41Sopenharmony_ci         IsDefineKeyedOwnICKind(slot_kind));
4381cb0ef41Sopenharmony_ci}
4391cb0ef41Sopenharmony_ci
4401cb0ef41Sopenharmony_civoid JSHeapBroker::SetFeedback(FeedbackSource const& source,
4411cb0ef41Sopenharmony_ci                               ProcessedFeedback const* feedback) {
4421cb0ef41Sopenharmony_ci  CHECK(source.IsValid());
4431cb0ef41Sopenharmony_ci  auto insertion = feedback_.insert({source, feedback});
4441cb0ef41Sopenharmony_ci  CHECK(insertion.second);
4451cb0ef41Sopenharmony_ci}
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_cibool JSHeapBroker::HasFeedback(FeedbackSource const& source) const {
4481cb0ef41Sopenharmony_ci  DCHECK(source.IsValid());
4491cb0ef41Sopenharmony_ci  return feedback_.find(source) != feedback_.end();
4501cb0ef41Sopenharmony_ci}
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedback(
4531cb0ef41Sopenharmony_ci    FeedbackSource const& source) const {
4541cb0ef41Sopenharmony_ci  DCHECK(source.IsValid());
4551cb0ef41Sopenharmony_ci  auto it = feedback_.find(source);
4561cb0ef41Sopenharmony_ci  CHECK_NE(it, feedback_.end());
4571cb0ef41Sopenharmony_ci  return *it->second;
4581cb0ef41Sopenharmony_ci}
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_ciFeedbackSlotKind JSHeapBroker::GetFeedbackSlotKind(
4611cb0ef41Sopenharmony_ci    FeedbackSource const& source) const {
4621cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source).slot_kind();
4631cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
4641cb0ef41Sopenharmony_ci  return nexus.kind();
4651cb0ef41Sopenharmony_ci}
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_cibool JSHeapBroker::FeedbackIsInsufficient(FeedbackSource const& source) const {
4681cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source).IsInsufficient();
4691cb0ef41Sopenharmony_ci  return FeedbackNexus(source.vector, source.slot, feedback_nexus_config())
4701cb0ef41Sopenharmony_ci      .IsUninitialized();
4711cb0ef41Sopenharmony_ci}
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ciconst ProcessedFeedback& JSHeapBroker::NewInsufficientFeedback(
4741cb0ef41Sopenharmony_ci    FeedbackSlotKind kind) const {
4751cb0ef41Sopenharmony_ci  return *zone()->New<InsufficientFeedback>(kind);
4761cb0ef41Sopenharmony_ci}
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForPropertyAccess(
4791cb0ef41Sopenharmony_ci    FeedbackSource const& source, AccessMode mode,
4801cb0ef41Sopenharmony_ci    base::Optional<NameRef> static_name) {
4811cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
4821cb0ef41Sopenharmony_ci  FeedbackSlotKind kind = nexus.kind();
4831cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(kind);
4841cb0ef41Sopenharmony_ci
4851cb0ef41Sopenharmony_ci  ZoneVector<MapRef> maps(zone());
4861cb0ef41Sopenharmony_ci  {
4871cb0ef41Sopenharmony_ci    std::vector<MapAndHandler> maps_and_handlers_unfiltered;
4881cb0ef41Sopenharmony_ci    nexus.ExtractMapsAndFeedback(&maps_and_handlers_unfiltered);
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci    for (const MapAndHandler& map_and_handler : maps_and_handlers_unfiltered) {
4911cb0ef41Sopenharmony_ci      MapRef map = MakeRefAssumeMemoryFence(this, *map_and_handler.first);
4921cb0ef41Sopenharmony_ci      // May change concurrently at any time - must be guarded by a dependency
4931cb0ef41Sopenharmony_ci      // if non-deprecation is important.
4941cb0ef41Sopenharmony_ci      if (map.is_deprecated()) {
4951cb0ef41Sopenharmony_ci        // TODO(ishell): support fast map updating if we enable it.
4961cb0ef41Sopenharmony_ci        CHECK(!FLAG_fast_map_update);
4971cb0ef41Sopenharmony_ci        base::Optional<Map> maybe_map = MapUpdater::TryUpdateNoLock(
4981cb0ef41Sopenharmony_ci            isolate(), *map.object(), ConcurrencyMode::kConcurrent);
4991cb0ef41Sopenharmony_ci        if (maybe_map.has_value()) {
5001cb0ef41Sopenharmony_ci          map = MakeRefAssumeMemoryFence(this, maybe_map.value());
5011cb0ef41Sopenharmony_ci        } else {
5021cb0ef41Sopenharmony_ci          continue;  // Couldn't update the deprecated map.
5031cb0ef41Sopenharmony_ci        }
5041cb0ef41Sopenharmony_ci      }
5051cb0ef41Sopenharmony_ci      if (map.is_abandoned_prototype_map()) continue;
5061cb0ef41Sopenharmony_ci      maps.push_back(map);
5071cb0ef41Sopenharmony_ci    }
5081cb0ef41Sopenharmony_ci  }
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci  base::Optional<NameRef> name =
5111cb0ef41Sopenharmony_ci      static_name.has_value() ? static_name : GetNameFeedback(nexus);
5121cb0ef41Sopenharmony_ci
5131cb0ef41Sopenharmony_ci  // If no maps were found for a non-megamorphic access, then our maps died
5141cb0ef41Sopenharmony_ci  // and we should soft-deopt.
5151cb0ef41Sopenharmony_ci  if (maps.empty() && nexus.ic_state() != InlineCacheState::MEGAMORPHIC) {
5161cb0ef41Sopenharmony_ci    return NewInsufficientFeedback(kind);
5171cb0ef41Sopenharmony_ci  }
5181cb0ef41Sopenharmony_ci
5191cb0ef41Sopenharmony_ci  if (name.has_value()) {
5201cb0ef41Sopenharmony_ci    // We rely on this invariant in JSGenericLowering.
5211cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(maps.empty(),
5221cb0ef41Sopenharmony_ci                   nexus.ic_state() == InlineCacheState::MEGAMORPHIC);
5231cb0ef41Sopenharmony_ci    return *zone()->New<NamedAccessFeedback>(*name, maps, kind);
5241cb0ef41Sopenharmony_ci  } else if (nexus.GetKeyType() == IcCheckType::kElement && !maps.empty()) {
5251cb0ef41Sopenharmony_ci    return ProcessFeedbackMapsForElementAccess(
5261cb0ef41Sopenharmony_ci        maps, KeyedAccessMode::FromNexus(nexus), kind);
5271cb0ef41Sopenharmony_ci  } else {
5281cb0ef41Sopenharmony_ci    // No actionable feedback.
5291cb0ef41Sopenharmony_ci    DCHECK(maps.empty());
5301cb0ef41Sopenharmony_ci    DCHECK_EQ(nexus.ic_state(), InlineCacheState::MEGAMORPHIC);
5311cb0ef41Sopenharmony_ci    // TODO(neis): Using ElementAccessFeedback here is kind of an abuse.
5321cb0ef41Sopenharmony_ci    return *zone()->New<ElementAccessFeedback>(
5331cb0ef41Sopenharmony_ci        zone(), KeyedAccessMode::FromNexus(nexus), kind);
5341cb0ef41Sopenharmony_ci  }
5351cb0ef41Sopenharmony_ci}
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForGlobalAccess(
5381cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
5391cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
5401cb0ef41Sopenharmony_ci  DCHECK(nexus.kind() == FeedbackSlotKind::kLoadGlobalInsideTypeof ||
5411cb0ef41Sopenharmony_ci         nexus.kind() == FeedbackSlotKind::kLoadGlobalNotInsideTypeof ||
5421cb0ef41Sopenharmony_ci         nexus.kind() == FeedbackSlotKind::kStoreGlobalSloppy ||
5431cb0ef41Sopenharmony_ci         nexus.kind() == FeedbackSlotKind::kStoreGlobalStrict);
5441cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
5451cb0ef41Sopenharmony_ci  if (nexus.ic_state() != InlineCacheState::MONOMORPHIC ||
5461cb0ef41Sopenharmony_ci      nexus.GetFeedback()->IsCleared()) {
5471cb0ef41Sopenharmony_ci    return *zone()->New<GlobalAccessFeedback>(nexus.kind());
5481cb0ef41Sopenharmony_ci  }
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  Handle<Object> feedback_value =
5511cb0ef41Sopenharmony_ci      CanonicalPersistentHandle(nexus.GetFeedback()->GetHeapObjectOrSmi());
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  if (feedback_value->IsSmi()) {
5541cb0ef41Sopenharmony_ci    // The wanted name belongs to a script-scope variable and the feedback
5551cb0ef41Sopenharmony_ci    // tells us where to find its value.
5561cb0ef41Sopenharmony_ci    int const number = feedback_value->Number();
5571cb0ef41Sopenharmony_ci    int const script_context_index =
5581cb0ef41Sopenharmony_ci        FeedbackNexus::ContextIndexBits::decode(number);
5591cb0ef41Sopenharmony_ci    int const context_slot_index = FeedbackNexus::SlotIndexBits::decode(number);
5601cb0ef41Sopenharmony_ci    ContextRef context = MakeRefAssumeMemoryFence(
5611cb0ef41Sopenharmony_ci        this,
5621cb0ef41Sopenharmony_ci        target_native_context().script_context_table().object()->get_context(
5631cb0ef41Sopenharmony_ci            script_context_index, kAcquireLoad));
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci    base::Optional<ObjectRef> contents = context.get(context_slot_index);
5661cb0ef41Sopenharmony_ci    if (contents.has_value()) CHECK(!contents->IsTheHole());
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci    return *zone()->New<GlobalAccessFeedback>(
5691cb0ef41Sopenharmony_ci        context, context_slot_index,
5701cb0ef41Sopenharmony_ci        FeedbackNexus::ImmutabilityBit::decode(number), nexus.kind());
5711cb0ef41Sopenharmony_ci  }
5721cb0ef41Sopenharmony_ci
5731cb0ef41Sopenharmony_ci  CHECK(feedback_value->IsPropertyCell());
5741cb0ef41Sopenharmony_ci  // The wanted name belongs (or did belong) to a property on the global
5751cb0ef41Sopenharmony_ci  // object and the feedback is the cell holding its value.
5761cb0ef41Sopenharmony_ci  return *zone()->New<GlobalAccessFeedback>(
5771cb0ef41Sopenharmony_ci      MakeRefAssumeMemoryFence(this,
5781cb0ef41Sopenharmony_ci                               Handle<PropertyCell>::cast(feedback_value)),
5791cb0ef41Sopenharmony_ci      nexus.kind());
5801cb0ef41Sopenharmony_ci}
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForBinaryOperation(
5831cb0ef41Sopenharmony_ci    FeedbackSource const& source) const {
5841cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
5851cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
5861cb0ef41Sopenharmony_ci  BinaryOperationHint hint = nexus.GetBinaryOperationFeedback();
5871cb0ef41Sopenharmony_ci  DCHECK_NE(hint, BinaryOperationHint::kNone);  // Not uninitialized.
5881cb0ef41Sopenharmony_ci  return *zone()->New<BinaryOperationFeedback>(hint, nexus.kind());
5891cb0ef41Sopenharmony_ci}
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForCompareOperation(
5921cb0ef41Sopenharmony_ci    FeedbackSource const& source) const {
5931cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
5941cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
5951cb0ef41Sopenharmony_ci  CompareOperationHint hint = nexus.GetCompareOperationFeedback();
5961cb0ef41Sopenharmony_ci  DCHECK_NE(hint, CompareOperationHint::kNone);  // Not uninitialized.
5971cb0ef41Sopenharmony_ci  return *zone()->New<CompareOperationFeedback>(hint, nexus.kind());
5981cb0ef41Sopenharmony_ci}
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForForIn(
6011cb0ef41Sopenharmony_ci    FeedbackSource const& source) const {
6021cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6031cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6041cb0ef41Sopenharmony_ci  ForInHint hint = nexus.GetForInFeedback();
6051cb0ef41Sopenharmony_ci  DCHECK_NE(hint, ForInHint::kNone);  // Not uninitialized.
6061cb0ef41Sopenharmony_ci  return *zone()->New<ForInFeedback>(hint, nexus.kind());
6071cb0ef41Sopenharmony_ci}
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForInstanceOf(
6101cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6111cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6121cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ci  base::Optional<JSObjectRef> optional_constructor;
6151cb0ef41Sopenharmony_ci  {
6161cb0ef41Sopenharmony_ci    MaybeHandle<JSObject> maybe_constructor = nexus.GetConstructorFeedback();
6171cb0ef41Sopenharmony_ci    Handle<JSObject> constructor;
6181cb0ef41Sopenharmony_ci    if (maybe_constructor.ToHandle(&constructor)) {
6191cb0ef41Sopenharmony_ci      optional_constructor = MakeRefAssumeMemoryFence(this, *constructor);
6201cb0ef41Sopenharmony_ci    }
6211cb0ef41Sopenharmony_ci  }
6221cb0ef41Sopenharmony_ci  return *zone()->New<InstanceOfFeedback>(optional_constructor, nexus.kind());
6231cb0ef41Sopenharmony_ci}
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForArrayOrObjectLiteral(
6261cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6271cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6281cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci  HeapObject object;
6311cb0ef41Sopenharmony_ci  if (!nexus.GetFeedback()->GetHeapObject(&object)) {
6321cb0ef41Sopenharmony_ci    return NewInsufficientFeedback(nexus.kind());
6331cb0ef41Sopenharmony_ci  }
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ci  AllocationSiteRef site =
6361cb0ef41Sopenharmony_ci      MakeRefAssumeMemoryFence(this, AllocationSite::cast(object));
6371cb0ef41Sopenharmony_ci  return *zone()->New<LiteralFeedback>(site, nexus.kind());
6381cb0ef41Sopenharmony_ci}
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForRegExpLiteral(
6411cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6421cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6431cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ci  HeapObject object;
6461cb0ef41Sopenharmony_ci  if (!nexus.GetFeedback()->GetHeapObject(&object)) {
6471cb0ef41Sopenharmony_ci    return NewInsufficientFeedback(nexus.kind());
6481cb0ef41Sopenharmony_ci  }
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci  RegExpBoilerplateDescriptionRef boilerplate = MakeRefAssumeMemoryFence(
6511cb0ef41Sopenharmony_ci      this, RegExpBoilerplateDescription::cast(object));
6521cb0ef41Sopenharmony_ci  return *zone()->New<RegExpLiteralFeedback>(boilerplate, nexus.kind());
6531cb0ef41Sopenharmony_ci}
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForTemplateObject(
6561cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6571cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6581cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci  HeapObject object;
6611cb0ef41Sopenharmony_ci  if (!nexus.GetFeedback()->GetHeapObject(&object)) {
6621cb0ef41Sopenharmony_ci    return NewInsufficientFeedback(nexus.kind());
6631cb0ef41Sopenharmony_ci  }
6641cb0ef41Sopenharmony_ci
6651cb0ef41Sopenharmony_ci  JSArrayRef array = MakeRefAssumeMemoryFence(this, JSArray::cast(object));
6661cb0ef41Sopenharmony_ci  return *zone()->New<TemplateObjectFeedback>(array, nexus.kind());
6671cb0ef41Sopenharmony_ci}
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ReadFeedbackForCall(
6701cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6711cb0ef41Sopenharmony_ci  FeedbackNexus nexus(source.vector, source.slot, feedback_nexus_config());
6721cb0ef41Sopenharmony_ci  if (nexus.IsUninitialized()) return NewInsufficientFeedback(nexus.kind());
6731cb0ef41Sopenharmony_ci
6741cb0ef41Sopenharmony_ci  base::Optional<HeapObjectRef> target_ref;
6751cb0ef41Sopenharmony_ci  {
6761cb0ef41Sopenharmony_ci    MaybeObject maybe_target = nexus.GetFeedback();
6771cb0ef41Sopenharmony_ci    HeapObject target_object;
6781cb0ef41Sopenharmony_ci    if (maybe_target->GetHeapObject(&target_object)) {
6791cb0ef41Sopenharmony_ci      target_ref = MakeRefAssumeMemoryFence(this, target_object);
6801cb0ef41Sopenharmony_ci    }
6811cb0ef41Sopenharmony_ci  }
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci  float frequency = nexus.ComputeCallFrequency();
6841cb0ef41Sopenharmony_ci  SpeculationMode mode = nexus.GetSpeculationMode();
6851cb0ef41Sopenharmony_ci  CallFeedbackContent content = nexus.GetCallFeedbackContent();
6861cb0ef41Sopenharmony_ci  return *zone()->New<CallFeedback>(target_ref, frequency, mode, content,
6871cb0ef41Sopenharmony_ci                                    nexus.kind());
6881cb0ef41Sopenharmony_ci}
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ciBinaryOperationHint JSHeapBroker::GetFeedbackForBinaryOperation(
6911cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6921cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ProcessFeedbackForBinaryOperation(source);
6931cb0ef41Sopenharmony_ci  return feedback.IsInsufficient() ? BinaryOperationHint::kNone
6941cb0ef41Sopenharmony_ci                                   : feedback.AsBinaryOperation().value();
6951cb0ef41Sopenharmony_ci}
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ciCompareOperationHint JSHeapBroker::GetFeedbackForCompareOperation(
6981cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
6991cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
7001cb0ef41Sopenharmony_ci      ProcessFeedbackForCompareOperation(source);
7011cb0ef41Sopenharmony_ci  return feedback.IsInsufficient() ? CompareOperationHint::kNone
7021cb0ef41Sopenharmony_ci                                   : feedback.AsCompareOperation().value();
7031cb0ef41Sopenharmony_ci}
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ciForInHint JSHeapBroker::GetFeedbackForForIn(FeedbackSource const& source) {
7061cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ProcessFeedbackForForIn(source);
7071cb0ef41Sopenharmony_ci  return feedback.IsInsufficient() ? ForInHint::kNone
7081cb0ef41Sopenharmony_ci                                   : feedback.AsForIn().value();
7091cb0ef41Sopenharmony_ci}
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForArrayOrObjectLiteral(
7121cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7131cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7141cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
7151cb0ef41Sopenharmony_ci      ReadFeedbackForArrayOrObjectLiteral(source);
7161cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7171cb0ef41Sopenharmony_ci  return feedback;
7181cb0ef41Sopenharmony_ci}
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForRegExpLiteral(
7211cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7221cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7231cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForRegExpLiteral(source);
7241cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7251cb0ef41Sopenharmony_ci  return feedback;
7261cb0ef41Sopenharmony_ci}
7271cb0ef41Sopenharmony_ci
7281cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForTemplateObject(
7291cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7301cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7311cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForTemplateObject(source);
7321cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7331cb0ef41Sopenharmony_ci  return feedback;
7341cb0ef41Sopenharmony_ci}
7351cb0ef41Sopenharmony_ci
7361cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ProcessFeedbackForBinaryOperation(
7371cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7381cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7391cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForBinaryOperation(source);
7401cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7411cb0ef41Sopenharmony_ci  return feedback;
7421cb0ef41Sopenharmony_ci}
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ProcessFeedbackForCompareOperation(
7451cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7461cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7471cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForCompareOperation(source);
7481cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7491cb0ef41Sopenharmony_ci  return feedback;
7501cb0ef41Sopenharmony_ci}
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::ProcessFeedbackForForIn(
7531cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7541cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7551cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForForIn(source);
7561cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7571cb0ef41Sopenharmony_ci  return feedback;
7581cb0ef41Sopenharmony_ci}
7591cb0ef41Sopenharmony_ci
7601cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForPropertyAccess(
7611cb0ef41Sopenharmony_ci    FeedbackSource const& source, AccessMode mode,
7621cb0ef41Sopenharmony_ci    base::Optional<NameRef> static_name) {
7631cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7641cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
7651cb0ef41Sopenharmony_ci      ReadFeedbackForPropertyAccess(source, mode, static_name);
7661cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7671cb0ef41Sopenharmony_ci  return feedback;
7681cb0ef41Sopenharmony_ci}
7691cb0ef41Sopenharmony_ci
7701cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForInstanceOf(
7711cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7721cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7731cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForInstanceOf(source);
7741cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7751cb0ef41Sopenharmony_ci  return feedback;
7761cb0ef41Sopenharmony_ci}
7771cb0ef41Sopenharmony_ci
7781cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForCall(
7791cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7801cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7811cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForCall(source);
7821cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7831cb0ef41Sopenharmony_ci  return feedback;
7841cb0ef41Sopenharmony_ci}
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_ciProcessedFeedback const& JSHeapBroker::GetFeedbackForGlobalAccess(
7871cb0ef41Sopenharmony_ci    FeedbackSource const& source) {
7881cb0ef41Sopenharmony_ci  if (HasFeedback(source)) return GetFeedback(source);
7891cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback = ReadFeedbackForGlobalAccess(source);
7901cb0ef41Sopenharmony_ci  SetFeedback(source, &feedback);
7911cb0ef41Sopenharmony_ci  return feedback;
7921cb0ef41Sopenharmony_ci}
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ciElementAccessFeedback const& JSHeapBroker::ProcessFeedbackMapsForElementAccess(
7951cb0ef41Sopenharmony_ci    ZoneVector<MapRef>& maps, KeyedAccessMode const& keyed_mode,
7961cb0ef41Sopenharmony_ci    FeedbackSlotKind slot_kind) {
7971cb0ef41Sopenharmony_ci  DCHECK(!maps.empty());
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  // Collect possible transition targets.
8001cb0ef41Sopenharmony_ci  MapHandles possible_transition_targets;
8011cb0ef41Sopenharmony_ci  possible_transition_targets.reserve(maps.size());
8021cb0ef41Sopenharmony_ci  for (MapRef& map : maps) {
8031cb0ef41Sopenharmony_ci    if (map.CanInlineElementAccess() &&
8041cb0ef41Sopenharmony_ci        IsFastElementsKind(map.elements_kind()) &&
8051cb0ef41Sopenharmony_ci        GetInitialFastElementsKind() != map.elements_kind()) {
8061cb0ef41Sopenharmony_ci      possible_transition_targets.push_back(map.object());
8071cb0ef41Sopenharmony_ci    }
8081cb0ef41Sopenharmony_ci  }
8091cb0ef41Sopenharmony_ci
8101cb0ef41Sopenharmony_ci  using TransitionGroup = ElementAccessFeedback::TransitionGroup;
8111cb0ef41Sopenharmony_ci  struct HandleLess {
8121cb0ef41Sopenharmony_ci    bool operator()(Handle<Map> x, Handle<Map> y) const {
8131cb0ef41Sopenharmony_ci      return x.address() < y.address();
8141cb0ef41Sopenharmony_ci    }
8151cb0ef41Sopenharmony_ci  };
8161cb0ef41Sopenharmony_ci  ZoneMap<Handle<Map>, TransitionGroup, HandleLess> transition_groups(zone());
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci  // Separate the actual receiver maps and the possible transition sources.
8191cb0ef41Sopenharmony_ci  for (const MapRef& map : maps) {
8201cb0ef41Sopenharmony_ci    Map transition_target;
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci    // Don't generate elements kind transitions from stable maps.
8231cb0ef41Sopenharmony_ci    if (!map.is_stable()) {
8241cb0ef41Sopenharmony_ci      // The lock is needed for UnusedPropertyFields (called deep inside
8251cb0ef41Sopenharmony_ci      // FindElementsKindTransitionedMap).
8261cb0ef41Sopenharmony_ci      MapUpdaterGuardIfNeeded mumd_scope(this);
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci      transition_target = map.object()->FindElementsKindTransitionedMap(
8291cb0ef41Sopenharmony_ci          isolate(), possible_transition_targets, ConcurrencyMode::kConcurrent);
8301cb0ef41Sopenharmony_ci    }
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci    if (transition_target.is_null()) {
8331cb0ef41Sopenharmony_ci      TransitionGroup group(1, map.object(), zone());
8341cb0ef41Sopenharmony_ci      transition_groups.insert({map.object(), group});
8351cb0ef41Sopenharmony_ci    } else {
8361cb0ef41Sopenharmony_ci      Handle<Map> target = CanonicalPersistentHandle(transition_target);
8371cb0ef41Sopenharmony_ci      TransitionGroup new_group(1, target, zone());
8381cb0ef41Sopenharmony_ci      TransitionGroup& actual_group =
8391cb0ef41Sopenharmony_ci          transition_groups.insert({target, new_group}).first->second;
8401cb0ef41Sopenharmony_ci      actual_group.push_back(map.object());
8411cb0ef41Sopenharmony_ci    }
8421cb0ef41Sopenharmony_ci  }
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ci  ElementAccessFeedback* result =
8451cb0ef41Sopenharmony_ci      zone()->New<ElementAccessFeedback>(zone(), keyed_mode, slot_kind);
8461cb0ef41Sopenharmony_ci  for (auto entry : transition_groups) {
8471cb0ef41Sopenharmony_ci    result->AddGroup(std::move(entry.second));
8481cb0ef41Sopenharmony_ci  }
8491cb0ef41Sopenharmony_ci
8501cb0ef41Sopenharmony_ci  CHECK(!result->transition_groups().empty());
8511cb0ef41Sopenharmony_ci  return *result;
8521cb0ef41Sopenharmony_ci}
8531cb0ef41Sopenharmony_ci
8541cb0ef41Sopenharmony_civoid ElementAccessFeedback::AddGroup(TransitionGroup&& group) {
8551cb0ef41Sopenharmony_ci  CHECK(!group.empty());
8561cb0ef41Sopenharmony_ci  transition_groups_.push_back(std::move(group));
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci#ifdef ENABLE_SLOW_DCHECKS
8591cb0ef41Sopenharmony_ci  // Check that each of the group's maps occurs exactly once in the whole
8601cb0ef41Sopenharmony_ci  // feedback. This implies that "a source is not a target".
8611cb0ef41Sopenharmony_ci  for (Handle<Map> map : group) {
8621cb0ef41Sopenharmony_ci    int count = 0;
8631cb0ef41Sopenharmony_ci    for (TransitionGroup const& some_group : transition_groups()) {
8641cb0ef41Sopenharmony_ci      count += std::count_if(
8651cb0ef41Sopenharmony_ci          some_group.begin(), some_group.end(),
8661cb0ef41Sopenharmony_ci          [&](Handle<Map> some_map) { return some_map.equals(map); });
8671cb0ef41Sopenharmony_ci    }
8681cb0ef41Sopenharmony_ci    CHECK_EQ(count, 1);
8691cb0ef41Sopenharmony_ci  }
8701cb0ef41Sopenharmony_ci#endif
8711cb0ef41Sopenharmony_ci}
8721cb0ef41Sopenharmony_ci
8731cb0ef41Sopenharmony_cibase::Optional<NameRef> JSHeapBroker::GetNameFeedback(
8741cb0ef41Sopenharmony_ci    FeedbackNexus const& nexus) {
8751cb0ef41Sopenharmony_ci  Name raw_name = nexus.GetName();
8761cb0ef41Sopenharmony_ci  if (raw_name.is_null()) return base::nullopt;
8771cb0ef41Sopenharmony_ci  return MakeRefAssumeMemoryFence(this, raw_name);
8781cb0ef41Sopenharmony_ci}
8791cb0ef41Sopenharmony_ci
8801cb0ef41Sopenharmony_ciPropertyAccessInfo JSHeapBroker::GetPropertyAccessInfo(
8811cb0ef41Sopenharmony_ci    MapRef map, NameRef name, AccessMode access_mode,
8821cb0ef41Sopenharmony_ci    CompilationDependencies* dependencies) {
8831cb0ef41Sopenharmony_ci  DCHECK_NOT_NULL(dependencies);
8841cb0ef41Sopenharmony_ci
8851cb0ef41Sopenharmony_ci  PropertyAccessTarget target({map, name, access_mode});
8861cb0ef41Sopenharmony_ci  auto it = property_access_infos_.find(target);
8871cb0ef41Sopenharmony_ci  if (it != property_access_infos_.end()) return it->second;
8881cb0ef41Sopenharmony_ci
8891cb0ef41Sopenharmony_ci  AccessInfoFactory factory(this, dependencies, zone());
8901cb0ef41Sopenharmony_ci  PropertyAccessInfo access_info =
8911cb0ef41Sopenharmony_ci      factory.ComputePropertyAccessInfo(map, name, access_mode);
8921cb0ef41Sopenharmony_ci  TRACE(this, "Storing PropertyAccessInfo for "
8931cb0ef41Sopenharmony_ci                  << access_mode << " of property " << name << " on map "
8941cb0ef41Sopenharmony_ci                  << map);
8951cb0ef41Sopenharmony_ci  property_access_infos_.insert({target, access_info});
8961cb0ef41Sopenharmony_ci  return access_info;
8971cb0ef41Sopenharmony_ci}
8981cb0ef41Sopenharmony_ci
8991cb0ef41Sopenharmony_ciBinaryOperationFeedback const& ProcessedFeedback::AsBinaryOperation() const {
9001cb0ef41Sopenharmony_ci  CHECK_EQ(kBinaryOperation, kind());
9011cb0ef41Sopenharmony_ci  return *static_cast<BinaryOperationFeedback const*>(this);
9021cb0ef41Sopenharmony_ci}
9031cb0ef41Sopenharmony_ci
9041cb0ef41Sopenharmony_ciCallFeedback const& ProcessedFeedback::AsCall() const {
9051cb0ef41Sopenharmony_ci  CHECK_EQ(kCall, kind());
9061cb0ef41Sopenharmony_ci  return *static_cast<CallFeedback const*>(this);
9071cb0ef41Sopenharmony_ci}
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_ciCompareOperationFeedback const& ProcessedFeedback::AsCompareOperation() const {
9101cb0ef41Sopenharmony_ci  CHECK_EQ(kCompareOperation, kind());
9111cb0ef41Sopenharmony_ci  return *static_cast<CompareOperationFeedback const*>(this);
9121cb0ef41Sopenharmony_ci}
9131cb0ef41Sopenharmony_ci
9141cb0ef41Sopenharmony_ciElementAccessFeedback const& ProcessedFeedback::AsElementAccess() const {
9151cb0ef41Sopenharmony_ci  CHECK_EQ(kElementAccess, kind());
9161cb0ef41Sopenharmony_ci  return *static_cast<ElementAccessFeedback const*>(this);
9171cb0ef41Sopenharmony_ci}
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ciForInFeedback const& ProcessedFeedback::AsForIn() const {
9201cb0ef41Sopenharmony_ci  CHECK_EQ(kForIn, kind());
9211cb0ef41Sopenharmony_ci  return *static_cast<ForInFeedback const*>(this);
9221cb0ef41Sopenharmony_ci}
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ciGlobalAccessFeedback const& ProcessedFeedback::AsGlobalAccess() const {
9251cb0ef41Sopenharmony_ci  CHECK_EQ(kGlobalAccess, kind());
9261cb0ef41Sopenharmony_ci  return *static_cast<GlobalAccessFeedback const*>(this);
9271cb0ef41Sopenharmony_ci}
9281cb0ef41Sopenharmony_ci
9291cb0ef41Sopenharmony_ciInstanceOfFeedback const& ProcessedFeedback::AsInstanceOf() const {
9301cb0ef41Sopenharmony_ci  CHECK_EQ(kInstanceOf, kind());
9311cb0ef41Sopenharmony_ci  return *static_cast<InstanceOfFeedback const*>(this);
9321cb0ef41Sopenharmony_ci}
9331cb0ef41Sopenharmony_ci
9341cb0ef41Sopenharmony_ciNamedAccessFeedback const& ProcessedFeedback::AsNamedAccess() const {
9351cb0ef41Sopenharmony_ci  CHECK_EQ(kNamedAccess, kind());
9361cb0ef41Sopenharmony_ci  return *static_cast<NamedAccessFeedback const*>(this);
9371cb0ef41Sopenharmony_ci}
9381cb0ef41Sopenharmony_ci
9391cb0ef41Sopenharmony_ciLiteralFeedback const& ProcessedFeedback::AsLiteral() const {
9401cb0ef41Sopenharmony_ci  CHECK_EQ(kLiteral, kind());
9411cb0ef41Sopenharmony_ci  return *static_cast<LiteralFeedback const*>(this);
9421cb0ef41Sopenharmony_ci}
9431cb0ef41Sopenharmony_ci
9441cb0ef41Sopenharmony_ciRegExpLiteralFeedback const& ProcessedFeedback::AsRegExpLiteral() const {
9451cb0ef41Sopenharmony_ci  CHECK_EQ(kRegExpLiteral, kind());
9461cb0ef41Sopenharmony_ci  return *static_cast<RegExpLiteralFeedback const*>(this);
9471cb0ef41Sopenharmony_ci}
9481cb0ef41Sopenharmony_ci
9491cb0ef41Sopenharmony_ciTemplateObjectFeedback const& ProcessedFeedback::AsTemplateObject() const {
9501cb0ef41Sopenharmony_ci  CHECK_EQ(kTemplateObject, kind());
9511cb0ef41Sopenharmony_ci  return *static_cast<TemplateObjectFeedback const*>(this);
9521cb0ef41Sopenharmony_ci}
9531cb0ef41Sopenharmony_ci
9541cb0ef41Sopenharmony_ci#undef TRACE
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci}  // namespace compiler
9571cb0ef41Sopenharmony_ci}  // namespace internal
9581cb0ef41Sopenharmony_ci}  // namespace v8
959