LCOV - code coverage report
Current view: top level - src/compiler - compilation-dependencies.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 187 187 100.0 %
Date: 2019-02-19 Functions: 45 45 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/compilation-dependencies.h"
       6             : 
       7             : #include "src/handles-inl.h"
       8             : #include "src/objects-inl.h"
       9             : #include "src/objects/allocation-site-inl.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : namespace compiler {
      14             : 
      15      475817 : CompilationDependencies::CompilationDependencies(Isolate* isolate, Zone* zone)
      16      951634 :     : zone_(zone), dependencies_(zone), isolate_(isolate) {}
      17             : 
      18      484220 : class CompilationDependencies::Dependency : public ZoneObject {
      19             :  public:
      20             :   virtual bool IsValid() const = 0;
      21      475571 :   virtual void PrepareInstall() {}
      22             :   virtual void Install(const MaybeObjectHandle& code) = 0;
      23             : 
      24             : #ifdef DEBUG
      25             :   virtual bool IsPretenureModeDependency() const { return false; }
      26             : #endif
      27             : };
      28             : 
      29             : class InitialMapDependency final : public CompilationDependencies::Dependency {
      30             :  public:
      31             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
      32             :   // longer need to explicitly store the initial map.
      33             :   InitialMapDependency(const JSFunctionRef& function, const MapRef& initial_map)
      34        5276 :       : function_(function), initial_map_(initial_map) {
      35             :     DCHECK(function_.has_initial_map());
      36             :     DCHECK(function_.initial_map().equals(initial_map_));
      37             :   }
      38             : 
      39       10504 :   bool IsValid() const override {
      40       10504 :     Handle<JSFunction> function = function_.object();
      41       31512 :     return function->has_initial_map() &&
      42       42016 :            function->initial_map() == *initial_map_.object();
      43             :   }
      44             : 
      45        5252 :   void Install(const MaybeObjectHandle& code) override {
      46             :     SLOW_DCHECK(IsValid());
      47             :     DependentCode::InstallDependency(function_.isolate(), code,
      48             :                                      initial_map_.object(),
      49       10504 :                                      DependentCode::kInitialMapChangedGroup);
      50        5252 :   }
      51             : 
      52             :  private:
      53             :   JSFunctionRef function_;
      54             :   MapRef initial_map_;
      55             : };
      56             : 
      57             : class PrototypePropertyDependency final
      58             :     : public CompilationDependencies::Dependency {
      59             :  public:
      60             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
      61             :   // longer need to explicitly store the prototype.
      62             :   PrototypePropertyDependency(const JSFunctionRef& function,
      63             :                               const ObjectRef& prototype)
      64        1376 :       : function_(function), prototype_(prototype) {
      65             :     DCHECK(function_.has_prototype());
      66             :     DCHECK(!function_.PrototypeRequiresRuntimeLookup());
      67             :     DCHECK(function_.prototype().equals(prototype_));
      68             :   }
      69             : 
      70        2738 :   bool IsValid() const override {
      71        2738 :     Handle<JSFunction> function = function_.object();
      72       10952 :     return function->has_prototype_slot() && function->has_prototype() &&
      73       10952 :            !function->PrototypeRequiresRuntimeLookup() &&
      74       10952 :            function->prototype() == *prototype_.object();
      75             :   }
      76             : 
      77        1376 :   void PrepareInstall() override {
      78             :     SLOW_DCHECK(IsValid());
      79        1376 :     Handle<JSFunction> function = function_.object();
      80        1376 :     if (!function->has_initial_map()) JSFunction::EnsureHasInitialMap(function);
      81        1376 :   }
      82             : 
      83        1362 :   void Install(const MaybeObjectHandle& code) override {
      84             :     SLOW_DCHECK(IsValid());
      85        1362 :     Handle<JSFunction> function = function_.object();
      86             :     DCHECK(function->has_initial_map());
      87        4086 :     Handle<Map> initial_map(function->initial_map(), function_.isolate());
      88             :     DependentCode::InstallDependency(function_.isolate(), code, initial_map,
      89        1362 :                                      DependentCode::kInitialMapChangedGroup);
      90        1362 :   }
      91             : 
      92             :  private:
      93             :   JSFunctionRef function_;
      94             :   ObjectRef prototype_;
      95             : };
      96             : 
      97             : class StableMapDependency final : public CompilationDependencies::Dependency {
      98             :  public:
      99      166185 :   explicit StableMapDependency(const MapRef& map) : map_(map) {
     100             :     DCHECK(map_.is_stable());
     101             :   }
     102             : 
     103      662626 :   bool IsValid() const override { return map_.object()->is_stable(); }
     104             : 
     105      165628 :   void Install(const MaybeObjectHandle& code) override {
     106             :     SLOW_DCHECK(IsValid());
     107             :     DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
     108      331256 :                                      DependentCode::kPrototypeCheckGroup);
     109      165628 :   }
     110             : 
     111             :  private:
     112             :   MapRef map_;
     113             : };
     114             : 
     115             : class TransitionDependency final : public CompilationDependencies::Dependency {
     116             :  public:
     117       19384 :   explicit TransitionDependency(const MapRef& map) : map_(map) {
     118             :     DCHECK(!map_.is_deprecated());
     119             :   }
     120             : 
     121       77412 :   bool IsValid() const override { return !map_.object()->is_deprecated(); }
     122             : 
     123       19351 :   void Install(const MaybeObjectHandle& code) override {
     124             :     SLOW_DCHECK(IsValid());
     125             :     DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
     126       38702 :                                      DependentCode::kTransitionGroup);
     127       19351 :   }
     128             : 
     129             :  private:
     130             :   MapRef map_;
     131             : };
     132             : 
     133             : class PretenureModeDependency final
     134             :     : public CompilationDependencies::Dependency {
     135             :  public:
     136             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     137             :   // longer need to explicitly store the mode.
     138             :   PretenureModeDependency(const AllocationSiteRef& site, PretenureFlag mode)
     139        7312 :       : site_(site), mode_(mode) {
     140             :     DCHECK_EQ(mode_, site_.GetPretenureMode());
     141             :   }
     142             : 
     143       14438 :   bool IsValid() const override {
     144       28876 :     return mode_ == site_.object()->GetPretenureMode();
     145             :   }
     146             : 
     147        7213 :   void Install(const MaybeObjectHandle& code) override {
     148             :     SLOW_DCHECK(IsValid());
     149             :     DependentCode::InstallDependency(
     150             :         site_.isolate(), code, site_.object(),
     151       14426 :         DependentCode::kAllocationSiteTenuringChangedGroup);
     152        7213 :   }
     153             : 
     154             : #ifdef DEBUG
     155             :   bool IsPretenureModeDependency() const override { return true; }
     156             : #endif
     157             : 
     158             :  private:
     159             :   AllocationSiteRef site_;
     160             :   PretenureFlag mode_;
     161             : };
     162             : 
     163             : class FieldTypeDependency final : public CompilationDependencies::Dependency {
     164             :  public:
     165             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     166             :   // longer need to explicitly store the type.
     167             :   FieldTypeDependency(const MapRef& owner, int descriptor,
     168             :                       const ObjectRef& type)
     169        3440 :       : owner_(owner), descriptor_(descriptor), type_(type) {
     170             :     DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
     171             :     DCHECK(type_.equals(owner_.GetFieldType(descriptor_)));
     172             :   }
     173             : 
     174        6361 :   bool IsValid() const override {
     175             :     DisallowHeapAllocation no_heap_allocation;
     176        6361 :     Handle<Map> owner = owner_.object();
     177        6361 :     Handle<Object> type = type_.object();
     178       19083 :     return *type == owner->instance_descriptors()->GetFieldType(descriptor_);
     179             :   }
     180             : 
     181        2958 :   void Install(const MaybeObjectHandle& code) override {
     182             :     SLOW_DCHECK(IsValid());
     183             :     DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
     184        5916 :                                      DependentCode::kFieldOwnerGroup);
     185        2958 :   }
     186             : 
     187             :  private:
     188             :   MapRef owner_;
     189             :   int descriptor_;
     190             :   ObjectRef type_;
     191             : };
     192             : 
     193             : class FieldConstnessDependency final
     194             :     : public CompilationDependencies::Dependency {
     195             :  public:
     196             :   FieldConstnessDependency(const MapRef& owner, int descriptor)
     197       71599 :       : owner_(owner), descriptor_(descriptor) {
     198             :     DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
     199             :     DCHECK_EQ(PropertyConstness::kConst,
     200             :               owner_.GetPropertyDetails(descriptor_).constness());
     201             :   }
     202             : 
     203      142821 :   bool IsValid() const override {
     204             :     DisallowHeapAllocation no_heap_allocation;
     205      142821 :     Handle<Map> owner = owner_.object();
     206             :     return PropertyConstness::kConst ==
     207      428463 :            owner->instance_descriptors()->GetDetails(descriptor_).constness();
     208             :   }
     209             : 
     210       71386 :   void Install(const MaybeObjectHandle& code) override {
     211             :     SLOW_DCHECK(IsValid());
     212             :     DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
     213      142772 :                                      DependentCode::kFieldOwnerGroup);
     214       71386 :   }
     215             : 
     216             :  private:
     217             :   MapRef owner_;
     218             :   int descriptor_;
     219             : };
     220             : 
     221             : class GlobalPropertyDependency final
     222             :     : public CompilationDependencies::Dependency {
     223             :  public:
     224             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     225             :   // longer need to explicitly store the type and the read_only flag.
     226             :   GlobalPropertyDependency(const PropertyCellRef& cell, PropertyCellType type,
     227             :                            bool read_only)
     228      182339 :       : cell_(cell), type_(type), read_only_(read_only) {
     229             :     DCHECK_EQ(type_, cell_.property_details().cell_type());
     230             :     DCHECK_EQ(read_only_, cell_.property_details().IsReadOnly());
     231             :   }
     232             : 
     233      363489 :   bool IsValid() const override {
     234      363489 :     Handle<PropertyCell> cell = cell_.object();
     235             :     // The dependency is never valid if the cell is 'invalidated'. This is
     236             :     // marked by setting the value to the hole.
     237      726978 :     if (cell->value() == *(cell_.isolate()->factory()->the_hole_value())) {
     238             :       DCHECK(cell->property_details().cell_type() ==
     239             :                  PropertyCellType::kInvalidated ||
     240             :              cell->property_details().cell_type() ==
     241             :                  PropertyCellType::kUninitialized);
     242             :       return false;
     243             :     }
     244     1817400 :     return type_ == cell->property_details().cell_type() &&
     245     1090433 :            read_only_ == cell->property_details().IsReadOnly();
     246             :   }
     247             : 
     248      181706 :   void Install(const MaybeObjectHandle& code) override {
     249             :     SLOW_DCHECK(IsValid());
     250             :     DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
     251      363412 :                                      DependentCode::kPropertyCellChangedGroup);
     252      181706 :   }
     253             : 
     254             :  private:
     255             :   PropertyCellRef cell_;
     256             :   PropertyCellType type_;
     257             :   bool read_only_;
     258             : };
     259             : 
     260             : class ProtectorDependency final : public CompilationDependencies::Dependency {
     261             :  public:
     262       19034 :   explicit ProtectorDependency(const PropertyCellRef& cell) : cell_(cell) {
     263             :     DCHECK_EQ(cell_.value().AsSmi(), Isolate::kProtectorValid);
     264             :   }
     265             : 
     266       38018 :   bool IsValid() const override {
     267       38018 :     Handle<PropertyCell> cell = cell_.object();
     268       38018 :     return cell->value() == Smi::FromInt(Isolate::kProtectorValid);
     269             :   }
     270             : 
     271       19007 :   void Install(const MaybeObjectHandle& code) override {
     272             :     SLOW_DCHECK(IsValid());
     273             :     DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
     274       38014 :                                      DependentCode::kPropertyCellChangedGroup);
     275       19007 :   }
     276             : 
     277             :  private:
     278             :   PropertyCellRef cell_;
     279             : };
     280             : 
     281             : class ElementsKindDependency final
     282             :     : public CompilationDependencies::Dependency {
     283             :  public:
     284             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     285             :   // longer need to explicitly store the elements kind.
     286             :   ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
     287        2999 :       : site_(site), kind_(kind) {
     288             :     DCHECK(AllocationSite::ShouldTrack(kind_));
     289             :     DCHECK_EQ(kind_, site_.PointsToLiteral()
     290             :                          ? site_.boilerplate().value().GetElementsKind()
     291             :                          : site_.GetElementsKind());
     292             :   }
     293             : 
     294        5924 :   bool IsValid() const override {
     295        5924 :     Handle<AllocationSite> site = site_.object();
     296       11848 :     ElementsKind kind = site->PointsToLiteral()
     297        9758 :                             ? site->boilerplate()->GetElementsKind()
     298       17772 :                             : site->GetElementsKind();
     299        5924 :     return kind_ == kind;
     300             :   }
     301             : 
     302        2954 :   void Install(const MaybeObjectHandle& code) override {
     303             :     SLOW_DCHECK(IsValid());
     304             :     DependentCode::InstallDependency(
     305             :         site_.isolate(), code, site_.object(),
     306        5908 :         DependentCode::kAllocationSiteTransitionChangedGroup);
     307        2954 :   }
     308             : 
     309             :  private:
     310             :   AllocationSiteRef site_;
     311             :   ElementsKind kind_;
     312             : };
     313             : 
     314             : class InitialMapInstanceSizePredictionDependency final
     315             :     : public CompilationDependencies::Dependency {
     316             :  public:
     317             :   InitialMapInstanceSizePredictionDependency(const JSFunctionRef& function,
     318             :                                              int instance_size)
     319        5276 :       : function_(function), instance_size_(instance_size) {}
     320             : 
     321       10509 :   bool IsValid() const override {
     322             :     // The dependency is valid if the prediction is the same as the current
     323             :     // slack tracking result.
     324       21018 :     if (!function_.object()->has_initial_map()) return false;
     325       21008 :     int instance_size = function_.object()->ComputeInstanceSizeWithMinSlack(
     326       21008 :         function_.isolate());
     327       10504 :     return instance_size == instance_size_;
     328             :   }
     329             : 
     330        5252 :   void PrepareInstall() override {
     331             :     SLOW_DCHECK(IsValid());
     332       10504 :     function_.object()->CompleteInobjectSlackTrackingIfActive();
     333        5252 :   }
     334             : 
     335        5252 :   void Install(const MaybeObjectHandle& code) override {
     336             :     SLOW_DCHECK(IsValid());
     337             :     DCHECK(!function_.object()
     338             :                 ->initial_map()
     339             :                 ->IsInobjectSlackTrackingInProgress());
     340        5252 :   }
     341             : 
     342             :  private:
     343             :   JSFunctionRef function_;
     344             :   int instance_size_;
     345             : };
     346             : 
     347        5276 : MapRef CompilationDependencies::DependOnInitialMap(
     348             :     const JSFunctionRef& function) {
     349        5276 :   MapRef map = function.initial_map();
     350       15828 :   dependencies_.push_front(new (zone_) InitialMapDependency(function, map));
     351        5276 :   return map;
     352             : }
     353             : 
     354        1376 : ObjectRef CompilationDependencies::DependOnPrototypeProperty(
     355             :     const JSFunctionRef& function) {
     356        1376 :   ObjectRef prototype = function.prototype();
     357             :   dependencies_.push_front(
     358        4128 :       new (zone_) PrototypePropertyDependency(function, prototype));
     359        1376 :   return prototype;
     360             : }
     361             : 
     362      168045 : void CompilationDependencies::DependOnStableMap(const MapRef& map) {
     363      168045 :   if (map.CanTransition()) {
     364      498555 :     dependencies_.push_front(new (zone_) StableMapDependency(map));
     365             :   } else {
     366             :     DCHECK(map.is_stable());
     367             :   }
     368      168045 : }
     369             : 
     370       21771 : void CompilationDependencies::DependOnTransition(const MapRef& target_map) {
     371       21771 :   if (target_map.CanBeDeprecated()) {
     372       58152 :     dependencies_.push_front(new (zone_) TransitionDependency(target_map));
     373             :   } else {
     374             :     DCHECK(!target_map.is_deprecated());
     375             :   }
     376       21771 : }
     377             : 
     378        7312 : PretenureFlag CompilationDependencies::DependOnPretenureMode(
     379             :     const AllocationSiteRef& site) {
     380        7312 :   PretenureFlag mode = site.GetPretenureMode();
     381       21936 :   dependencies_.push_front(new (zone_) PretenureModeDependency(site, mode));
     382        7312 :   return mode;
     383             : }
     384             : 
     385       71639 : PropertyConstness CompilationDependencies::DependOnFieldConstness(
     386             :     const MapRef& map, int descriptor) {
     387       71639 :   MapRef owner = map.FindFieldOwner(descriptor);
     388             :   PropertyConstness constness =
     389      143278 :       owner.GetPropertyDetails(descriptor).constness();
     390       71639 :   if (constness == PropertyConstness::kMutable) return constness;
     391             : 
     392             :   // If the map can have fast elements transitions, then the field can be only
     393             :   // considered constant if the map does not transition.
     394      143198 :   if (Map::CanHaveFastTransitionableElementsKind(map.instance_type())) {
     395             :     // If the map can already transition away, let us report the field as
     396             :     // mutable.
     397       15583 :     if (!map.is_stable()) {
     398             :       return PropertyConstness::kMutable;
     399             :     }
     400       15583 :     DependOnStableMap(map);
     401             :   }
     402             : 
     403             :   DCHECK_EQ(constness, PropertyConstness::kConst);
     404             :   dependencies_.push_front(new (zone_)
     405      214797 :                                FieldConstnessDependency(owner, descriptor));
     406       71599 :   return PropertyConstness::kConst;
     407             : }
     408             : 
     409        3440 : void CompilationDependencies::DependOnFieldType(const MapRef& map,
     410             :                                                 int descriptor) {
     411        3440 :   MapRef owner = map.FindFieldOwner(descriptor);
     412        3440 :   ObjectRef type = owner.GetFieldType(descriptor);
     413             :   DCHECK(type.equals(map.GetFieldType(descriptor)));
     414             :   dependencies_.push_front(new (zone_)
     415       10320 :                                FieldTypeDependency(owner, descriptor, type));
     416        3440 : }
     417             : 
     418      182339 : void CompilationDependencies::DependOnGlobalProperty(
     419             :     const PropertyCellRef& cell) {
     420      364678 :   PropertyCellType type = cell.property_details().cell_type();
     421      364678 :   bool read_only = cell.property_details().IsReadOnly();
     422             :   dependencies_.push_front(new (zone_)
     423      547017 :                                GlobalPropertyDependency(cell, type, read_only));
     424      182339 : }
     425             : 
     426       19034 : void CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
     427       57102 :   dependencies_.push_front(new (zone_) ProtectorDependency(cell));
     428       19034 : }
     429             : 
     430        7536 : void CompilationDependencies::DependOnElementsKind(
     431             :     const AllocationSiteRef& site) {
     432             :   // Do nothing if the object doesn't have any useful element transitions left.
     433        7536 :   ElementsKind kind = site.PointsToLiteral()
     434       19486 :                           ? site.boilerplate().value().GetElementsKind()
     435       15072 :                           : site.GetElementsKind();
     436        7536 :   if (AllocationSite::ShouldTrack(kind)) {
     437        8997 :     dependencies_.push_front(new (zone_) ElementsKindDependency(site, kind));
     438             :   }
     439        7536 : }
     440             : 
     441         465 : bool CompilationDependencies::AreValid() const {
     442        1325 :   for (auto dep : dependencies_) {
     443         495 :     if (!dep->IsValid()) return false;
     444             :   }
     445             :   return true;
     446             : }
     447             : 
     448      456574 : bool CompilationDependencies::Commit(Handle<Code> code) {
     449     1395347 :   for (auto dep : dependencies_) {
     450      482243 :     if (!dep->IsValid()) {
     451             :       dependencies_.clear();
     452             :       return false;
     453             :     }
     454      482199 :     dep->PrepareInstall();
     455             :   }
     456             : 
     457             :   DisallowCodeDependencyChange no_dependency_change;
     458     1395129 :   for (auto dep : dependencies_) {
     459             :     // Check each dependency's validity again right before installing it,
     460             :     // because the first iteration above might have invalidated some
     461             :     // dependencies. For example, PrototypePropertyDependency::PrepareInstall
     462             :     // can call EnsureHasInitialMap, which can invalidate a StableMapDependency
     463             :     // on the prototype object's map.
     464      482083 :     if (!dep->IsValid()) {
     465             :       dependencies_.clear();
     466             :       return false;
     467             :     }
     468      482069 :     dep->Install(MaybeObjectHandle::Weak(code));
     469             :   }
     470             : 
     471             :   // It is even possible that a GC during the above installations invalidated
     472             :   // one of the dependencies. However, this should only affect pretenure mode
     473             :   // dependencies, which we assert below. It is safe to return successfully in
     474             :   // these cases, because once the code gets executed it will do a stack check
     475             :   // that triggers its deoptimization.
     476      456516 :   if (FLAG_stress_gc_during_compilation) {
     477             :     isolate_->heap()->PreciseCollectAllGarbage(
     478             :         Heap::kNoGCFlags, GarbageCollectionReason::kTesting,
     479           5 :         kGCCallbackFlagForced);
     480             :   }
     481             : #ifdef DEBUG
     482             :   for (auto dep : dependencies_) {
     483             :     CHECK_IMPLIES(!dep->IsValid(), dep->IsPretenureModeDependency());
     484             :   }
     485             : #endif
     486             : 
     487             :   dependencies_.clear();
     488      456516 :   return true;
     489             : }
     490             : 
     491             : namespace {
     492             : // This function expects to never see a JSProxy.
     493       57985 : void DependOnStablePrototypeChain(JSHeapBroker* broker,
     494             :                                   CompilationDependencies* deps, MapRef map,
     495             :                                   const JSObjectRef& last_prototype) {
     496             :   while (true) {
     497       89379 :     map.SerializePrototype();
     498       89379 :     JSObjectRef proto = map.prototype().AsJSObject();
     499       89379 :     map = proto.map();
     500       89379 :     deps->DependOnStableMap(map);
     501       89379 :     if (proto.equals(last_prototype)) break;
     502             :   }
     503       57985 : }
     504             : }  // namespace
     505             : 
     506       55408 : void CompilationDependencies::DependOnStablePrototypeChains(
     507             :     JSHeapBroker* broker, std::vector<Handle<Map>> const& receiver_maps,
     508             :     const JSObjectRef& holder) {
     509             :   // Determine actual holder and perform prototype chain checks.
     510      168801 :   for (auto map : receiver_maps) {
     511             :     MapRef receiver_map(broker, map);
     512       57985 :     if (receiver_map.IsPrimitiveMap()) {
     513             :       // Perform the implicit ToObject for primitives here.
     514             :       // Implemented according to ES6 section 7.3.2 GetV (V, P).
     515             :       base::Optional<JSFunctionRef> constructor =
     516        7991 :           broker->native_context().GetConstructorFunction(receiver_map);
     517        7991 :       if (constructor.has_value()) receiver_map = constructor->initial_map();
     518             :     }
     519       57985 :     DependOnStablePrototypeChain(broker, this, receiver_map, holder);
     520             :   }
     521       55408 : }
     522             : 
     523        5751 : void CompilationDependencies::DependOnElementsKinds(
     524             :     const AllocationSiteRef& site) {
     525        5751 :   AllocationSiteRef current = site;
     526             :   while (true) {
     527        5975 :     DependOnElementsKind(current);
     528        5975 :     if (!current.nested_site().IsAllocationSite()) break;
     529         224 :     current = current.nested_site().AsAllocationSite();
     530             :   }
     531         224 :   CHECK_EQ(current.nested_site().AsSmi(), 0);
     532        5751 : }
     533             : 
     534        1024 : SlackTrackingPrediction::SlackTrackingPrediction(MapRef initial_map,
     535             :                                                  int instance_size)
     536             :     : instance_size_(instance_size),
     537             :       inobject_property_count_(
     538       12600 :           (instance_size >> kTaggedSizeLog2) -
     539        8348 :           initial_map.GetInObjectPropertiesStartInWords()) {}
     540             : 
     541             : SlackTrackingPrediction
     542        5276 : CompilationDependencies::DependOnInitialMapInstanceSizePrediction(
     543             :     const JSFunctionRef& function) {
     544        5276 :   MapRef initial_map = DependOnInitialMap(function);
     545        5276 :   int instance_size = function.InitialMapInstanceSizeWithMinSlack();
     546             :   // Currently, we always install the prediction dependency. If this turns out
     547             :   // to be too expensive, we can only install the dependency if slack
     548             :   // tracking is active.
     549             :   dependencies_.push_front(
     550             :       new (zone_)
     551       15828 :           InitialMapInstanceSizePredictionDependency(function, instance_size));
     552             :   DCHECK_LE(instance_size, function.initial_map().instance_size());
     553        5276 :   return SlackTrackingPrediction(initial_map, instance_size);
     554             : }
     555             : 
     556             : }  // namespace compiler
     557             : }  // namespace internal
     558      178779 : }  // namespace v8

Generated by: LCOV version 1.10