LCOV - code coverage report
Current view: top level - src/compiler - compilation-dependencies.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 224 224 100.0 %
Date: 2019-03-21 Functions: 51 51 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      482967 : CompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
      16             :                                                  Zone* zone)
      17      965934 :     : zone_(zone), broker_(broker), dependencies_(zone) {}
      18             : 
      19      476583 : class CompilationDependencies::Dependency : public ZoneObject {
      20             :  public:
      21             :   virtual bool IsValid() const = 0;
      22      467066 :   virtual void PrepareInstall() {}
      23             :   virtual void Install(const MaybeObjectHandle& code) = 0;
      24             : 
      25             : #ifdef DEBUG
      26             :   virtual bool IsPretenureModeDependency() const { return false; }
      27             : #endif
      28             : };
      29             : 
      30             : class InitialMapDependency final : public CompilationDependencies::Dependency {
      31             :  public:
      32             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
      33             :   // longer need to explicitly store the initial map.
      34             :   InitialMapDependency(const JSFunctionRef& function, const MapRef& initial_map)
      35        5058 :       : function_(function), initial_map_(initial_map) {
      36             :     DCHECK(function_.has_initial_map());
      37             :     DCHECK(function_.initial_map().equals(initial_map_));
      38             :   }
      39             : 
      40       10053 :   bool IsValid() const override {
      41       10053 :     Handle<JSFunction> function = function_.object();
      42       20106 :     return function->has_initial_map() &&
      43       20106 :            function->initial_map() == *initial_map_.object();
      44             :   }
      45             : 
      46        5025 :   void Install(const MaybeObjectHandle& code) override {
      47             :     SLOW_DCHECK(IsValid());
      48       15075 :     DependentCode::InstallDependency(function_.isolate(), code,
      49             :                                      initial_map_.object(),
      50        5025 :                                      DependentCode::kInitialMapChangedGroup);
      51        5025 :   }
      52             : 
      53             :  private:
      54             :   JSFunctionRef function_;
      55             :   MapRef initial_map_;
      56             : };
      57             : 
      58             : class PrototypePropertyDependency final
      59             :     : public CompilationDependencies::Dependency {
      60             :  public:
      61             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
      62             :   // longer need to explicitly store the prototype.
      63             :   PrototypePropertyDependency(const JSFunctionRef& function,
      64             :                               const ObjectRef& prototype)
      65        1319 :       : function_(function), prototype_(prototype) {
      66             :     DCHECK(function_.has_prototype());
      67             :     DCHECK(!function_.PrototypeRequiresRuntimeLookup());
      68             :     DCHECK(function_.prototype().equals(prototype_));
      69             :   }
      70             : 
      71        2618 :   bool IsValid() const override {
      72        2618 :     Handle<JSFunction> function = function_.object();
      73       10472 :     return function->has_prototype_slot() && function->has_prototype() &&
      74        7854 :            !function->PrototypeRequiresRuntimeLookup() &&
      75        7854 :            function->prototype() == *prototype_.object();
      76             :   }
      77             : 
      78        1316 :   void PrepareInstall() override {
      79             :     SLOW_DCHECK(IsValid());
      80        1316 :     Handle<JSFunction> function = function_.object();
      81        1316 :     if (!function->has_initial_map()) JSFunction::EnsureHasInitialMap(function);
      82        1316 :   }
      83             : 
      84        1302 :   void Install(const MaybeObjectHandle& code) override {
      85             :     SLOW_DCHECK(IsValid());
      86        1302 :     Handle<JSFunction> function = function_.object();
      87             :     DCHECK(function->has_initial_map());
      88        1302 :     Handle<Map> initial_map(function->initial_map(), function_.isolate());
      89        2604 :     DependentCode::InstallDependency(function_.isolate(), code, initial_map,
      90        1302 :                                      DependentCode::kInitialMapChangedGroup);
      91        1302 :   }
      92             : 
      93             :  private:
      94             :   JSFunctionRef function_;
      95             :   ObjectRef prototype_;
      96             : };
      97             : 
      98             : class StableMapDependency final : public CompilationDependencies::Dependency {
      99             :  public:
     100      158757 :   explicit StableMapDependency(const MapRef& map) : map_(map) {
     101             :     DCHECK(map_.is_stable());
     102             :   }
     103             : 
     104      631984 :   bool IsValid() const override { return map_.object()->is_stable(); }
     105             : 
     106      157963 :   void Install(const MaybeObjectHandle& code) override {
     107             :     SLOW_DCHECK(IsValid());
     108      473889 :     DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
     109      157963 :                                      DependentCode::kPrototypeCheckGroup);
     110      157963 :   }
     111             : 
     112             :  private:
     113             :   MapRef map_;
     114             : };
     115             : 
     116             : class TransitionDependency final : public CompilationDependencies::Dependency {
     117             :  public:
     118       19102 :   explicit TransitionDependency(const MapRef& map) : map_(map) {
     119             :     DCHECK(!map_.is_deprecated());
     120             :   }
     121             : 
     122       76312 :   bool IsValid() const override { return !map_.object()->is_deprecated(); }
     123             : 
     124       19076 :   void Install(const MaybeObjectHandle& code) override {
     125             :     SLOW_DCHECK(IsValid());
     126       57228 :     DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
     127       19076 :                                      DependentCode::kTransitionGroup);
     128       19076 :   }
     129             : 
     130             :  private:
     131             :   MapRef map_;
     132             : };
     133             : 
     134             : class PretenureModeDependency final
     135             :     : public CompilationDependencies::Dependency {
     136             :  public:
     137             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     138             :   // longer need to explicitly store the mode.
     139             :   PretenureModeDependency(const AllocationSiteRef& site,
     140             :                           AllocationType allocation)
     141        7250 :       : site_(site), allocation_(allocation) {
     142             :     DCHECK_EQ(allocation, site_.GetAllocationType());
     143             :   }
     144             : 
     145       14259 :   bool IsValid() const override {
     146       28518 :     return allocation_ == site_.object()->GetAllocationType();
     147             :   }
     148             : 
     149        7123 :   void Install(const MaybeObjectHandle& code) override {
     150             :     SLOW_DCHECK(IsValid());
     151       21369 :     DependentCode::InstallDependency(
     152             :         site_.isolate(), code, site_.object(),
     153        7123 :         DependentCode::kAllocationSiteTenuringChangedGroup);
     154        7123 :   }
     155             : 
     156             : #ifdef DEBUG
     157             :   bool IsPretenureModeDependency() const override { return true; }
     158             : #endif
     159             : 
     160             :  private:
     161             :   AllocationSiteRef site_;
     162             :   AllocationType allocation_;
     163             : };
     164             : 
     165             : class FieldTypeDependency final : public CompilationDependencies::Dependency {
     166             :  public:
     167             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     168             :   // longer need to explicitly store the type.
     169             :   FieldTypeDependency(const MapRef& owner, int descriptor,
     170             :                       const ObjectRef& type)
     171        4495 :       : owner_(owner), descriptor_(descriptor), type_(type) {
     172             :     DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
     173             :     DCHECK(type_.equals(owner_.GetFieldType(descriptor_)));
     174             :   }
     175             : 
     176        8552 :   bool IsValid() const override {
     177             :     DisallowHeapAllocation no_heap_allocation;
     178        8552 :     Handle<Map> owner = owner_.object();
     179        8552 :     Handle<Object> type = type_.object();
     180       25656 :     return *type == owner->instance_descriptors()->GetFieldType(descriptor_);
     181             :   }
     182             : 
     183        4098 :   void Install(const MaybeObjectHandle& code) override {
     184             :     SLOW_DCHECK(IsValid());
     185       12294 :     DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
     186        4098 :                                      DependentCode::kFieldOwnerGroup);
     187        4098 :   }
     188             : 
     189             :  private:
     190             :   MapRef owner_;
     191             :   int descriptor_;
     192             :   ObjectRef type_;
     193             : };
     194             : 
     195             : class FieldConstnessDependency final
     196             :     : public CompilationDependencies::Dependency {
     197             :  public:
     198             :   FieldConstnessDependency(const MapRef& owner, int descriptor)
     199       68882 :       : owner_(owner), descriptor_(descriptor) {
     200             :     DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
     201             :     DCHECK_EQ(PropertyConstness::kConst,
     202             :               owner_.GetPropertyDetails(descriptor_).constness());
     203             :   }
     204             : 
     205      137093 :   bool IsValid() const override {
     206             :     DisallowHeapAllocation no_heap_allocation;
     207      137093 :     Handle<Map> owner = owner_.object();
     208             :     return PropertyConstness::kConst ==
     209      411279 :            owner->instance_descriptors()->GetDetails(descriptor_).constness();
     210             :   }
     211             : 
     212       68524 :   void Install(const MaybeObjectHandle& code) override {
     213             :     SLOW_DCHECK(IsValid());
     214      205572 :     DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
     215       68524 :                                      DependentCode::kFieldOwnerGroup);
     216       68524 :   }
     217             : 
     218             :  private:
     219             :   MapRef owner_;
     220             :   int descriptor_;
     221             : };
     222             : 
     223             : class GlobalPropertyDependency final
     224             :     : public CompilationDependencies::Dependency {
     225             :  public:
     226             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     227             :   // longer need to explicitly store the type and the read_only flag.
     228             :   GlobalPropertyDependency(const PropertyCellRef& cell, PropertyCellType type,
     229             :                            bool read_only)
     230      184208 :       : cell_(cell), type_(type), read_only_(read_only) {
     231             :     DCHECK_EQ(type_, cell_.property_details().cell_type());
     232             :     DCHECK_EQ(read_only_, cell_.property_details().IsReadOnly());
     233             :   }
     234             : 
     235      365782 :   bool IsValid() const override {
     236      365782 :     Handle<PropertyCell> cell = cell_.object();
     237             :     // The dependency is never valid if the cell is 'invalidated'. This is
     238             :     // marked by setting the value to the hole.
     239      731564 :     if (cell->value() == *(cell_.isolate()->factory()->the_hole_value())) {
     240             :       DCHECK(cell->property_details().cell_type() ==
     241             :                  PropertyCellType::kInvalidated ||
     242             :              cell->property_details().cell_type() ==
     243             :                  PropertyCellType::kUninitialized);
     244             :       return false;
     245             :     }
     246     1097318 :     return type_ == cell->property_details().cell_type() &&
     247      365770 :            read_only_ == cell->property_details().IsReadOnly();
     248             :   }
     249             : 
     250      182845 :   void Install(const MaybeObjectHandle& code) override {
     251             :     SLOW_DCHECK(IsValid());
     252      548535 :     DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
     253      182845 :                                      DependentCode::kPropertyCellChangedGroup);
     254      182845 :   }
     255             : 
     256             :  private:
     257             :   PropertyCellRef cell_;
     258             :   PropertyCellType type_;
     259             :   bool read_only_;
     260             : };
     261             : 
     262             : class ProtectorDependency final : public CompilationDependencies::Dependency {
     263             :  public:
     264       19570 :   explicit ProtectorDependency(const PropertyCellRef& cell) : cell_(cell) {
     265             :     DCHECK_EQ(cell_.value().AsSmi(), Isolate::kProtectorValid);
     266             :   }
     267             : 
     268       38868 :   bool IsValid() const override {
     269       38868 :     Handle<PropertyCell> cell = cell_.object();
     270       38868 :     return cell->value() == Smi::FromInt(Isolate::kProtectorValid);
     271             :   }
     272             : 
     273       19432 :   void Install(const MaybeObjectHandle& code) override {
     274             :     SLOW_DCHECK(IsValid());
     275       58296 :     DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
     276       19432 :                                      DependentCode::kPropertyCellChangedGroup);
     277       19432 :   }
     278             : 
     279             :  private:
     280             :   PropertyCellRef cell_;
     281             : };
     282             : 
     283             : class ElementsKindDependency final
     284             :     : public CompilationDependencies::Dependency {
     285             :  public:
     286             :   // TODO(neis): Once the concurrent compiler frontend is always-on, we no
     287             :   // longer need to explicitly store the elements kind.
     288             :   ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
     289        2884 :       : site_(site), kind_(kind) {
     290             :     DCHECK(AllocationSite::ShouldTrack(kind_));
     291             :     DCHECK_EQ(kind_, site_.PointsToLiteral()
     292             :                          ? site_.boilerplate().value().GetElementsKind()
     293             :                          : site_.GetElementsKind());
     294             :   }
     295             : 
     296        5691 :   bool IsValid() const override {
     297        5691 :     Handle<AllocationSite> site = site_.object();
     298             :     ElementsKind kind = site->PointsToLiteral()
     299        9461 :                             ? site->boilerplate()->GetElementsKind()
     300        9461 :                             : site->GetElementsKind();
     301        5691 :     return kind_ == kind;
     302             :   }
     303             : 
     304        2837 :   void Install(const MaybeObjectHandle& code) override {
     305             :     SLOW_DCHECK(IsValid());
     306        8511 :     DependentCode::InstallDependency(
     307             :         site_.isolate(), code, site_.object(),
     308        2837 :         DependentCode::kAllocationSiteTransitionChangedGroup);
     309        2837 :   }
     310             : 
     311             :  private:
     312             :   AllocationSiteRef site_;
     313             :   ElementsKind kind_;
     314             : };
     315             : 
     316             : class InitialMapInstanceSizePredictionDependency final
     317             :     : public CompilationDependencies::Dependency {
     318             :  public:
     319             :   InitialMapInstanceSizePredictionDependency(const JSFunctionRef& function,
     320             :                                              int instance_size)
     321        5058 :       : function_(function), instance_size_(instance_size) {}
     322             : 
     323       10059 :   bool IsValid() const override {
     324             :     // The dependency is valid if the prediction is the same as the current
     325             :     // slack tracking result.
     326       20118 :     if (!function_.object()->has_initial_map()) return false;
     327       30159 :     int instance_size = function_.object()->ComputeInstanceSizeWithMinSlack(
     328       10053 :         function_.isolate());
     329       10053 :     return instance_size == instance_size_;
     330             :   }
     331             : 
     332        5028 :   void PrepareInstall() override {
     333             :     SLOW_DCHECK(IsValid());
     334       10056 :     function_.object()->CompleteInobjectSlackTrackingIfActive();
     335        5028 :   }
     336             : 
     337        5025 :   void Install(const MaybeObjectHandle& code) override {
     338             :     SLOW_DCHECK(IsValid());
     339             :     DCHECK(!function_.object()
     340             :                 ->initial_map()
     341             :                 ->IsInobjectSlackTrackingInProgress());
     342        5025 :   }
     343             : 
     344             :  private:
     345             :   JSFunctionRef function_;
     346             :   int instance_size_;
     347             : };
     348             : 
     349        5058 : MapRef CompilationDependencies::DependOnInitialMap(
     350             :     const JSFunctionRef& function) {
     351        5058 :   MapRef map = function.initial_map();
     352       15174 :   dependencies_.push_front(new (zone_) InitialMapDependency(function, map));
     353        5058 :   return map;
     354             : }
     355             : 
     356        1319 : ObjectRef CompilationDependencies::DependOnPrototypeProperty(
     357             :     const JSFunctionRef& function) {
     358        1319 :   ObjectRef prototype = function.prototype();
     359        2638 :   dependencies_.push_front(
     360        1319 :       new (zone_) PrototypePropertyDependency(function, prototype));
     361        1319 :   return prototype;
     362             : }
     363             : 
     364      160811 : void CompilationDependencies::DependOnStableMap(const MapRef& map) {
     365      160811 :   if (map.CanTransition()) {
     366      476271 :     dependencies_.push_front(new (zone_) StableMapDependency(map));
     367             :   } else {
     368             :     DCHECK(map.is_stable());
     369             :   }
     370      160811 : }
     371             : 
     372       21490 : void CompilationDependencies::DependOnTransition(const MapRef& target_map) {
     373       21490 :   if (target_map.CanBeDeprecated()) {
     374       57306 :     dependencies_.push_front(new (zone_) TransitionDependency(target_map));
     375             :   } else {
     376             :     DCHECK(!target_map.is_deprecated());
     377             :   }
     378       21490 : }
     379             : 
     380        7250 : AllocationType CompilationDependencies::DependOnPretenureMode(
     381             :     const AllocationSiteRef& site) {
     382        7250 :   AllocationType allocation = site.GetAllocationType();
     383       21750 :   dependencies_.push_front(new (zone_)
     384             :                                PretenureModeDependency(site, allocation));
     385        7250 :   return allocation;
     386             : }
     387             : 
     388       68914 : PropertyConstness CompilationDependencies::DependOnFieldConstness(
     389             :     const MapRef& map, int descriptor) {
     390       68914 :   MapRef owner = map.FindFieldOwner(descriptor);
     391             :   PropertyConstness constness =
     392      137828 :       owner.GetPropertyDetails(descriptor).constness();
     393       68914 :   if (constness == PropertyConstness::kMutable) return constness;
     394             : 
     395             :   // If the map can have fast elements transitions, then the field can be only
     396             :   // considered constant if the map does not transition.
     397      137764 :   if (Map::CanHaveFastTransitionableElementsKind(map.instance_type())) {
     398             :     // If the map can already transition away, let us report the field as
     399             :     // mutable.
     400       13079 :     if (!map.is_stable()) {
     401             :       return PropertyConstness::kMutable;
     402             :     }
     403       13079 :     DependOnStableMap(map);
     404             :   }
     405             : 
     406             :   DCHECK_EQ(constness, PropertyConstness::kConst);
     407      206646 :   dependencies_.push_front(new (zone_)
     408             :                                FieldConstnessDependency(owner, descriptor));
     409       68882 :   return PropertyConstness::kConst;
     410             : }
     411             : 
     412        4495 : void CompilationDependencies::DependOnFieldType(const MapRef& map,
     413             :                                                 int descriptor) {
     414        4495 :   MapRef owner = map.FindFieldOwner(descriptor);
     415        4495 :   ObjectRef type = owner.GetFieldType(descriptor);
     416             :   DCHECK(type.equals(map.GetFieldType(descriptor)));
     417       13485 :   dependencies_.push_front(new (zone_)
     418             :                                FieldTypeDependency(owner, descriptor, type));
     419        4495 : }
     420             : 
     421      184208 : void CompilationDependencies::DependOnGlobalProperty(
     422             :     const PropertyCellRef& cell) {
     423      368416 :   PropertyCellType type = cell.property_details().cell_type();
     424      368416 :   bool read_only = cell.property_details().IsReadOnly();
     425      552624 :   dependencies_.push_front(new (zone_)
     426             :                                GlobalPropertyDependency(cell, type, read_only));
     427      184208 : }
     428             : 
     429       20489 : bool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
     430       20489 :   if (cell.value().AsSmi() != Isolate::kProtectorValid) return false;
     431       58710 :   dependencies_.push_front(new (zone_) ProtectorDependency(cell));
     432       19570 :   return true;
     433             : }
     434             : 
     435        8197 : bool CompilationDependencies::DependOnArrayBufferDetachingProtector() {
     436        8197 :   return DependOnProtector(PropertyCellRef(
     437             :       broker_,
     438       24591 :       broker_->isolate()->factory()->array_buffer_detaching_protector()));
     439             : }
     440             : 
     441         738 : bool CompilationDependencies::DependOnArrayIteratorProtector() {
     442         738 :   return DependOnProtector(PropertyCellRef(
     443        2214 :       broker_, broker_->isolate()->factory()->array_iterator_protector()));
     444             : }
     445             : 
     446         773 : bool CompilationDependencies::DependOnArraySpeciesProtector() {
     447         773 :   return DependOnProtector(PropertyCellRef(
     448        2319 :       broker_, broker_->isolate()->factory()->array_species_protector()));
     449             : }
     450             : 
     451        6411 : bool CompilationDependencies::DependOnNoElementsProtector() {
     452        6411 :   return DependOnProtector(PropertyCellRef(
     453       19233 :       broker_, broker_->isolate()->factory()->no_elements_protector()));
     454             : }
     455             : 
     456        3999 : bool CompilationDependencies::DependOnPromiseHookProtector() {
     457        3999 :   return DependOnProtector(PropertyCellRef(
     458       11997 :       broker_, broker_->isolate()->factory()->promise_hook_protector()));
     459             : }
     460             : 
     461         228 : bool CompilationDependencies::DependOnPromiseSpeciesProtector() {
     462         228 :   return DependOnProtector(PropertyCellRef(
     463         684 :       broker_, broker_->isolate()->factory()->promise_species_protector()));
     464             : }
     465             : 
     466         109 : bool CompilationDependencies::DependOnPromiseThenProtector() {
     467         109 :   return DependOnProtector(PropertyCellRef(
     468         327 :       broker_, broker_->isolate()->factory()->promise_then_protector()));
     469             : }
     470             : 
     471        7498 : void CompilationDependencies::DependOnElementsKind(
     472             :     const AllocationSiteRef& site) {
     473             :   // Do nothing if the object doesn't have any useful element transitions left.
     474        7498 :   ElementsKind kind = site.PointsToLiteral()
     475       19542 :                           ? site.boilerplate().value().GetElementsKind()
     476       14996 :                           : site.GetElementsKind();
     477        7498 :   if (AllocationSite::ShouldTrack(kind)) {
     478        8652 :     dependencies_.push_front(new (zone_) ElementsKindDependency(site, kind));
     479             :   }
     480        7498 : }
     481             : 
     482         372 : bool CompilationDependencies::AreValid() const {
     483         688 :   for (auto dep : dependencies_) {
     484         396 :     if (!dep->IsValid()) return false;
     485             :   }
     486             :   return true;
     487             : }
     488             : 
     489      463634 : bool CompilationDependencies::Commit(Handle<Code> code) {
     490      937044 :   for (auto dep : dependencies_) {
     491      473463 :     if (!dep->IsValid()) {
     492             :       dependencies_.clear();
     493             :       return false;
     494             :     }
     495      473410 :     dep->PrepareInstall();
     496             :   }
     497             : 
     498             :   DisallowCodeDependencyChange no_dependency_change;
     499      936831 :   for (auto dep : dependencies_) {
     500             :     // Check each dependency's validity again right before installing it,
     501             :     // because the first iteration above might have invalidated some
     502             :     // dependencies. For example, PrototypePropertyDependency::PrepareInstall
     503             :     // can call EnsureHasInitialMap, which can invalidate a StableMapDependency
     504             :     // on the prototype object's map.
     505      473264 :     if (!dep->IsValid()) {
     506             :       dependencies_.clear();
     507             :       return false;
     508             :     }
     509      473250 :     dep->Install(MaybeObjectHandle::Weak(code));
     510             :   }
     511             : 
     512             :   // It is even possible that a GC during the above installations invalidated
     513             :   // one of the dependencies. However, this should only affect pretenure mode
     514             :   // dependencies, which we assert below. It is safe to return successfully in
     515             :   // these cases, because once the code gets executed it will do a stack check
     516             :   // that triggers its deoptimization.
     517      463567 :   if (FLAG_stress_gc_during_compilation) {
     518           2 :     broker_->isolate()->heap()->PreciseCollectAllGarbage(
     519             :         Heap::kNoGCFlags, GarbageCollectionReason::kTesting,
     520           2 :         kGCCallbackFlagForced);
     521             :   }
     522             : #ifdef DEBUG
     523             :   for (auto dep : dependencies_) {
     524             :     CHECK_IMPLIES(!dep->IsValid(), dep->IsPretenureModeDependency());
     525             :   }
     526             : #endif
     527             : 
     528             :   dependencies_.clear();
     529      463567 :   return true;
     530             : }
     531             : 
     532             : namespace {
     533             : // This function expects to never see a JSProxy.
     534       53528 : void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
     535             :                                   const JSObjectRef& last_prototype) {
     536       29343 :   while (true) {
     537       82871 :     map.SerializePrototype();
     538       82871 :     JSObjectRef proto = map.prototype().AsJSObject();
     539       82871 :     map = proto.map();
     540       82871 :     deps->DependOnStableMap(map);
     541       82871 :     if (proto.equals(last_prototype)) break;
     542             :   }
     543       53528 : }
     544             : }  // namespace
     545             : 
     546       51514 : void CompilationDependencies::DependOnStablePrototypeChains(
     547             :     std::vector<Handle<Map>> const& receiver_maps, const JSObjectRef& holder) {
     548             :   // Determine actual holder and perform prototype chain checks.
     549      105042 :   for (auto map : receiver_maps) {
     550       53528 :     MapRef receiver_map(broker_, map);
     551       53528 :     if (receiver_map.IsPrimitiveMap()) {
     552             :       // Perform the implicit ToObject for primitives here.
     553             :       // Implemented according to ES6 section 7.3.2 GetV (V, P).
     554             :       base::Optional<JSFunctionRef> constructor =
     555        7882 :           broker_->native_context().GetConstructorFunction(receiver_map);
     556        7882 :       if (constructor.has_value()) receiver_map = constructor->initial_map();
     557             :     }
     558       53528 :     DependOnStablePrototypeChain(this, receiver_map, holder);
     559             :   }
     560       51514 : }
     561             : 
     562        5774 : void CompilationDependencies::DependOnElementsKinds(
     563             :     const AllocationSiteRef& site) {
     564        5774 :   AllocationSiteRef current = site;
     565         248 :   while (true) {
     566        6022 :     DependOnElementsKind(current);
     567        6022 :     if (!current.nested_site().IsAllocationSite()) break;
     568         248 :     current = current.nested_site().AsAllocationSite();
     569             :   }
     570        5774 :   CHECK_EQ(current.nested_site().AsSmi(), 0);
     571        5774 : }
     572             : 
     573         968 : SlackTrackingPrediction::SlackTrackingPrediction(MapRef initial_map,
     574             :                                                  int instance_size)
     575             :     : instance_size_(instance_size),
     576             :       inobject_property_count_(
     577       12052 :           (instance_size >> kTaggedSizeLog2) -
     578        7962 :           initial_map.GetInObjectPropertiesStartInWords()) {}
     579             : 
     580             : SlackTrackingPrediction
     581        5058 : CompilationDependencies::DependOnInitialMapInstanceSizePrediction(
     582             :     const JSFunctionRef& function) {
     583        5058 :   MapRef initial_map = DependOnInitialMap(function);
     584        5058 :   int instance_size = function.InitialMapInstanceSizeWithMinSlack();
     585             :   // Currently, we always install the prediction dependency. If this turns out
     586             :   // to be too expensive, we can only install the dependency if slack
     587             :   // tracking is active.
     588       10116 :   dependencies_.push_front(
     589        5058 :       new (zone_)
     590             :           InitialMapInstanceSizePredictionDependency(function, instance_size));
     591             :   DCHECK_LE(instance_size, function.initial_map().instance_size());
     592        5058 :   return SlackTrackingPrediction(initial_map, instance_size);
     593             : }
     594             : 
     595             : }  // namespace compiler
     596             : }  // namespace internal
     597      120216 : }  // namespace v8

Generated by: LCOV version 1.10