11cb0ef41Sopenharmony_ci// Copyright 2015 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/compilation-dependencies.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/base/optional.h"
81cb0ef41Sopenharmony_ci#include "src/execution/protectors.h"
91cb0ef41Sopenharmony_ci#include "src/handles/handles-inl.h"
101cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h"
111cb0ef41Sopenharmony_ci#include "src/objects/internal-index.h"
121cb0ef41Sopenharmony_ci#include "src/objects/js-array-inl.h"
131cb0ef41Sopenharmony_ci#include "src/objects/js-function-inl.h"
141cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
151cb0ef41Sopenharmony_ci#include "src/zone/zone-handle-set.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace v8 {
181cb0ef41Sopenharmony_cinamespace internal {
191cb0ef41Sopenharmony_cinamespace compiler {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci#define DEPENDENCY_LIST(V)              \
221cb0ef41Sopenharmony_ci  V(ConsistentJSFunctionView)           \
231cb0ef41Sopenharmony_ci  V(ConstantInDictionaryPrototypeChain) \
241cb0ef41Sopenharmony_ci  V(ElementsKind)                       \
251cb0ef41Sopenharmony_ci  V(FieldConstness)                     \
261cb0ef41Sopenharmony_ci  V(FieldRepresentation)                \
271cb0ef41Sopenharmony_ci  V(FieldType)                          \
281cb0ef41Sopenharmony_ci  V(GlobalProperty)                     \
291cb0ef41Sopenharmony_ci  V(InitialMap)                         \
301cb0ef41Sopenharmony_ci  V(InitialMapInstanceSizePrediction)   \
311cb0ef41Sopenharmony_ci  V(OwnConstantDataProperty)            \
321cb0ef41Sopenharmony_ci  V(OwnConstantDictionaryProperty)      \
331cb0ef41Sopenharmony_ci  V(OwnConstantElement)                 \
341cb0ef41Sopenharmony_ci  V(PretenureMode)                      \
351cb0ef41Sopenharmony_ci  V(Protector)                          \
361cb0ef41Sopenharmony_ci  V(PrototypeProperty)                  \
371cb0ef41Sopenharmony_ci  V(StableMap)                          \
381cb0ef41Sopenharmony_ci  V(Transition)                         \
391cb0ef41Sopenharmony_ci  V(ObjectSlotValue)
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciCompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
421cb0ef41Sopenharmony_ci                                                 Zone* zone)
431cb0ef41Sopenharmony_ci    : zone_(zone), broker_(broker), dependencies_(zone) {
441cb0ef41Sopenharmony_ci  broker->set_dependencies(this);
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_cinamespace {
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_cienum CompilationDependencyKind {
501cb0ef41Sopenharmony_ci#define V(Name) k##Name,
511cb0ef41Sopenharmony_ci  DEPENDENCY_LIST(V)
521cb0ef41Sopenharmony_ci#undef V
531cb0ef41Sopenharmony_ci};
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci#define V(Name) class Name##Dependency;
561cb0ef41Sopenharmony_ciDEPENDENCY_LIST(V)
571cb0ef41Sopenharmony_ci#undef V
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciconst char* CompilationDependencyKindToString(CompilationDependencyKind kind) {
601cb0ef41Sopenharmony_ci#define V(Name) #Name "Dependency",
611cb0ef41Sopenharmony_ci  static const char* const names[] = {DEPENDENCY_LIST(V)};
621cb0ef41Sopenharmony_ci#undef V
631cb0ef41Sopenharmony_ci  return names[kind];
641cb0ef41Sopenharmony_ci}
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ciclass PendingDependencies;
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci}  // namespace
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciclass CompilationDependency : public ZoneObject {
711cb0ef41Sopenharmony_ci public:
721cb0ef41Sopenharmony_ci  explicit CompilationDependency(CompilationDependencyKind kind) : kind(kind) {}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci  virtual bool IsValid() const = 0;
751cb0ef41Sopenharmony_ci  virtual void PrepareInstall() const {}
761cb0ef41Sopenharmony_ci  virtual void Install(PendingDependencies* deps) const = 0;
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci#define V(Name)                                     \
791cb0ef41Sopenharmony_ci  bool Is##Name() const { return kind == k##Name; } \
801cb0ef41Sopenharmony_ci  V8_ALLOW_UNUSED const Name##Dependency* As##Name() const;
811cb0ef41Sopenharmony_ci  DEPENDENCY_LIST(V)
821cb0ef41Sopenharmony_ci#undef V
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  const char* ToString() const {
851cb0ef41Sopenharmony_ci    return CompilationDependencyKindToString(kind);
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  const CompilationDependencyKind kind;
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci private:
911cb0ef41Sopenharmony_ci  virtual size_t Hash() const = 0;
921cb0ef41Sopenharmony_ci  virtual bool Equals(const CompilationDependency* that) const = 0;
931cb0ef41Sopenharmony_ci  friend struct CompilationDependencies::CompilationDependencyHash;
941cb0ef41Sopenharmony_ci  friend struct CompilationDependencies::CompilationDependencyEqual;
951cb0ef41Sopenharmony_ci};
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_cisize_t CompilationDependencies::CompilationDependencyHash::operator()(
981cb0ef41Sopenharmony_ci    const CompilationDependency* dep) const {
991cb0ef41Sopenharmony_ci  return base::hash_combine(dep->kind, dep->Hash());
1001cb0ef41Sopenharmony_ci}
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_cibool CompilationDependencies::CompilationDependencyEqual::operator()(
1031cb0ef41Sopenharmony_ci    const CompilationDependency* lhs, const CompilationDependency* rhs) const {
1041cb0ef41Sopenharmony_ci  return lhs->kind == rhs->kind && lhs->Equals(rhs);
1051cb0ef41Sopenharmony_ci}
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_cinamespace {
1081cb0ef41Sopenharmony_ci
1091cb0ef41Sopenharmony_ci// Dependencies can only be fully deduplicated immediately prior to
1101cb0ef41Sopenharmony_ci// installation (because PrepareInstall may create the object on which the dep
1111cb0ef41Sopenharmony_ci// will be installed). We gather and dedupe deps in this class, and install
1121cb0ef41Sopenharmony_ci// them from here.
1131cb0ef41Sopenharmony_ciclass PendingDependencies final {
1141cb0ef41Sopenharmony_ci public:
1151cb0ef41Sopenharmony_ci  explicit PendingDependencies(Zone* zone) : deps_(zone) {}
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  void Register(Handle<HeapObject> object,
1181cb0ef41Sopenharmony_ci                DependentCode::DependencyGroup group) {
1191cb0ef41Sopenharmony_ci    deps_[object] |= group;
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  void InstallAll(Isolate* isolate, Handle<Code> code) {
1231cb0ef41Sopenharmony_ci    if (V8_UNLIKELY(FLAG_predictable)) {
1241cb0ef41Sopenharmony_ci      InstallAllPredictable(isolate, code);
1251cb0ef41Sopenharmony_ci      return;
1261cb0ef41Sopenharmony_ci    }
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci    // With deduplication done we no longer rely on the object address for
1291cb0ef41Sopenharmony_ci    // hashing.
1301cb0ef41Sopenharmony_ci    AllowGarbageCollection yes_gc;
1311cb0ef41Sopenharmony_ci    for (const auto& o_and_g : deps_) {
1321cb0ef41Sopenharmony_ci      DependentCode::InstallDependency(isolate, code, o_and_g.first,
1331cb0ef41Sopenharmony_ci                                       o_and_g.second);
1341cb0ef41Sopenharmony_ci    }
1351cb0ef41Sopenharmony_ci  }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  void InstallAllPredictable(Isolate* isolate, Handle<Code> code) {
1381cb0ef41Sopenharmony_ci    CHECK(FLAG_predictable);
1391cb0ef41Sopenharmony_ci    // First, guarantee predictable iteration order.
1401cb0ef41Sopenharmony_ci    using HandleAndGroup =
1411cb0ef41Sopenharmony_ci        std::pair<Handle<HeapObject>, DependentCode::DependencyGroups>;
1421cb0ef41Sopenharmony_ci    std::vector<HandleAndGroup> entries(deps_.begin(), deps_.end());
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci    std::sort(entries.begin(), entries.end(),
1451cb0ef41Sopenharmony_ci              [](const HandleAndGroup& lhs, const HandleAndGroup& rhs) {
1461cb0ef41Sopenharmony_ci                return lhs.first->ptr() < rhs.first->ptr();
1471cb0ef41Sopenharmony_ci              });
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci    // With deduplication done we no longer rely on the object address for
1501cb0ef41Sopenharmony_ci    // hashing.
1511cb0ef41Sopenharmony_ci    AllowGarbageCollection yes_gc;
1521cb0ef41Sopenharmony_ci    for (const auto& o_and_g : entries) {
1531cb0ef41Sopenharmony_ci      DependentCode::InstallDependency(isolate, code, o_and_g.first,
1541cb0ef41Sopenharmony_ci                                       o_and_g.second);
1551cb0ef41Sopenharmony_ci    }
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci private:
1591cb0ef41Sopenharmony_ci  struct HandleHash {
1601cb0ef41Sopenharmony_ci    size_t operator()(const Handle<HeapObject>& x) const {
1611cb0ef41Sopenharmony_ci      return static_cast<size_t>(x->ptr());
1621cb0ef41Sopenharmony_ci    }
1631cb0ef41Sopenharmony_ci  };
1641cb0ef41Sopenharmony_ci  struct HandleEqual {
1651cb0ef41Sopenharmony_ci    bool operator()(const Handle<HeapObject>& lhs,
1661cb0ef41Sopenharmony_ci                    const Handle<HeapObject>& rhs) const {
1671cb0ef41Sopenharmony_ci      return lhs.is_identical_to(rhs);
1681cb0ef41Sopenharmony_ci    }
1691cb0ef41Sopenharmony_ci  };
1701cb0ef41Sopenharmony_ci  ZoneUnorderedMap<Handle<HeapObject>, DependentCode::DependencyGroups,
1711cb0ef41Sopenharmony_ci                   HandleHash, HandleEqual>
1721cb0ef41Sopenharmony_ci      deps_;
1731cb0ef41Sopenharmony_ci  const DisallowGarbageCollection no_gc_;
1741cb0ef41Sopenharmony_ci};
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ciclass InitialMapDependency final : public CompilationDependency {
1771cb0ef41Sopenharmony_ci public:
1781cb0ef41Sopenharmony_ci  InitialMapDependency(JSHeapBroker* broker, const JSFunctionRef& function,
1791cb0ef41Sopenharmony_ci                       const MapRef& initial_map)
1801cb0ef41Sopenharmony_ci      : CompilationDependency(kInitialMap),
1811cb0ef41Sopenharmony_ci        function_(function),
1821cb0ef41Sopenharmony_ci        initial_map_(initial_map) {}
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  bool IsValid() const override {
1851cb0ef41Sopenharmony_ci    Handle<JSFunction> function = function_.object();
1861cb0ef41Sopenharmony_ci    return function->has_initial_map() &&
1871cb0ef41Sopenharmony_ci           function->initial_map() == *initial_map_.object();
1881cb0ef41Sopenharmony_ci  }
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
1911cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
1921cb0ef41Sopenharmony_ci    deps->Register(initial_map_.object(),
1931cb0ef41Sopenharmony_ci                   DependentCode::kInitialMapChangedGroup);
1941cb0ef41Sopenharmony_ci  }
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci private:
1971cb0ef41Sopenharmony_ci  size_t Hash() const override {
1981cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
1991cb0ef41Sopenharmony_ci    return base::hash_combine(h(function_), h(initial_map_));
2001cb0ef41Sopenharmony_ci  }
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
2031cb0ef41Sopenharmony_ci    const InitialMapDependency* const zat = that->AsInitialMap();
2041cb0ef41Sopenharmony_ci    return function_.equals(zat->function_) &&
2051cb0ef41Sopenharmony_ci           initial_map_.equals(zat->initial_map_);
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  const JSFunctionRef function_;
2091cb0ef41Sopenharmony_ci  const MapRef initial_map_;
2101cb0ef41Sopenharmony_ci};
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ciclass PrototypePropertyDependency final : public CompilationDependency {
2131cb0ef41Sopenharmony_ci public:
2141cb0ef41Sopenharmony_ci  PrototypePropertyDependency(JSHeapBroker* broker,
2151cb0ef41Sopenharmony_ci                              const JSFunctionRef& function,
2161cb0ef41Sopenharmony_ci                              const ObjectRef& prototype)
2171cb0ef41Sopenharmony_ci      : CompilationDependency(kPrototypeProperty),
2181cb0ef41Sopenharmony_ci        function_(function),
2191cb0ef41Sopenharmony_ci        prototype_(prototype) {
2201cb0ef41Sopenharmony_ci    DCHECK(function_.has_instance_prototype(broker->dependencies()));
2211cb0ef41Sopenharmony_ci    DCHECK(!function_.PrototypeRequiresRuntimeLookup(broker->dependencies()));
2221cb0ef41Sopenharmony_ci    DCHECK(function_.instance_prototype(broker->dependencies())
2231cb0ef41Sopenharmony_ci               .equals(prototype_));
2241cb0ef41Sopenharmony_ci  }
2251cb0ef41Sopenharmony_ci
2261cb0ef41Sopenharmony_ci  bool IsValid() const override {
2271cb0ef41Sopenharmony_ci    Handle<JSFunction> function = function_.object();
2281cb0ef41Sopenharmony_ci    return function->has_prototype_slot() &&
2291cb0ef41Sopenharmony_ci           function->has_instance_prototype() &&
2301cb0ef41Sopenharmony_ci           !function->PrototypeRequiresRuntimeLookup() &&
2311cb0ef41Sopenharmony_ci           function->instance_prototype() == *prototype_.object();
2321cb0ef41Sopenharmony_ci  }
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  void PrepareInstall() const override {
2351cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
2361cb0ef41Sopenharmony_ci    Handle<JSFunction> function = function_.object();
2371cb0ef41Sopenharmony_ci    if (!function->has_initial_map()) JSFunction::EnsureHasInitialMap(function);
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
2411cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
2421cb0ef41Sopenharmony_ci    Handle<JSFunction> function = function_.object();
2431cb0ef41Sopenharmony_ci    CHECK(function->has_initial_map());
2441cb0ef41Sopenharmony_ci    Handle<Map> initial_map(function->initial_map(), function_.isolate());
2451cb0ef41Sopenharmony_ci    deps->Register(initial_map, DependentCode::kInitialMapChangedGroup);
2461cb0ef41Sopenharmony_ci  }
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci private:
2491cb0ef41Sopenharmony_ci  size_t Hash() const override {
2501cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
2511cb0ef41Sopenharmony_ci    return base::hash_combine(h(function_), h(prototype_));
2521cb0ef41Sopenharmony_ci  }
2531cb0ef41Sopenharmony_ci
2541cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
2551cb0ef41Sopenharmony_ci    const PrototypePropertyDependency* const zat = that->AsPrototypeProperty();
2561cb0ef41Sopenharmony_ci    return function_.equals(zat->function_) &&
2571cb0ef41Sopenharmony_ci           prototype_.equals(zat->prototype_);
2581cb0ef41Sopenharmony_ci  }
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci  const JSFunctionRef function_;
2611cb0ef41Sopenharmony_ci  const ObjectRef prototype_;
2621cb0ef41Sopenharmony_ci};
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ciclass StableMapDependency final : public CompilationDependency {
2651cb0ef41Sopenharmony_ci public:
2661cb0ef41Sopenharmony_ci  explicit StableMapDependency(const MapRef& map)
2671cb0ef41Sopenharmony_ci      : CompilationDependency(kStableMap), map_(map) {}
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci  bool IsValid() const override {
2701cb0ef41Sopenharmony_ci    // TODO(v8:11670): Consider turn this back into a CHECK inside the
2711cb0ef41Sopenharmony_ci    // constructor and DependOnStableMap, if possible in light of concurrent
2721cb0ef41Sopenharmony_ci    // heap state modifications.
2731cb0ef41Sopenharmony_ci    return !map_.object()->is_dictionary_map() && map_.object()->is_stable();
2741cb0ef41Sopenharmony_ci  }
2751cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
2761cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
2771cb0ef41Sopenharmony_ci    deps->Register(map_.object(), DependentCode::kPrototypeCheckGroup);
2781cb0ef41Sopenharmony_ci  }
2791cb0ef41Sopenharmony_ci
2801cb0ef41Sopenharmony_ci private:
2811cb0ef41Sopenharmony_ci  size_t Hash() const override {
2821cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
2831cb0ef41Sopenharmony_ci    return base::hash_combine(h(map_));
2841cb0ef41Sopenharmony_ci  }
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
2871cb0ef41Sopenharmony_ci    const StableMapDependency* const zat = that->AsStableMap();
2881cb0ef41Sopenharmony_ci    return map_.equals(zat->map_);
2891cb0ef41Sopenharmony_ci  }
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  const MapRef map_;
2921cb0ef41Sopenharmony_ci};
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ciclass ConstantInDictionaryPrototypeChainDependency final
2951cb0ef41Sopenharmony_ci    : public CompilationDependency {
2961cb0ef41Sopenharmony_ci public:
2971cb0ef41Sopenharmony_ci  explicit ConstantInDictionaryPrototypeChainDependency(
2981cb0ef41Sopenharmony_ci      const MapRef receiver_map, const NameRef property_name,
2991cb0ef41Sopenharmony_ci      const ObjectRef constant, PropertyKind kind)
3001cb0ef41Sopenharmony_ci      : CompilationDependency(kConstantInDictionaryPrototypeChain),
3011cb0ef41Sopenharmony_ci        receiver_map_(receiver_map),
3021cb0ef41Sopenharmony_ci        property_name_{property_name},
3031cb0ef41Sopenharmony_ci        constant_{constant},
3041cb0ef41Sopenharmony_ci        kind_{kind} {
3051cb0ef41Sopenharmony_ci    DCHECK(V8_DICT_PROPERTY_CONST_TRACKING_BOOL);
3061cb0ef41Sopenharmony_ci  }
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  // Checks that |constant_| is still the value of accessing |property_name_|
3091cb0ef41Sopenharmony_ci  // starting at |receiver_map_|.
3101cb0ef41Sopenharmony_ci  bool IsValid() const override { return !GetHolderIfValid().is_null(); }
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
3131cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
3141cb0ef41Sopenharmony_ci    Isolate* isolate = receiver_map_.isolate();
3151cb0ef41Sopenharmony_ci    Handle<JSObject> holder = GetHolderIfValid().ToHandleChecked();
3161cb0ef41Sopenharmony_ci    Handle<Map> map = receiver_map_.object();
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci    while (map->prototype() != *holder) {
3191cb0ef41Sopenharmony_ci      map = handle(map->prototype().map(), isolate);
3201cb0ef41Sopenharmony_ci      DCHECK(map->IsJSObjectMap());  // Due to IsValid holding.
3211cb0ef41Sopenharmony_ci      deps->Register(map, DependentCode::kPrototypeCheckGroup);
3221cb0ef41Sopenharmony_ci    }
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci    DCHECK(map->prototype().map().IsJSObjectMap());  // Due to IsValid holding.
3251cb0ef41Sopenharmony_ci    deps->Register(handle(map->prototype().map(), isolate),
3261cb0ef41Sopenharmony_ci                   DependentCode::kPrototypeCheckGroup);
3271cb0ef41Sopenharmony_ci  }
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci private:
3301cb0ef41Sopenharmony_ci  // If the dependency is still valid, returns holder of the constant. Otherwise
3311cb0ef41Sopenharmony_ci  // returns null.
3321cb0ef41Sopenharmony_ci  // TODO(neis) Currently, invoking IsValid and then Install duplicates the call
3331cb0ef41Sopenharmony_ci  // to GetHolderIfValid. Instead, consider letting IsValid change the state
3341cb0ef41Sopenharmony_ci  // (and store the holder), or merge IsValid and Install.
3351cb0ef41Sopenharmony_ci  MaybeHandle<JSObject> GetHolderIfValid() const {
3361cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
3371cb0ef41Sopenharmony_ci    Isolate* isolate = receiver_map_.isolate();
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ci    Handle<Object> holder;
3401cb0ef41Sopenharmony_ci    HeapObject prototype = receiver_map_.object()->prototype();
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci    enum class ValidationResult { kFoundCorrect, kFoundIncorrect, kNotFound };
3431cb0ef41Sopenharmony_ci    auto try_load = [&](auto dictionary) -> ValidationResult {
3441cb0ef41Sopenharmony_ci      InternalIndex entry =
3451cb0ef41Sopenharmony_ci          dictionary.FindEntry(isolate, property_name_.object());
3461cb0ef41Sopenharmony_ci      if (entry.is_not_found()) {
3471cb0ef41Sopenharmony_ci        return ValidationResult::kNotFound;
3481cb0ef41Sopenharmony_ci      }
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci      PropertyDetails details = dictionary.DetailsAt(entry);
3511cb0ef41Sopenharmony_ci      if (details.constness() != PropertyConstness::kConst) {
3521cb0ef41Sopenharmony_ci        return ValidationResult::kFoundIncorrect;
3531cb0ef41Sopenharmony_ci      }
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_ci      Object dictionary_value = dictionary.ValueAt(entry);
3561cb0ef41Sopenharmony_ci      Object value;
3571cb0ef41Sopenharmony_ci      // We must be able to detect the case that the property |property_name_|
3581cb0ef41Sopenharmony_ci      // of |holder_| was originally a plain function |constant_| (when creating
3591cb0ef41Sopenharmony_ci      // this dependency) and has since become an accessor whose getter is
3601cb0ef41Sopenharmony_ci      // |constant_|. Therefore, we cannot just look at the property kind of
3611cb0ef41Sopenharmony_ci      // |details|, because that reflects the current situation, not the one
3621cb0ef41Sopenharmony_ci      // when creating this dependency.
3631cb0ef41Sopenharmony_ci      if (details.kind() != kind_) {
3641cb0ef41Sopenharmony_ci        return ValidationResult::kFoundIncorrect;
3651cb0ef41Sopenharmony_ci      }
3661cb0ef41Sopenharmony_ci      if (kind_ == PropertyKind::kAccessor) {
3671cb0ef41Sopenharmony_ci        if (!dictionary_value.IsAccessorPair()) {
3681cb0ef41Sopenharmony_ci          return ValidationResult::kFoundIncorrect;
3691cb0ef41Sopenharmony_ci        }
3701cb0ef41Sopenharmony_ci        // Only supporting loading at the moment, so we only ever want the
3711cb0ef41Sopenharmony_ci        // getter.
3721cb0ef41Sopenharmony_ci        value = AccessorPair::cast(dictionary_value)
3731cb0ef41Sopenharmony_ci                    .get(AccessorComponent::ACCESSOR_GETTER);
3741cb0ef41Sopenharmony_ci      } else {
3751cb0ef41Sopenharmony_ci        value = dictionary_value;
3761cb0ef41Sopenharmony_ci      }
3771cb0ef41Sopenharmony_ci      return value == *constant_.object() ? ValidationResult::kFoundCorrect
3781cb0ef41Sopenharmony_ci                                          : ValidationResult::kFoundIncorrect;
3791cb0ef41Sopenharmony_ci    };
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci    while (prototype.IsJSObject()) {
3821cb0ef41Sopenharmony_ci      // We only care about JSObjects because that's the only type of holder
3831cb0ef41Sopenharmony_ci      // (and types of prototypes on the chain to the holder) that
3841cb0ef41Sopenharmony_ci      // AccessInfoFactory::ComputePropertyAccessInfo allows.
3851cb0ef41Sopenharmony_ci      JSObject object = JSObject::cast(prototype);
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci      // We only support dictionary mode prototypes on the chain for this kind
3881cb0ef41Sopenharmony_ci      // of dependency.
3891cb0ef41Sopenharmony_ci      CHECK(!object.HasFastProperties());
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci      ValidationResult result =
3921cb0ef41Sopenharmony_ci          V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
3931cb0ef41Sopenharmony_ci              ? try_load(object.property_dictionary_swiss())
3941cb0ef41Sopenharmony_ci              : try_load(object.property_dictionary());
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ci      if (result == ValidationResult::kFoundCorrect) {
3971cb0ef41Sopenharmony_ci        return handle(object, isolate);
3981cb0ef41Sopenharmony_ci      } else if (result == ValidationResult::kFoundIncorrect) {
3991cb0ef41Sopenharmony_ci        return MaybeHandle<JSObject>();
4001cb0ef41Sopenharmony_ci      }
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci      // In case of kNotFound, continue walking up the chain.
4031cb0ef41Sopenharmony_ci      prototype = object.map().prototype();
4041cb0ef41Sopenharmony_ci    }
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ci    return MaybeHandle<JSObject>();
4071cb0ef41Sopenharmony_ci  }
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  size_t Hash() const override {
4101cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
4111cb0ef41Sopenharmony_ci    return base::hash_combine(h(receiver_map_), h(property_name_), h(constant_),
4121cb0ef41Sopenharmony_ci                              static_cast<int>(kind_));
4131cb0ef41Sopenharmony_ci  }
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
4161cb0ef41Sopenharmony_ci    const ConstantInDictionaryPrototypeChainDependency* const zat =
4171cb0ef41Sopenharmony_ci        that->AsConstantInDictionaryPrototypeChain();
4181cb0ef41Sopenharmony_ci    return receiver_map_.equals(zat->receiver_map_) &&
4191cb0ef41Sopenharmony_ci           property_name_.equals(zat->property_name_) &&
4201cb0ef41Sopenharmony_ci           constant_.equals(zat->constant_) && kind_ == zat->kind_;
4211cb0ef41Sopenharmony_ci  }
4221cb0ef41Sopenharmony_ci
4231cb0ef41Sopenharmony_ci  const MapRef receiver_map_;
4241cb0ef41Sopenharmony_ci  const NameRef property_name_;
4251cb0ef41Sopenharmony_ci  const ObjectRef constant_;
4261cb0ef41Sopenharmony_ci  const PropertyKind kind_;
4271cb0ef41Sopenharmony_ci};
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ciclass OwnConstantDataPropertyDependency final : public CompilationDependency {
4301cb0ef41Sopenharmony_ci public:
4311cb0ef41Sopenharmony_ci  OwnConstantDataPropertyDependency(JSHeapBroker* broker,
4321cb0ef41Sopenharmony_ci                                    const JSObjectRef& holder,
4331cb0ef41Sopenharmony_ci                                    const MapRef& map,
4341cb0ef41Sopenharmony_ci                                    Representation representation,
4351cb0ef41Sopenharmony_ci                                    FieldIndex index, const ObjectRef& value)
4361cb0ef41Sopenharmony_ci      : CompilationDependency(kOwnConstantDataProperty),
4371cb0ef41Sopenharmony_ci        broker_(broker),
4381cb0ef41Sopenharmony_ci        holder_(holder),
4391cb0ef41Sopenharmony_ci        map_(map),
4401cb0ef41Sopenharmony_ci        representation_(representation),
4411cb0ef41Sopenharmony_ci        index_(index),
4421cb0ef41Sopenharmony_ci        value_(value) {}
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  bool IsValid() const override {
4451cb0ef41Sopenharmony_ci    if (holder_.object()->map() != *map_.object()) {
4461cb0ef41Sopenharmony_ci      TRACE_BROKER_MISSING(broker_,
4471cb0ef41Sopenharmony_ci                           "Map change detected in " << holder_.object());
4481cb0ef41Sopenharmony_ci      return false;
4491cb0ef41Sopenharmony_ci    }
4501cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_heap_allocation;
4511cb0ef41Sopenharmony_ci    Object current_value = holder_.object()->RawFastPropertyAt(index_);
4521cb0ef41Sopenharmony_ci    Object used_value = *value_.object();
4531cb0ef41Sopenharmony_ci    if (representation_.IsDouble()) {
4541cb0ef41Sopenharmony_ci      // Compare doubles by bit pattern.
4551cb0ef41Sopenharmony_ci      if (!current_value.IsHeapNumber() || !used_value.IsHeapNumber() ||
4561cb0ef41Sopenharmony_ci          HeapNumber::cast(current_value).value_as_bits(kRelaxedLoad) !=
4571cb0ef41Sopenharmony_ci              HeapNumber::cast(used_value).value_as_bits(kRelaxedLoad)) {
4581cb0ef41Sopenharmony_ci        TRACE_BROKER_MISSING(broker_,
4591cb0ef41Sopenharmony_ci                             "Constant Double property value changed in "
4601cb0ef41Sopenharmony_ci                                 << holder_.object() << " at FieldIndex "
4611cb0ef41Sopenharmony_ci                                 << index_.property_index());
4621cb0ef41Sopenharmony_ci        return false;
4631cb0ef41Sopenharmony_ci      }
4641cb0ef41Sopenharmony_ci    } else if (current_value != used_value) {
4651cb0ef41Sopenharmony_ci      TRACE_BROKER_MISSING(broker_, "Constant property value changed in "
4661cb0ef41Sopenharmony_ci                                        << holder_.object() << " at FieldIndex "
4671cb0ef41Sopenharmony_ci                                        << index_.property_index());
4681cb0ef41Sopenharmony_ci      return false;
4691cb0ef41Sopenharmony_ci    }
4701cb0ef41Sopenharmony_ci    return true;
4711cb0ef41Sopenharmony_ci  }
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {}
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci private:
4761cb0ef41Sopenharmony_ci  size_t Hash() const override {
4771cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
4781cb0ef41Sopenharmony_ci    return base::hash_combine(h(holder_), h(map_), representation_.kind(),
4791cb0ef41Sopenharmony_ci                              index_.bit_field(), h(value_));
4801cb0ef41Sopenharmony_ci  }
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
4831cb0ef41Sopenharmony_ci    const OwnConstantDataPropertyDependency* const zat =
4841cb0ef41Sopenharmony_ci        that->AsOwnConstantDataProperty();
4851cb0ef41Sopenharmony_ci    return holder_.equals(zat->holder_) && map_.equals(zat->map_) &&
4861cb0ef41Sopenharmony_ci           representation_.Equals(zat->representation_) &&
4871cb0ef41Sopenharmony_ci           index_ == zat->index_ && value_.equals(zat->value_);
4881cb0ef41Sopenharmony_ci  }
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci  JSHeapBroker* const broker_;
4911cb0ef41Sopenharmony_ci  JSObjectRef const holder_;
4921cb0ef41Sopenharmony_ci  MapRef const map_;
4931cb0ef41Sopenharmony_ci  Representation const representation_;
4941cb0ef41Sopenharmony_ci  FieldIndex const index_;
4951cb0ef41Sopenharmony_ci  ObjectRef const value_;
4961cb0ef41Sopenharmony_ci};
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ciclass OwnConstantDictionaryPropertyDependency final
4991cb0ef41Sopenharmony_ci    : public CompilationDependency {
5001cb0ef41Sopenharmony_ci public:
5011cb0ef41Sopenharmony_ci  OwnConstantDictionaryPropertyDependency(JSHeapBroker* broker,
5021cb0ef41Sopenharmony_ci                                          const JSObjectRef& holder,
5031cb0ef41Sopenharmony_ci                                          InternalIndex index,
5041cb0ef41Sopenharmony_ci                                          const ObjectRef& value)
5051cb0ef41Sopenharmony_ci      : CompilationDependency(kOwnConstantDictionaryProperty),
5061cb0ef41Sopenharmony_ci        broker_(broker),
5071cb0ef41Sopenharmony_ci        holder_(holder),
5081cb0ef41Sopenharmony_ci        map_(holder.map()),
5091cb0ef41Sopenharmony_ci        index_(index),
5101cb0ef41Sopenharmony_ci        value_(value) {
5111cb0ef41Sopenharmony_ci    // We depend on map() being cached.
5121cb0ef41Sopenharmony_ci    STATIC_ASSERT(ref_traits<JSObject>::ref_serialization_kind !=
5131cb0ef41Sopenharmony_ci                  RefSerializationKind::kNeverSerialized);
5141cb0ef41Sopenharmony_ci  }
5151cb0ef41Sopenharmony_ci
5161cb0ef41Sopenharmony_ci  bool IsValid() const override {
5171cb0ef41Sopenharmony_ci    if (holder_.object()->map() != *map_.object()) {
5181cb0ef41Sopenharmony_ci      TRACE_BROKER_MISSING(broker_,
5191cb0ef41Sopenharmony_ci                           "Map change detected in " << holder_.object());
5201cb0ef41Sopenharmony_ci      return false;
5211cb0ef41Sopenharmony_ci    }
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci    base::Optional<Object> maybe_value = JSObject::DictionaryPropertyAt(
5241cb0ef41Sopenharmony_ci        holder_.object(), index_, broker_->isolate()->heap());
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci    if (!maybe_value) {
5271cb0ef41Sopenharmony_ci      TRACE_BROKER_MISSING(
5281cb0ef41Sopenharmony_ci          broker_, holder_.object()
5291cb0ef41Sopenharmony_ci                       << "has a value that might not safe to read at index "
5301cb0ef41Sopenharmony_ci                       << index_.as_int());
5311cb0ef41Sopenharmony_ci      return false;
5321cb0ef41Sopenharmony_ci    }
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci    if (*maybe_value != *value_.object()) {
5351cb0ef41Sopenharmony_ci      TRACE_BROKER_MISSING(broker_, "Constant property value changed in "
5361cb0ef41Sopenharmony_ci                                        << holder_.object()
5371cb0ef41Sopenharmony_ci                                        << " at InternalIndex "
5381cb0ef41Sopenharmony_ci                                        << index_.as_int());
5391cb0ef41Sopenharmony_ci      return false;
5401cb0ef41Sopenharmony_ci    }
5411cb0ef41Sopenharmony_ci    return true;
5421cb0ef41Sopenharmony_ci  }
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {}
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ci private:
5471cb0ef41Sopenharmony_ci  size_t Hash() const override {
5481cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
5491cb0ef41Sopenharmony_ci    return base::hash_combine(h(holder_), h(map_), index_.raw_value(),
5501cb0ef41Sopenharmony_ci                              h(value_));
5511cb0ef41Sopenharmony_ci  }
5521cb0ef41Sopenharmony_ci
5531cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
5541cb0ef41Sopenharmony_ci    const OwnConstantDictionaryPropertyDependency* const zat =
5551cb0ef41Sopenharmony_ci        that->AsOwnConstantDictionaryProperty();
5561cb0ef41Sopenharmony_ci    return holder_.equals(zat->holder_) && map_.equals(zat->map_) &&
5571cb0ef41Sopenharmony_ci           index_ == zat->index_ && value_.equals(zat->value_);
5581cb0ef41Sopenharmony_ci  }
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci  JSHeapBroker* const broker_;
5611cb0ef41Sopenharmony_ci  JSObjectRef const holder_;
5621cb0ef41Sopenharmony_ci  MapRef const map_;
5631cb0ef41Sopenharmony_ci  InternalIndex const index_;
5641cb0ef41Sopenharmony_ci  ObjectRef const value_;
5651cb0ef41Sopenharmony_ci};
5661cb0ef41Sopenharmony_ci
5671cb0ef41Sopenharmony_ciclass ConsistentJSFunctionViewDependency final : public CompilationDependency {
5681cb0ef41Sopenharmony_ci public:
5691cb0ef41Sopenharmony_ci  explicit ConsistentJSFunctionViewDependency(const JSFunctionRef& function)
5701cb0ef41Sopenharmony_ci      : CompilationDependency(kConsistentJSFunctionView), function_(function) {}
5711cb0ef41Sopenharmony_ci
5721cb0ef41Sopenharmony_ci  bool IsValid() const override {
5731cb0ef41Sopenharmony_ci    return function_.IsConsistentWithHeapState();
5741cb0ef41Sopenharmony_ci  }
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {}
5771cb0ef41Sopenharmony_ci
5781cb0ef41Sopenharmony_ci private:
5791cb0ef41Sopenharmony_ci  size_t Hash() const override {
5801cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
5811cb0ef41Sopenharmony_ci    return base::hash_combine(h(function_));
5821cb0ef41Sopenharmony_ci  }
5831cb0ef41Sopenharmony_ci
5841cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
5851cb0ef41Sopenharmony_ci    const ConsistentJSFunctionViewDependency* const zat =
5861cb0ef41Sopenharmony_ci        that->AsConsistentJSFunctionView();
5871cb0ef41Sopenharmony_ci    return function_.equals(zat->function_);
5881cb0ef41Sopenharmony_ci  }
5891cb0ef41Sopenharmony_ci
5901cb0ef41Sopenharmony_ci  const JSFunctionRef function_;
5911cb0ef41Sopenharmony_ci};
5921cb0ef41Sopenharmony_ci
5931cb0ef41Sopenharmony_ciclass TransitionDependency final : public CompilationDependency {
5941cb0ef41Sopenharmony_ci public:
5951cb0ef41Sopenharmony_ci  explicit TransitionDependency(const MapRef& map)
5961cb0ef41Sopenharmony_ci      : CompilationDependency(kTransition), map_(map) {
5971cb0ef41Sopenharmony_ci    DCHECK(map_.CanBeDeprecated());
5981cb0ef41Sopenharmony_ci  }
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci  bool IsValid() const override { return !map_.object()->is_deprecated(); }
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
6031cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
6041cb0ef41Sopenharmony_ci    deps->Register(map_.object(), DependentCode::kTransitionGroup);
6051cb0ef41Sopenharmony_ci  }
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci private:
6081cb0ef41Sopenharmony_ci  size_t Hash() const override {
6091cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
6101cb0ef41Sopenharmony_ci    return base::hash_combine(h(map_));
6111cb0ef41Sopenharmony_ci  }
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
6141cb0ef41Sopenharmony_ci    const TransitionDependency* const zat = that->AsTransition();
6151cb0ef41Sopenharmony_ci    return map_.equals(zat->map_);
6161cb0ef41Sopenharmony_ci  }
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci  const MapRef map_;
6191cb0ef41Sopenharmony_ci};
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ciclass PretenureModeDependency final : public CompilationDependency {
6221cb0ef41Sopenharmony_ci public:
6231cb0ef41Sopenharmony_ci  PretenureModeDependency(const AllocationSiteRef& site,
6241cb0ef41Sopenharmony_ci                          AllocationType allocation)
6251cb0ef41Sopenharmony_ci      : CompilationDependency(kPretenureMode),
6261cb0ef41Sopenharmony_ci        site_(site),
6271cb0ef41Sopenharmony_ci        allocation_(allocation) {}
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_ci  bool IsValid() const override {
6301cb0ef41Sopenharmony_ci    return allocation_ == site_.object()->GetAllocationType();
6311cb0ef41Sopenharmony_ci  }
6321cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
6331cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
6341cb0ef41Sopenharmony_ci    deps->Register(site_.object(),
6351cb0ef41Sopenharmony_ci                   DependentCode::kAllocationSiteTenuringChangedGroup);
6361cb0ef41Sopenharmony_ci  }
6371cb0ef41Sopenharmony_ci
6381cb0ef41Sopenharmony_ci private:
6391cb0ef41Sopenharmony_ci  size_t Hash() const override {
6401cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
6411cb0ef41Sopenharmony_ci    return base::hash_combine(h(site_), allocation_);
6421cb0ef41Sopenharmony_ci  }
6431cb0ef41Sopenharmony_ci
6441cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
6451cb0ef41Sopenharmony_ci    const PretenureModeDependency* const zat = that->AsPretenureMode();
6461cb0ef41Sopenharmony_ci    return site_.equals(zat->site_) && allocation_ == zat->allocation_;
6471cb0ef41Sopenharmony_ci  }
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci  const AllocationSiteRef site_;
6501cb0ef41Sopenharmony_ci  const AllocationType allocation_;
6511cb0ef41Sopenharmony_ci};
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ciclass FieldRepresentationDependency final : public CompilationDependency {
6541cb0ef41Sopenharmony_ci public:
6551cb0ef41Sopenharmony_ci  FieldRepresentationDependency(const MapRef& map, InternalIndex descriptor,
6561cb0ef41Sopenharmony_ci                                Representation representation)
6571cb0ef41Sopenharmony_ci      : CompilationDependency(kFieldRepresentation),
6581cb0ef41Sopenharmony_ci        map_(map),
6591cb0ef41Sopenharmony_ci        descriptor_(descriptor),
6601cb0ef41Sopenharmony_ci        representation_(representation) {}
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ci  bool IsValid() const override {
6631cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_heap_allocation;
6641cb0ef41Sopenharmony_ci    if (map_.object()->is_deprecated()) return false;
6651cb0ef41Sopenharmony_ci    return representation_.Equals(map_.object()
6661cb0ef41Sopenharmony_ci                                      ->instance_descriptors(map_.isolate())
6671cb0ef41Sopenharmony_ci                                      .GetDetails(descriptor_)
6681cb0ef41Sopenharmony_ci                                      .representation());
6691cb0ef41Sopenharmony_ci  }
6701cb0ef41Sopenharmony_ci
6711cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
6721cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
6731cb0ef41Sopenharmony_ci    Isolate* isolate = map_.isolate();
6741cb0ef41Sopenharmony_ci    Handle<Map> owner(map_.object()->FindFieldOwner(isolate, descriptor_),
6751cb0ef41Sopenharmony_ci                      isolate);
6761cb0ef41Sopenharmony_ci    CHECK(!owner->is_deprecated());
6771cb0ef41Sopenharmony_ci    CHECK(representation_.Equals(owner->instance_descriptors(isolate)
6781cb0ef41Sopenharmony_ci                                     .GetDetails(descriptor_)
6791cb0ef41Sopenharmony_ci                                     .representation()));
6801cb0ef41Sopenharmony_ci    deps->Register(owner, DependentCode::kFieldRepresentationGroup);
6811cb0ef41Sopenharmony_ci  }
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci  bool DependsOn(const Handle<Map>& receiver_map) const {
6841cb0ef41Sopenharmony_ci    return map_.object().equals(receiver_map);
6851cb0ef41Sopenharmony_ci  }
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci private:
6881cb0ef41Sopenharmony_ci  size_t Hash() const override {
6891cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
6901cb0ef41Sopenharmony_ci    return base::hash_combine(h(map_), descriptor_.as_int(),
6911cb0ef41Sopenharmony_ci                              representation_.kind());
6921cb0ef41Sopenharmony_ci  }
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
6951cb0ef41Sopenharmony_ci    const FieldRepresentationDependency* const zat =
6961cb0ef41Sopenharmony_ci        that->AsFieldRepresentation();
6971cb0ef41Sopenharmony_ci    return map_.equals(zat->map_) && descriptor_ == zat->descriptor_ &&
6981cb0ef41Sopenharmony_ci           representation_.Equals(zat->representation_);
6991cb0ef41Sopenharmony_ci  }
7001cb0ef41Sopenharmony_ci
7011cb0ef41Sopenharmony_ci  const MapRef map_;
7021cb0ef41Sopenharmony_ci  const InternalIndex descriptor_;
7031cb0ef41Sopenharmony_ci  const Representation representation_;
7041cb0ef41Sopenharmony_ci};
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ciclass FieldTypeDependency final : public CompilationDependency {
7071cb0ef41Sopenharmony_ci public:
7081cb0ef41Sopenharmony_ci  FieldTypeDependency(const MapRef& map, InternalIndex descriptor,
7091cb0ef41Sopenharmony_ci                      const ObjectRef& type)
7101cb0ef41Sopenharmony_ci      : CompilationDependency(kFieldType),
7111cb0ef41Sopenharmony_ci        map_(map),
7121cb0ef41Sopenharmony_ci        descriptor_(descriptor),
7131cb0ef41Sopenharmony_ci        type_(type) {}
7141cb0ef41Sopenharmony_ci
7151cb0ef41Sopenharmony_ci  bool IsValid() const override {
7161cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_heap_allocation;
7171cb0ef41Sopenharmony_ci    if (map_.object()->is_deprecated()) return false;
7181cb0ef41Sopenharmony_ci    return *type_.object() == map_.object()
7191cb0ef41Sopenharmony_ci                                  ->instance_descriptors(map_.isolate())
7201cb0ef41Sopenharmony_ci                                  .GetFieldType(descriptor_);
7211cb0ef41Sopenharmony_ci  }
7221cb0ef41Sopenharmony_ci
7231cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
7241cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
7251cb0ef41Sopenharmony_ci    Isolate* isolate = map_.isolate();
7261cb0ef41Sopenharmony_ci    Handle<Map> owner(map_.object()->FindFieldOwner(isolate, descriptor_),
7271cb0ef41Sopenharmony_ci                      isolate);
7281cb0ef41Sopenharmony_ci    CHECK(!owner->is_deprecated());
7291cb0ef41Sopenharmony_ci    CHECK_EQ(*type_.object(),
7301cb0ef41Sopenharmony_ci             owner->instance_descriptors(isolate).GetFieldType(descriptor_));
7311cb0ef41Sopenharmony_ci    deps->Register(owner, DependentCode::kFieldTypeGroup);
7321cb0ef41Sopenharmony_ci  }
7331cb0ef41Sopenharmony_ci
7341cb0ef41Sopenharmony_ci private:
7351cb0ef41Sopenharmony_ci  size_t Hash() const override {
7361cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
7371cb0ef41Sopenharmony_ci    return base::hash_combine(h(map_), descriptor_.as_int(), h(type_));
7381cb0ef41Sopenharmony_ci  }
7391cb0ef41Sopenharmony_ci
7401cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
7411cb0ef41Sopenharmony_ci    const FieldTypeDependency* const zat = that->AsFieldType();
7421cb0ef41Sopenharmony_ci    return map_.equals(zat->map_) && descriptor_ == zat->descriptor_ &&
7431cb0ef41Sopenharmony_ci           type_.equals(zat->type_);
7441cb0ef41Sopenharmony_ci  }
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci  const MapRef map_;
7471cb0ef41Sopenharmony_ci  const InternalIndex descriptor_;
7481cb0ef41Sopenharmony_ci  const ObjectRef type_;
7491cb0ef41Sopenharmony_ci};
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ciclass FieldConstnessDependency final : public CompilationDependency {
7521cb0ef41Sopenharmony_ci public:
7531cb0ef41Sopenharmony_ci  FieldConstnessDependency(const MapRef& map, InternalIndex descriptor)
7541cb0ef41Sopenharmony_ci      : CompilationDependency(kFieldConstness),
7551cb0ef41Sopenharmony_ci        map_(map),
7561cb0ef41Sopenharmony_ci        descriptor_(descriptor) {}
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ci  bool IsValid() const override {
7591cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_heap_allocation;
7601cb0ef41Sopenharmony_ci    if (map_.object()->is_deprecated()) return false;
7611cb0ef41Sopenharmony_ci    return PropertyConstness::kConst ==
7621cb0ef41Sopenharmony_ci           map_.object()
7631cb0ef41Sopenharmony_ci               ->instance_descriptors(map_.isolate())
7641cb0ef41Sopenharmony_ci               .GetDetails(descriptor_)
7651cb0ef41Sopenharmony_ci               .constness();
7661cb0ef41Sopenharmony_ci  }
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
7691cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
7701cb0ef41Sopenharmony_ci    Isolate* isolate = map_.isolate();
7711cb0ef41Sopenharmony_ci    Handle<Map> owner(map_.object()->FindFieldOwner(isolate, descriptor_),
7721cb0ef41Sopenharmony_ci                      isolate);
7731cb0ef41Sopenharmony_ci    CHECK(!owner->is_deprecated());
7741cb0ef41Sopenharmony_ci    CHECK_EQ(PropertyConstness::kConst, owner->instance_descriptors(isolate)
7751cb0ef41Sopenharmony_ci                                            .GetDetails(descriptor_)
7761cb0ef41Sopenharmony_ci                                            .constness());
7771cb0ef41Sopenharmony_ci    deps->Register(owner, DependentCode::kFieldConstGroup);
7781cb0ef41Sopenharmony_ci  }
7791cb0ef41Sopenharmony_ci
7801cb0ef41Sopenharmony_ci private:
7811cb0ef41Sopenharmony_ci  size_t Hash() const override {
7821cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
7831cb0ef41Sopenharmony_ci    return base::hash_combine(h(map_), descriptor_.as_int());
7841cb0ef41Sopenharmony_ci  }
7851cb0ef41Sopenharmony_ci
7861cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
7871cb0ef41Sopenharmony_ci    const FieldConstnessDependency* const zat = that->AsFieldConstness();
7881cb0ef41Sopenharmony_ci    return map_.equals(zat->map_) && descriptor_ == zat->descriptor_;
7891cb0ef41Sopenharmony_ci  }
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_ci  const MapRef map_;
7921cb0ef41Sopenharmony_ci  const InternalIndex descriptor_;
7931cb0ef41Sopenharmony_ci};
7941cb0ef41Sopenharmony_ci
7951cb0ef41Sopenharmony_ciclass GlobalPropertyDependency final : public CompilationDependency {
7961cb0ef41Sopenharmony_ci public:
7971cb0ef41Sopenharmony_ci  GlobalPropertyDependency(const PropertyCellRef& cell, PropertyCellType type,
7981cb0ef41Sopenharmony_ci                           bool read_only)
7991cb0ef41Sopenharmony_ci      : CompilationDependency(kGlobalProperty),
8001cb0ef41Sopenharmony_ci        cell_(cell),
8011cb0ef41Sopenharmony_ci        type_(type),
8021cb0ef41Sopenharmony_ci        read_only_(read_only) {
8031cb0ef41Sopenharmony_ci    DCHECK_EQ(type_, cell_.property_details().cell_type());
8041cb0ef41Sopenharmony_ci    DCHECK_EQ(read_only_, cell_.property_details().IsReadOnly());
8051cb0ef41Sopenharmony_ci  }
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci  bool IsValid() const override {
8081cb0ef41Sopenharmony_ci    Handle<PropertyCell> cell = cell_.object();
8091cb0ef41Sopenharmony_ci    // The dependency is never valid if the cell is 'invalidated'. This is
8101cb0ef41Sopenharmony_ci    // marked by setting the value to the hole.
8111cb0ef41Sopenharmony_ci    if (cell->value() == *(cell_.isolate()->factory()->the_hole_value())) {
8121cb0ef41Sopenharmony_ci      return false;
8131cb0ef41Sopenharmony_ci    }
8141cb0ef41Sopenharmony_ci    return type_ == cell->property_details().cell_type() &&
8151cb0ef41Sopenharmony_ci           read_only_ == cell->property_details().IsReadOnly();
8161cb0ef41Sopenharmony_ci  }
8171cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
8181cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
8191cb0ef41Sopenharmony_ci    deps->Register(cell_.object(), DependentCode::kPropertyCellChangedGroup);
8201cb0ef41Sopenharmony_ci  }
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci private:
8231cb0ef41Sopenharmony_ci  size_t Hash() const override {
8241cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
8251cb0ef41Sopenharmony_ci    return base::hash_combine(h(cell_), static_cast<int>(type_), read_only_);
8261cb0ef41Sopenharmony_ci  }
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
8291cb0ef41Sopenharmony_ci    const GlobalPropertyDependency* const zat = that->AsGlobalProperty();
8301cb0ef41Sopenharmony_ci    return cell_.equals(zat->cell_) && type_ == zat->type_ &&
8311cb0ef41Sopenharmony_ci           read_only_ == zat->read_only_;
8321cb0ef41Sopenharmony_ci  }
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  const PropertyCellRef cell_;
8351cb0ef41Sopenharmony_ci  const PropertyCellType type_;
8361cb0ef41Sopenharmony_ci  const bool read_only_;
8371cb0ef41Sopenharmony_ci};
8381cb0ef41Sopenharmony_ci
8391cb0ef41Sopenharmony_ciclass ProtectorDependency final : public CompilationDependency {
8401cb0ef41Sopenharmony_ci public:
8411cb0ef41Sopenharmony_ci  explicit ProtectorDependency(const PropertyCellRef& cell)
8421cb0ef41Sopenharmony_ci      : CompilationDependency(kProtector), cell_(cell) {}
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ci  bool IsValid() const override {
8451cb0ef41Sopenharmony_ci    Handle<PropertyCell> cell = cell_.object();
8461cb0ef41Sopenharmony_ci    return cell->value() == Smi::FromInt(Protectors::kProtectorValid);
8471cb0ef41Sopenharmony_ci  }
8481cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
8491cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
8501cb0ef41Sopenharmony_ci    deps->Register(cell_.object(), DependentCode::kPropertyCellChangedGroup);
8511cb0ef41Sopenharmony_ci  }
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci private:
8541cb0ef41Sopenharmony_ci  size_t Hash() const override {
8551cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
8561cb0ef41Sopenharmony_ci    return base::hash_combine(h(cell_));
8571cb0ef41Sopenharmony_ci  }
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
8601cb0ef41Sopenharmony_ci    const ProtectorDependency* const zat = that->AsProtector();
8611cb0ef41Sopenharmony_ci    return cell_.equals(zat->cell_);
8621cb0ef41Sopenharmony_ci  }
8631cb0ef41Sopenharmony_ci
8641cb0ef41Sopenharmony_ci  const PropertyCellRef cell_;
8651cb0ef41Sopenharmony_ci};
8661cb0ef41Sopenharmony_ci
8671cb0ef41Sopenharmony_ci// Check that an object slot will not change during compilation.
8681cb0ef41Sopenharmony_ciclass ObjectSlotValueDependency final : public CompilationDependency {
8691cb0ef41Sopenharmony_ci public:
8701cb0ef41Sopenharmony_ci  explicit ObjectSlotValueDependency(const HeapObjectRef& object, int offset,
8711cb0ef41Sopenharmony_ci                                     const ObjectRef& value)
8721cb0ef41Sopenharmony_ci      : CompilationDependency(kObjectSlotValue),
8731cb0ef41Sopenharmony_ci        object_(object.object()),
8741cb0ef41Sopenharmony_ci        offset_(offset),
8751cb0ef41Sopenharmony_ci        value_(value.object()) {}
8761cb0ef41Sopenharmony_ci
8771cb0ef41Sopenharmony_ci  bool IsValid() const override {
8781cb0ef41Sopenharmony_ci    PtrComprCageBase cage_base = GetPtrComprCageBase(*object_);
8791cb0ef41Sopenharmony_ci    Object current_value =
8801cb0ef41Sopenharmony_ci        offset_ == HeapObject::kMapOffset
8811cb0ef41Sopenharmony_ci            ? object_->map()
8821cb0ef41Sopenharmony_ci            : TaggedField<Object>::Relaxed_Load(cage_base, *object_, offset_);
8831cb0ef41Sopenharmony_ci    return *value_ == current_value;
8841cb0ef41Sopenharmony_ci  }
8851cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {}
8861cb0ef41Sopenharmony_ci
8871cb0ef41Sopenharmony_ci private:
8881cb0ef41Sopenharmony_ci  size_t Hash() const override {
8891cb0ef41Sopenharmony_ci    return base::hash_combine(object_.address(), offset_, value_.address());
8901cb0ef41Sopenharmony_ci  }
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
8931cb0ef41Sopenharmony_ci    const ObjectSlotValueDependency* const zat = that->AsObjectSlotValue();
8941cb0ef41Sopenharmony_ci    return object_->address() == zat->object_->address() &&
8951cb0ef41Sopenharmony_ci           offset_ == zat->offset_ && value_.address() == zat->value_.address();
8961cb0ef41Sopenharmony_ci  }
8971cb0ef41Sopenharmony_ci
8981cb0ef41Sopenharmony_ci  Handle<HeapObject> object_;
8991cb0ef41Sopenharmony_ci  int offset_;
9001cb0ef41Sopenharmony_ci  Handle<Object> value_;
9011cb0ef41Sopenharmony_ci};
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_ciclass ElementsKindDependency final : public CompilationDependency {
9041cb0ef41Sopenharmony_ci public:
9051cb0ef41Sopenharmony_ci  ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
9061cb0ef41Sopenharmony_ci      : CompilationDependency(kElementsKind), site_(site), kind_(kind) {
9071cb0ef41Sopenharmony_ci    DCHECK(AllocationSite::ShouldTrack(kind_));
9081cb0ef41Sopenharmony_ci  }
9091cb0ef41Sopenharmony_ci
9101cb0ef41Sopenharmony_ci  bool IsValid() const override {
9111cb0ef41Sopenharmony_ci    Handle<AllocationSite> site = site_.object();
9121cb0ef41Sopenharmony_ci    ElementsKind kind =
9131cb0ef41Sopenharmony_ci        site->PointsToLiteral()
9141cb0ef41Sopenharmony_ci            ? site->boilerplate(kAcquireLoad).map().elements_kind()
9151cb0ef41Sopenharmony_ci            : site->GetElementsKind();
9161cb0ef41Sopenharmony_ci    return kind_ == kind;
9171cb0ef41Sopenharmony_ci  }
9181cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
9191cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
9201cb0ef41Sopenharmony_ci    deps->Register(site_.object(),
9211cb0ef41Sopenharmony_ci                   DependentCode::kAllocationSiteTransitionChangedGroup);
9221cb0ef41Sopenharmony_ci  }
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci private:
9251cb0ef41Sopenharmony_ci  size_t Hash() const override {
9261cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
9271cb0ef41Sopenharmony_ci    return base::hash_combine(h(site_), static_cast<int>(kind_));
9281cb0ef41Sopenharmony_ci  }
9291cb0ef41Sopenharmony_ci
9301cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
9311cb0ef41Sopenharmony_ci    const ElementsKindDependency* const zat = that->AsElementsKind();
9321cb0ef41Sopenharmony_ci    return site_.equals(zat->site_) && kind_ == zat->kind_;
9331cb0ef41Sopenharmony_ci  }
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci  const AllocationSiteRef site_;
9361cb0ef41Sopenharmony_ci  const ElementsKind kind_;
9371cb0ef41Sopenharmony_ci};
9381cb0ef41Sopenharmony_ci
9391cb0ef41Sopenharmony_ci// Only valid if the holder can use direct reads, since validation uses
9401cb0ef41Sopenharmony_ci// GetOwnConstantElementFromHeap.
9411cb0ef41Sopenharmony_ciclass OwnConstantElementDependency final : public CompilationDependency {
9421cb0ef41Sopenharmony_ci public:
9431cb0ef41Sopenharmony_ci  OwnConstantElementDependency(const JSObjectRef& holder, uint32_t index,
9441cb0ef41Sopenharmony_ci                               const ObjectRef& element)
9451cb0ef41Sopenharmony_ci      : CompilationDependency(kOwnConstantElement),
9461cb0ef41Sopenharmony_ci        holder_(holder),
9471cb0ef41Sopenharmony_ci        index_(index),
9481cb0ef41Sopenharmony_ci        element_(element) {}
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_ci  bool IsValid() const override {
9511cb0ef41Sopenharmony_ci    DisallowGarbageCollection no_gc;
9521cb0ef41Sopenharmony_ci    JSObject holder = *holder_.object();
9531cb0ef41Sopenharmony_ci    base::Optional<Object> maybe_element =
9541cb0ef41Sopenharmony_ci        holder_.GetOwnConstantElementFromHeap(holder.elements(),
9551cb0ef41Sopenharmony_ci                                              holder.GetElementsKind(), index_);
9561cb0ef41Sopenharmony_ci    if (!maybe_element.has_value()) return false;
9571cb0ef41Sopenharmony_ci
9581cb0ef41Sopenharmony_ci    return maybe_element.value() == *element_.object();
9591cb0ef41Sopenharmony_ci  }
9601cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {}
9611cb0ef41Sopenharmony_ci
9621cb0ef41Sopenharmony_ci private:
9631cb0ef41Sopenharmony_ci  size_t Hash() const override {
9641cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
9651cb0ef41Sopenharmony_ci    return base::hash_combine(h(holder_), index_, h(element_));
9661cb0ef41Sopenharmony_ci  }
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
9691cb0ef41Sopenharmony_ci    const OwnConstantElementDependency* const zat =
9701cb0ef41Sopenharmony_ci        that->AsOwnConstantElement();
9711cb0ef41Sopenharmony_ci    return holder_.equals(zat->holder_) && index_ == zat->index_ &&
9721cb0ef41Sopenharmony_ci           element_.equals(zat->element_);
9731cb0ef41Sopenharmony_ci  }
9741cb0ef41Sopenharmony_ci
9751cb0ef41Sopenharmony_ci  const JSObjectRef holder_;
9761cb0ef41Sopenharmony_ci  const uint32_t index_;
9771cb0ef41Sopenharmony_ci  const ObjectRef element_;
9781cb0ef41Sopenharmony_ci};
9791cb0ef41Sopenharmony_ci
9801cb0ef41Sopenharmony_ciclass InitialMapInstanceSizePredictionDependency final
9811cb0ef41Sopenharmony_ci    : public CompilationDependency {
9821cb0ef41Sopenharmony_ci public:
9831cb0ef41Sopenharmony_ci  InitialMapInstanceSizePredictionDependency(const JSFunctionRef& function,
9841cb0ef41Sopenharmony_ci                                             int instance_size)
9851cb0ef41Sopenharmony_ci      : CompilationDependency(kInitialMapInstanceSizePrediction),
9861cb0ef41Sopenharmony_ci        function_(function),
9871cb0ef41Sopenharmony_ci        instance_size_(instance_size) {}
9881cb0ef41Sopenharmony_ci
9891cb0ef41Sopenharmony_ci  bool IsValid() const override {
9901cb0ef41Sopenharmony_ci    // The dependency is valid if the prediction is the same as the current
9911cb0ef41Sopenharmony_ci    // slack tracking result.
9921cb0ef41Sopenharmony_ci    if (!function_.object()->has_initial_map()) return false;
9931cb0ef41Sopenharmony_ci    int instance_size = function_.object()->ComputeInstanceSizeWithMinSlack(
9941cb0ef41Sopenharmony_ci        function_.isolate());
9951cb0ef41Sopenharmony_ci    return instance_size == instance_size_;
9961cb0ef41Sopenharmony_ci  }
9971cb0ef41Sopenharmony_ci
9981cb0ef41Sopenharmony_ci  void PrepareInstall() const override {
9991cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
10001cb0ef41Sopenharmony_ci    function_.object()->CompleteInobjectSlackTrackingIfActive();
10011cb0ef41Sopenharmony_ci  }
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ci  void Install(PendingDependencies* deps) const override {
10041cb0ef41Sopenharmony_ci    SLOW_DCHECK(IsValid());
10051cb0ef41Sopenharmony_ci    DCHECK(
10061cb0ef41Sopenharmony_ci        !function_.object()->initial_map().IsInobjectSlackTrackingInProgress());
10071cb0ef41Sopenharmony_ci  }
10081cb0ef41Sopenharmony_ci
10091cb0ef41Sopenharmony_ci private:
10101cb0ef41Sopenharmony_ci  size_t Hash() const override {
10111cb0ef41Sopenharmony_ci    ObjectRef::Hash h;
10121cb0ef41Sopenharmony_ci    return base::hash_combine(h(function_), instance_size_);
10131cb0ef41Sopenharmony_ci  }
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ci  bool Equals(const CompilationDependency* that) const override {
10161cb0ef41Sopenharmony_ci    const InitialMapInstanceSizePredictionDependency* const zat =
10171cb0ef41Sopenharmony_ci        that->AsInitialMapInstanceSizePrediction();
10181cb0ef41Sopenharmony_ci    return function_.equals(zat->function_) &&
10191cb0ef41Sopenharmony_ci           instance_size_ == zat->instance_size_;
10201cb0ef41Sopenharmony_ci  }
10211cb0ef41Sopenharmony_ci
10221cb0ef41Sopenharmony_ci  const JSFunctionRef function_;
10231cb0ef41Sopenharmony_ci  const int instance_size_;
10241cb0ef41Sopenharmony_ci};
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci}  // namespace
10271cb0ef41Sopenharmony_ci
10281cb0ef41Sopenharmony_civoid CompilationDependencies::RecordDependency(
10291cb0ef41Sopenharmony_ci    CompilationDependency const* dependency) {
10301cb0ef41Sopenharmony_ci  if (dependency != nullptr) dependencies_.insert(dependency);
10311cb0ef41Sopenharmony_ci}
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ciMapRef CompilationDependencies::DependOnInitialMap(
10341cb0ef41Sopenharmony_ci    const JSFunctionRef& function) {
10351cb0ef41Sopenharmony_ci  MapRef map = function.initial_map(this);
10361cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<InitialMapDependency>(broker_, function, map));
10371cb0ef41Sopenharmony_ci  return map;
10381cb0ef41Sopenharmony_ci}
10391cb0ef41Sopenharmony_ci
10401cb0ef41Sopenharmony_ciObjectRef CompilationDependencies::DependOnPrototypeProperty(
10411cb0ef41Sopenharmony_ci    const JSFunctionRef& function) {
10421cb0ef41Sopenharmony_ci  ObjectRef prototype = function.instance_prototype(this);
10431cb0ef41Sopenharmony_ci  RecordDependency(
10441cb0ef41Sopenharmony_ci      zone_->New<PrototypePropertyDependency>(broker_, function, prototype));
10451cb0ef41Sopenharmony_ci  return prototype;
10461cb0ef41Sopenharmony_ci}
10471cb0ef41Sopenharmony_ci
10481cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnStableMap(const MapRef& map) {
10491cb0ef41Sopenharmony_ci  if (map.CanTransition()) {
10501cb0ef41Sopenharmony_ci    RecordDependency(zone_->New<StableMapDependency>(map));
10511cb0ef41Sopenharmony_ci  }
10521cb0ef41Sopenharmony_ci}
10531cb0ef41Sopenharmony_ci
10541cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnConstantInDictionaryPrototypeChain(
10551cb0ef41Sopenharmony_ci    const MapRef& receiver_map, const NameRef& property_name,
10561cb0ef41Sopenharmony_ci    const ObjectRef& constant, PropertyKind kind) {
10571cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<ConstantInDictionaryPrototypeChainDependency>(
10581cb0ef41Sopenharmony_ci      receiver_map, property_name, constant, kind));
10591cb0ef41Sopenharmony_ci}
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ciAllocationType CompilationDependencies::DependOnPretenureMode(
10621cb0ef41Sopenharmony_ci    const AllocationSiteRef& site) {
10631cb0ef41Sopenharmony_ci  if (!FLAG_allocation_site_pretenuring) return AllocationType::kYoung;
10641cb0ef41Sopenharmony_ci  AllocationType allocation = site.GetAllocationType();
10651cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<PretenureModeDependency>(site, allocation));
10661cb0ef41Sopenharmony_ci  return allocation;
10671cb0ef41Sopenharmony_ci}
10681cb0ef41Sopenharmony_ci
10691cb0ef41Sopenharmony_ciPropertyConstness CompilationDependencies::DependOnFieldConstness(
10701cb0ef41Sopenharmony_ci    const MapRef& map, InternalIndex descriptor) {
10711cb0ef41Sopenharmony_ci  PropertyConstness constness = map.GetPropertyDetails(descriptor).constness();
10721cb0ef41Sopenharmony_ci  if (constness == PropertyConstness::kMutable) return constness;
10731cb0ef41Sopenharmony_ci
10741cb0ef41Sopenharmony_ci  // If the map can have fast elements transitions, then the field can be only
10751cb0ef41Sopenharmony_ci  // considered constant if the map does not transition.
10761cb0ef41Sopenharmony_ci  if (Map::CanHaveFastTransitionableElementsKind(map.instance_type())) {
10771cb0ef41Sopenharmony_ci    // If the map can already transition away, let us report the field as
10781cb0ef41Sopenharmony_ci    // mutable.
10791cb0ef41Sopenharmony_ci    if (!map.is_stable()) {
10801cb0ef41Sopenharmony_ci      return PropertyConstness::kMutable;
10811cb0ef41Sopenharmony_ci    }
10821cb0ef41Sopenharmony_ci    DependOnStableMap(map);
10831cb0ef41Sopenharmony_ci  }
10841cb0ef41Sopenharmony_ci
10851cb0ef41Sopenharmony_ci  DCHECK_EQ(constness, PropertyConstness::kConst);
10861cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<FieldConstnessDependency>(map, descriptor));
10871cb0ef41Sopenharmony_ci  return PropertyConstness::kConst;
10881cb0ef41Sopenharmony_ci}
10891cb0ef41Sopenharmony_ci
10901cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnGlobalProperty(
10911cb0ef41Sopenharmony_ci    const PropertyCellRef& cell) {
10921cb0ef41Sopenharmony_ci  PropertyCellType type = cell.property_details().cell_type();
10931cb0ef41Sopenharmony_ci  bool read_only = cell.property_details().IsReadOnly();
10941cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<GlobalPropertyDependency>(cell, type, read_only));
10951cb0ef41Sopenharmony_ci}
10961cb0ef41Sopenharmony_ci
10971cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
10981cb0ef41Sopenharmony_ci  cell.CacheAsProtector();
10991cb0ef41Sopenharmony_ci  if (cell.value().AsSmi() != Protectors::kProtectorValid) return false;
11001cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<ProtectorDependency>(cell));
11011cb0ef41Sopenharmony_ci  return true;
11021cb0ef41Sopenharmony_ci}
11031cb0ef41Sopenharmony_ci
11041cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnArrayBufferDetachingProtector() {
11051cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11061cb0ef41Sopenharmony_ci      broker_,
11071cb0ef41Sopenharmony_ci      broker_->isolate()->factory()->array_buffer_detaching_protector()));
11081cb0ef41Sopenharmony_ci}
11091cb0ef41Sopenharmony_ci
11101cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnArrayIteratorProtector() {
11111cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11121cb0ef41Sopenharmony_ci      broker_, broker_->isolate()->factory()->array_iterator_protector()));
11131cb0ef41Sopenharmony_ci}
11141cb0ef41Sopenharmony_ci
11151cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnArraySpeciesProtector() {
11161cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11171cb0ef41Sopenharmony_ci      broker_, broker_->isolate()->factory()->array_species_protector()));
11181cb0ef41Sopenharmony_ci}
11191cb0ef41Sopenharmony_ci
11201cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnNoElementsProtector() {
11211cb0ef41Sopenharmony_ci  return DependOnProtector(
11221cb0ef41Sopenharmony_ci      MakeRef(broker_, broker_->isolate()->factory()->no_elements_protector()));
11231cb0ef41Sopenharmony_ci}
11241cb0ef41Sopenharmony_ci
11251cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnPromiseHookProtector() {
11261cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11271cb0ef41Sopenharmony_ci      broker_, broker_->isolate()->factory()->promise_hook_protector()));
11281cb0ef41Sopenharmony_ci}
11291cb0ef41Sopenharmony_ci
11301cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnPromiseSpeciesProtector() {
11311cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11321cb0ef41Sopenharmony_ci      broker_, broker_->isolate()->factory()->promise_species_protector()));
11331cb0ef41Sopenharmony_ci}
11341cb0ef41Sopenharmony_ci
11351cb0ef41Sopenharmony_cibool CompilationDependencies::DependOnPromiseThenProtector() {
11361cb0ef41Sopenharmony_ci  return DependOnProtector(MakeRef(
11371cb0ef41Sopenharmony_ci      broker_, broker_->isolate()->factory()->promise_then_protector()));
11381cb0ef41Sopenharmony_ci}
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnElementsKind(
11411cb0ef41Sopenharmony_ci    const AllocationSiteRef& site) {
11421cb0ef41Sopenharmony_ci  ElementsKind kind = site.PointsToLiteral()
11431cb0ef41Sopenharmony_ci                          ? site.boilerplate().value().map().elements_kind()
11441cb0ef41Sopenharmony_ci                          : site.GetElementsKind();
11451cb0ef41Sopenharmony_ci  if (AllocationSite::ShouldTrack(kind)) {
11461cb0ef41Sopenharmony_ci    RecordDependency(zone_->New<ElementsKindDependency>(site, kind));
11471cb0ef41Sopenharmony_ci  }
11481cb0ef41Sopenharmony_ci}
11491cb0ef41Sopenharmony_ci
11501cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnObjectSlotValue(
11511cb0ef41Sopenharmony_ci    const HeapObjectRef& object, int offset, const ObjectRef& value) {
11521cb0ef41Sopenharmony_ci  RecordDependency(
11531cb0ef41Sopenharmony_ci      zone_->New<ObjectSlotValueDependency>(object, offset, value));
11541cb0ef41Sopenharmony_ci}
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnOwnConstantElement(
11571cb0ef41Sopenharmony_ci    const JSObjectRef& holder, uint32_t index, const ObjectRef& element) {
11581cb0ef41Sopenharmony_ci  RecordDependency(
11591cb0ef41Sopenharmony_ci      zone_->New<OwnConstantElementDependency>(holder, index, element));
11601cb0ef41Sopenharmony_ci}
11611cb0ef41Sopenharmony_ci
11621cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnOwnConstantDataProperty(
11631cb0ef41Sopenharmony_ci    const JSObjectRef& holder, const MapRef& map, Representation representation,
11641cb0ef41Sopenharmony_ci    FieldIndex index, const ObjectRef& value) {
11651cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<OwnConstantDataPropertyDependency>(
11661cb0ef41Sopenharmony_ci      broker_, holder, map, representation, index, value));
11671cb0ef41Sopenharmony_ci}
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnOwnConstantDictionaryProperty(
11701cb0ef41Sopenharmony_ci    const JSObjectRef& holder, InternalIndex index, const ObjectRef& value) {
11711cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<OwnConstantDictionaryPropertyDependency>(
11721cb0ef41Sopenharmony_ci      broker_, holder, index, value));
11731cb0ef41Sopenharmony_ci}
11741cb0ef41Sopenharmony_ci
11751cb0ef41Sopenharmony_ciV8_INLINE void TraceInvalidCompilationDependency(
11761cb0ef41Sopenharmony_ci    const CompilationDependency* d) {
11771cb0ef41Sopenharmony_ci  DCHECK(FLAG_trace_compilation_dependencies);
11781cb0ef41Sopenharmony_ci  DCHECK(!d->IsValid());
11791cb0ef41Sopenharmony_ci  PrintF("Compilation aborted due to invalid dependency: %s\n", d->ToString());
11801cb0ef41Sopenharmony_ci}
11811cb0ef41Sopenharmony_ci
11821cb0ef41Sopenharmony_cibool CompilationDependencies::Commit(Handle<Code> code) {
11831cb0ef41Sopenharmony_ci  if (!PrepareInstall()) return false;
11841cb0ef41Sopenharmony_ci
11851cb0ef41Sopenharmony_ci  {
11861cb0ef41Sopenharmony_ci    PendingDependencies pending_deps(zone_);
11871cb0ef41Sopenharmony_ci    DisallowCodeDependencyChange no_dependency_change;
11881cb0ef41Sopenharmony_ci    for (const CompilationDependency* dep : dependencies_) {
11891cb0ef41Sopenharmony_ci      // Check each dependency's validity again right before installing it,
11901cb0ef41Sopenharmony_ci      // because the first iteration above might have invalidated some
11911cb0ef41Sopenharmony_ci      // dependencies. For example, PrototypePropertyDependency::PrepareInstall
11921cb0ef41Sopenharmony_ci      // can call EnsureHasInitialMap, which can invalidate a
11931cb0ef41Sopenharmony_ci      // StableMapDependency on the prototype object's map.
11941cb0ef41Sopenharmony_ci      if (!dep->IsValid()) {
11951cb0ef41Sopenharmony_ci        if (FLAG_trace_compilation_dependencies) {
11961cb0ef41Sopenharmony_ci          TraceInvalidCompilationDependency(dep);
11971cb0ef41Sopenharmony_ci        }
11981cb0ef41Sopenharmony_ci        dependencies_.clear();
11991cb0ef41Sopenharmony_ci        return false;
12001cb0ef41Sopenharmony_ci      }
12011cb0ef41Sopenharmony_ci      dep->Install(&pending_deps);
12021cb0ef41Sopenharmony_ci    }
12031cb0ef41Sopenharmony_ci    pending_deps.InstallAll(broker_->isolate(), code);
12041cb0ef41Sopenharmony_ci  }
12051cb0ef41Sopenharmony_ci
12061cb0ef41Sopenharmony_ci  // It is even possible that a GC during the above installations invalidated
12071cb0ef41Sopenharmony_ci  // one of the dependencies. However, this should only affect
12081cb0ef41Sopenharmony_ci  //
12091cb0ef41Sopenharmony_ci  // 1. pretenure mode dependencies, or
12101cb0ef41Sopenharmony_ci  // 2. function consistency dependencies,
12111cb0ef41Sopenharmony_ci  //
12121cb0ef41Sopenharmony_ci  // which we assert below. It is safe to return successfully in these cases,
12131cb0ef41Sopenharmony_ci  // because
12141cb0ef41Sopenharmony_ci  //
12151cb0ef41Sopenharmony_ci  // 1. once the code gets executed it will do a stack check that triggers its
12161cb0ef41Sopenharmony_ci  //    deoptimization.
12171cb0ef41Sopenharmony_ci  // 2. since the function state was deemed consistent above, that means the
12181cb0ef41Sopenharmony_ci  //    compilation saw a self-consistent state of the jsfunction.
12191cb0ef41Sopenharmony_ci  if (FLAG_stress_gc_during_compilation) {
12201cb0ef41Sopenharmony_ci    broker_->isolate()->heap()->PreciseCollectAllGarbage(
12211cb0ef41Sopenharmony_ci        Heap::kForcedGC, GarbageCollectionReason::kTesting, kNoGCCallbackFlags);
12221cb0ef41Sopenharmony_ci  }
12231cb0ef41Sopenharmony_ci#ifdef DEBUG
12241cb0ef41Sopenharmony_ci  for (auto dep : dependencies_) {
12251cb0ef41Sopenharmony_ci    CHECK_IMPLIES(!dep->IsValid(),
12261cb0ef41Sopenharmony_ci                  dep->IsPretenureMode() || dep->IsConsistentJSFunctionView());
12271cb0ef41Sopenharmony_ci  }
12281cb0ef41Sopenharmony_ci#endif
12291cb0ef41Sopenharmony_ci
12301cb0ef41Sopenharmony_ci  dependencies_.clear();
12311cb0ef41Sopenharmony_ci  return true;
12321cb0ef41Sopenharmony_ci}
12331cb0ef41Sopenharmony_ci
12341cb0ef41Sopenharmony_cibool CompilationDependencies::PrepareInstall() {
12351cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_predictable)) {
12361cb0ef41Sopenharmony_ci    return PrepareInstallPredictable();
12371cb0ef41Sopenharmony_ci  }
12381cb0ef41Sopenharmony_ci
12391cb0ef41Sopenharmony_ci  for (auto dep : dependencies_) {
12401cb0ef41Sopenharmony_ci    if (!dep->IsValid()) {
12411cb0ef41Sopenharmony_ci      if (FLAG_trace_compilation_dependencies) {
12421cb0ef41Sopenharmony_ci        TraceInvalidCompilationDependency(dep);
12431cb0ef41Sopenharmony_ci      }
12441cb0ef41Sopenharmony_ci      dependencies_.clear();
12451cb0ef41Sopenharmony_ci      return false;
12461cb0ef41Sopenharmony_ci    }
12471cb0ef41Sopenharmony_ci    dep->PrepareInstall();
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci  return true;
12501cb0ef41Sopenharmony_ci}
12511cb0ef41Sopenharmony_ci
12521cb0ef41Sopenharmony_cibool CompilationDependencies::PrepareInstallPredictable() {
12531cb0ef41Sopenharmony_ci  CHECK(FLAG_predictable);
12541cb0ef41Sopenharmony_ci
12551cb0ef41Sopenharmony_ci  std::vector<const CompilationDependency*> deps(dependencies_.begin(),
12561cb0ef41Sopenharmony_ci                                                 dependencies_.end());
12571cb0ef41Sopenharmony_ci  std::sort(deps.begin(), deps.end());
12581cb0ef41Sopenharmony_ci
12591cb0ef41Sopenharmony_ci  for (auto dep : deps) {
12601cb0ef41Sopenharmony_ci    if (!dep->IsValid()) {
12611cb0ef41Sopenharmony_ci      if (FLAG_trace_compilation_dependencies) {
12621cb0ef41Sopenharmony_ci        TraceInvalidCompilationDependency(dep);
12631cb0ef41Sopenharmony_ci      }
12641cb0ef41Sopenharmony_ci      dependencies_.clear();
12651cb0ef41Sopenharmony_ci      return false;
12661cb0ef41Sopenharmony_ci    }
12671cb0ef41Sopenharmony_ci    dep->PrepareInstall();
12681cb0ef41Sopenharmony_ci  }
12691cb0ef41Sopenharmony_ci  return true;
12701cb0ef41Sopenharmony_ci}
12711cb0ef41Sopenharmony_ci
12721cb0ef41Sopenharmony_cinamespace {
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ci// This function expects to never see a JSProxy.
12751cb0ef41Sopenharmony_civoid DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
12761cb0ef41Sopenharmony_ci                                  base::Optional<JSObjectRef> last_prototype) {
12771cb0ef41Sopenharmony_ci  while (true) {
12781cb0ef41Sopenharmony_ci    HeapObjectRef proto = map.prototype();
12791cb0ef41Sopenharmony_ci    if (!proto.IsJSObject()) {
12801cb0ef41Sopenharmony_ci      CHECK_EQ(proto.map().oddball_type(), OddballType::kNull);
12811cb0ef41Sopenharmony_ci      break;
12821cb0ef41Sopenharmony_ci    }
12831cb0ef41Sopenharmony_ci    map = proto.map();
12841cb0ef41Sopenharmony_ci    deps->DependOnStableMap(map);
12851cb0ef41Sopenharmony_ci    if (last_prototype.has_value() && proto.equals(*last_prototype)) break;
12861cb0ef41Sopenharmony_ci  }
12871cb0ef41Sopenharmony_ci}
12881cb0ef41Sopenharmony_ci
12891cb0ef41Sopenharmony_ci}  // namespace
12901cb0ef41Sopenharmony_ci
12911cb0ef41Sopenharmony_ci#define V(Name)                                                     \
12921cb0ef41Sopenharmony_ci  const Name##Dependency* CompilationDependency::As##Name() const { \
12931cb0ef41Sopenharmony_ci    DCHECK(Is##Name());                                             \
12941cb0ef41Sopenharmony_ci    return static_cast<const Name##Dependency*>(this);              \
12951cb0ef41Sopenharmony_ci  }
12961cb0ef41Sopenharmony_ciDEPENDENCY_LIST(V)
12971cb0ef41Sopenharmony_ci#undef V
12981cb0ef41Sopenharmony_ci
12991cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnStablePrototypeChains(
13001cb0ef41Sopenharmony_ci    ZoneVector<MapRef> const& receiver_maps, WhereToStart start,
13011cb0ef41Sopenharmony_ci    base::Optional<JSObjectRef> last_prototype) {
13021cb0ef41Sopenharmony_ci  for (MapRef receiver_map : receiver_maps) {
13031cb0ef41Sopenharmony_ci    if (receiver_map.IsPrimitiveMap()) {
13041cb0ef41Sopenharmony_ci      // Perform the implicit ToObject for primitives here.
13051cb0ef41Sopenharmony_ci      // Implemented according to ES6 section 7.3.2 GetV (V, P).
13061cb0ef41Sopenharmony_ci      // Note: Keep sync'd with AccessInfoFactory::ComputePropertyAccessInfo.
13071cb0ef41Sopenharmony_ci      base::Optional<JSFunctionRef> constructor =
13081cb0ef41Sopenharmony_ci          broker_->target_native_context().GetConstructorFunction(receiver_map);
13091cb0ef41Sopenharmony_ci      receiver_map = constructor.value().initial_map(this);
13101cb0ef41Sopenharmony_ci    }
13111cb0ef41Sopenharmony_ci    if (start == kStartAtReceiver) DependOnStableMap(receiver_map);
13121cb0ef41Sopenharmony_ci    DependOnStablePrototypeChain(this, receiver_map, last_prototype);
13131cb0ef41Sopenharmony_ci  }
13141cb0ef41Sopenharmony_ci}
13151cb0ef41Sopenharmony_ci
13161cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnElementsKinds(
13171cb0ef41Sopenharmony_ci    const AllocationSiteRef& site) {
13181cb0ef41Sopenharmony_ci  AllocationSiteRef current = site;
13191cb0ef41Sopenharmony_ci  while (true) {
13201cb0ef41Sopenharmony_ci    DependOnElementsKind(current);
13211cb0ef41Sopenharmony_ci    if (!current.nested_site().IsAllocationSite()) break;
13221cb0ef41Sopenharmony_ci    current = current.nested_site().AsAllocationSite();
13231cb0ef41Sopenharmony_ci  }
13241cb0ef41Sopenharmony_ci  CHECK_EQ(current.nested_site().AsSmi(), 0);
13251cb0ef41Sopenharmony_ci}
13261cb0ef41Sopenharmony_ci
13271cb0ef41Sopenharmony_civoid CompilationDependencies::DependOnConsistentJSFunctionView(
13281cb0ef41Sopenharmony_ci    const JSFunctionRef& function) {
13291cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<ConsistentJSFunctionViewDependency>(function));
13301cb0ef41Sopenharmony_ci}
13311cb0ef41Sopenharmony_ci
13321cb0ef41Sopenharmony_ciSlackTrackingPrediction::SlackTrackingPrediction(MapRef initial_map,
13331cb0ef41Sopenharmony_ci                                                 int instance_size)
13341cb0ef41Sopenharmony_ci    : instance_size_(instance_size),
13351cb0ef41Sopenharmony_ci      inobject_property_count_(
13361cb0ef41Sopenharmony_ci          (instance_size >> kTaggedSizeLog2) -
13371cb0ef41Sopenharmony_ci          initial_map.GetInObjectPropertiesStartInWords()) {}
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ciSlackTrackingPrediction
13401cb0ef41Sopenharmony_ciCompilationDependencies::DependOnInitialMapInstanceSizePrediction(
13411cb0ef41Sopenharmony_ci    const JSFunctionRef& function) {
13421cb0ef41Sopenharmony_ci  MapRef initial_map = DependOnInitialMap(function);
13431cb0ef41Sopenharmony_ci  int instance_size = function.InitialMapInstanceSizeWithMinSlack(this);
13441cb0ef41Sopenharmony_ci  // Currently, we always install the prediction dependency. If this turns out
13451cb0ef41Sopenharmony_ci  // to be too expensive, we can only install the dependency if slack
13461cb0ef41Sopenharmony_ci  // tracking is active.
13471cb0ef41Sopenharmony_ci  RecordDependency(zone_->New<InitialMapInstanceSizePredictionDependency>(
13481cb0ef41Sopenharmony_ci      function, instance_size));
13491cb0ef41Sopenharmony_ci  CHECK_LE(instance_size, function.initial_map(this).instance_size());
13501cb0ef41Sopenharmony_ci  return SlackTrackingPrediction(initial_map, instance_size);
13511cb0ef41Sopenharmony_ci}
13521cb0ef41Sopenharmony_ci
13531cb0ef41Sopenharmony_ciCompilationDependency const*
13541cb0ef41Sopenharmony_ciCompilationDependencies::TransitionDependencyOffTheRecord(
13551cb0ef41Sopenharmony_ci    const MapRef& target_map) const {
13561cb0ef41Sopenharmony_ci  if (target_map.CanBeDeprecated()) {
13571cb0ef41Sopenharmony_ci    return zone_->New<TransitionDependency>(target_map);
13581cb0ef41Sopenharmony_ci  } else {
13591cb0ef41Sopenharmony_ci    DCHECK(!target_map.is_deprecated());
13601cb0ef41Sopenharmony_ci    return nullptr;
13611cb0ef41Sopenharmony_ci  }
13621cb0ef41Sopenharmony_ci}
13631cb0ef41Sopenharmony_ci
13641cb0ef41Sopenharmony_ciCompilationDependency const*
13651cb0ef41Sopenharmony_ciCompilationDependencies::FieldRepresentationDependencyOffTheRecord(
13661cb0ef41Sopenharmony_ci    const MapRef& map, InternalIndex descriptor,
13671cb0ef41Sopenharmony_ci    Representation representation) const {
13681cb0ef41Sopenharmony_ci  return zone_->New<FieldRepresentationDependency>(map, descriptor,
13691cb0ef41Sopenharmony_ci                                                   representation);
13701cb0ef41Sopenharmony_ci}
13711cb0ef41Sopenharmony_ci
13721cb0ef41Sopenharmony_ciCompilationDependency const*
13731cb0ef41Sopenharmony_ciCompilationDependencies::FieldTypeDependencyOffTheRecord(
13741cb0ef41Sopenharmony_ci    const MapRef& map, InternalIndex descriptor, const ObjectRef& type) const {
13751cb0ef41Sopenharmony_ci  return zone_->New<FieldTypeDependency>(map, descriptor, type);
13761cb0ef41Sopenharmony_ci}
13771cb0ef41Sopenharmony_ci
13781cb0ef41Sopenharmony_ci#ifdef DEBUG
13791cb0ef41Sopenharmony_ci// static
13801cb0ef41Sopenharmony_cibool CompilationDependencies::IsFieldRepresentationDependencyOnMap(
13811cb0ef41Sopenharmony_ci    const CompilationDependency* dep, const Handle<Map>& receiver_map) {
13821cb0ef41Sopenharmony_ci  return dep->IsFieldRepresentation() &&
13831cb0ef41Sopenharmony_ci         dep->AsFieldRepresentation()->DependsOn(receiver_map);
13841cb0ef41Sopenharmony_ci}
13851cb0ef41Sopenharmony_ci#endif  // DEBUG
13861cb0ef41Sopenharmony_ci
13871cb0ef41Sopenharmony_ci#undef DEPENDENCY_LIST
13881cb0ef41Sopenharmony_ci
13891cb0ef41Sopenharmony_ci}  // namespace compiler
13901cb0ef41Sopenharmony_ci}  // namespace internal
13911cb0ef41Sopenharmony_ci}  // namespace v8
1392