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