LCOV - code coverage report
Current view: top level - src - map-updater.h (source / functions) Hit Total Coverage
Test: app.info Lines: 3 3 100.0 %
Date: 2017-04-26 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2017 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             : #ifndef V8_MAP_RECONFIGURER_H_
       6             : #define V8_MAP_RECONFIGURER_H_
       7             : 
       8             : #include "src/elements-kind.h"
       9             : #include "src/globals.h"
      10             : #include "src/handles.h"
      11             : #include "src/objects.h"
      12             : #include "src/property-details.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : 
      17             : // The |MapUpdater| class implements all sorts of map reconfigurations
      18             : // including changes of elements kind, property attributes, property kind,
      19             : // property location and field representations/type changes. It ensures that
      20             : // the reconfigured map and all the intermediate maps are properly integrated
      21             : // into the exising transition tree.
      22             : //
      23             : // To avoid high degrees over polymorphism, and to stabilize quickly, on every
      24             : // rewrite the new type is deduced by merging the current type with any
      25             : // potential new (partial) version of the type in the transition tree.
      26             : // To do this, on each rewrite:
      27             : // - Search the root of the transition tree using FindRootMap.
      28             : // - Find/create a |root_map| with requested |new_elements_kind|.
      29             : // - Find |target_map|, the newest matching version of this map using the
      30             : //   "updated" |old_map|'s descriptor array (i.e. whose entry at |modify_index|
      31             : //   is considered to be of |new_kind| and having |new_attributes|) to walk
      32             : //   the transition tree.
      33             : // - Merge/generalize the "updated" descriptor array of the |old_map| and
      34             : //   descriptor array of the |target_map|.
      35             : // - Generalize the |modify_index| descriptor using |new_representation| and
      36             : //   |new_field_type|.
      37             : // - Walk the tree again starting from the root towards |target_map|. Stop at
      38             : //   |split_map|, the first map who's descriptor array does not match the merged
      39             : //   descriptor array.
      40             : // - If |target_map| == |split_map|, |target_map| is in the expected state.
      41             : //   Return it.
      42             : // - Otherwise, invalidate the outdated transition target from |target_map|, and
      43             : //   replace its transition tree with a new branch for the updated descriptors.
      44             : class MapUpdater {
      45             :  public:
      46     1846740 :   MapUpdater(Isolate* isolate, Handle<Map> old_map)
      47             :       : isolate_(isolate),
      48             :         old_map_(old_map),
      49             :         old_descriptors_(old_map->instance_descriptors(), isolate_),
      50             :         old_nof_(old_map_->NumberOfOwnDescriptors()),
      51     5540220 :         new_elements_kind_(old_map_->elements_kind()) {
      52             :     // We shouldn't try to update remote objects.
      53             :     DCHECK(!old_map->FindRootMap()->GetConstructor()->IsFunctionTemplateInfo());
      54     1846740 :   }
      55             : 
      56             :   // Prepares for reconfiguring of a property at |descriptor| to data field
      57             :   // with given |attributes| and |representation|/|field_type| and
      58             :   // performs the steps 1-5.
      59             :   Handle<Map> ReconfigureToDataField(int descriptor,
      60             :                                      PropertyAttributes attributes,
      61             :                                      PropertyConstness constness,
      62             :                                      Representation representation,
      63             :                                      Handle<FieldType> field_type);
      64             : 
      65             :   // Prepares for reconfiguring elements kind and performs the steps 1-5.
      66             :   Handle<Map> ReconfigureElementsKind(ElementsKind elements_kind);
      67             : 
      68             :   // Prepares for updating deprecated map to most up-to-date non-deprecated
      69             :   // version and performs the steps 1-5.
      70             :   Handle<Map> Update();
      71             : 
      72             :  private:
      73             :   enum State { kInitialized, kAtRootMap, kAtTargetMap, kEnd };
      74             : 
      75             :   // Try to reconfigure property in-place without rebuilding transition tree
      76             :   // and creating new maps. See implementation for details.
      77             :   State TryRecofigureToDataFieldInplace();
      78             : 
      79             :   // Step 1.
      80             :   // - Search the root of the transition tree using FindRootMap.
      81             :   // - Find/create a |root_map_| with requested |new_elements_kind_|.
      82             :   State FindRootMap();
      83             : 
      84             :   // Step 2.
      85             :   // - Find |target_map_|, the newest matching version of this map using the
      86             :   //   "updated" |old_map|'s descriptor array (i.e. whose entry at
      87             :   //   |modified_descriptor_| is considered to be of |new_kind| and having
      88             :   //   |new_attributes|) to walk the transition tree.
      89             :   State FindTargetMap();
      90             : 
      91             :   // Step 3.
      92             :   // - Merge/generalize the "updated" descriptor array of the |old_map_| and
      93             :   //   descriptor array of the |target_map_|.
      94             :   // - Generalize the |modified_descriptor_| using |new_representation| and
      95             :   //   |new_field_type_|.
      96             :   Handle<DescriptorArray> BuildDescriptorArray();
      97             : 
      98             :   // Step 4.
      99             :   // - Walk the tree again starting from the root towards |target_map|. Stop at
     100             :   //   |split_map|, the first map who's descriptor array does not match the
     101             :   //   merged descriptor array.
     102             :   Handle<Map> FindSplitMap(Handle<DescriptorArray> descriptors);
     103             : 
     104             :   // Step 5.
     105             :   // - If |target_map| == |split_map|, |target_map| is in the expected state.
     106             :   //   Return it.
     107             :   // - Otherwise, invalidate the outdated transition target from |target_map|,
     108             :   //   and replace its transition tree with a new branch for the updated
     109             :   //   descriptors.
     110             :   State ConstructNewMap();
     111             : 
     112             :   // When a requested reconfiguration can not be done the result is a copy
     113             :   // of |old_map_| where every field has |Tagged| representation and |Any|
     114             :   // field type. This map is disconnected from the transition tree.
     115             :   State CopyGeneralizeAllFields(const char* reason);
     116             : 
     117             :   // Returns name of a |descriptor| property.
     118             :   inline Name* GetKey(int descriptor) const;
     119             : 
     120             :   // Returns property details of a |descriptor| in "updated" |old_descrtiptors_|
     121             :   // array.
     122             :   inline PropertyDetails GetDetails(int descriptor) const;
     123             : 
     124             :   // Returns value of a |descriptor| with kDescriptor location in "updated"
     125             :   // |old_descrtiptors_| array.
     126             :   inline Object* GetValue(int descriptor) const;
     127             : 
     128             :   // Returns field type for a |descriptor| with kField location in "updated"
     129             :   // |old_descrtiptors_| array.
     130             :   inline FieldType* GetFieldType(int descriptor) const;
     131             : 
     132             :   // If a |descriptor| property in "updated" |old_descriptors_| has kField
     133             :   // location then returns it's field type otherwise computes optimal field
     134             :   // type for the descriptor's value and |representation|. The |location|
     135             :   // value must be a pre-fetched location for |descriptor|.
     136             :   inline Handle<FieldType> GetOrComputeFieldType(
     137             :       int descriptor, PropertyLocation location,
     138             :       Representation representation) const;
     139             : 
     140             :   // If a |descriptor| property in given |descriptors| array has kField
     141             :   // location then returns it's field type otherwise computes optimal field
     142             :   // type for the descriptor's value and |representation|.
     143             :   // The |location| value must be a pre-fetched location for |descriptor|.
     144             :   inline Handle<FieldType> GetOrComputeFieldType(
     145             :       Handle<DescriptorArray> descriptors, int descriptor,
     146             :       PropertyLocation location, Representation representation);
     147             : 
     148             :   void GeneralizeField(Handle<Map> map, int modify_index,
     149             :                        PropertyConstness new_constness,
     150             :                        Representation new_representation,
     151             :                        Handle<FieldType> new_field_type);
     152             : 
     153             :   Isolate* isolate_;
     154             :   Handle<Map> old_map_;
     155             :   Handle<DescriptorArray> old_descriptors_;
     156             :   Handle<Map> root_map_;
     157             :   Handle<Map> target_map_;
     158             :   Handle<Map> result_map_;
     159             :   int old_nof_;
     160             : 
     161             :   State state_ = kInitialized;
     162             :   ElementsKind new_elements_kind_;
     163             : 
     164             :   // If |modified_descriptor_| is not equal to -1 them the fields below form
     165             :   // an "update" of the |old_map_|'s descriptors.
     166             :   int modified_descriptor_ = -1;
     167             :   PropertyKind new_kind_ = kData;
     168             :   PropertyAttributes new_attributes_ = NONE;
     169             :   PropertyConstness new_constness_ = kMutable;
     170             :   PropertyLocation new_location_ = kField;
     171             :   Representation new_representation_ = Representation::None();
     172             : 
     173             :   // Data specific to kField location.
     174             :   Handle<FieldType> new_field_type_;
     175             : 
     176             :   // Data specific to kDescriptor location.
     177             :   Handle<Object> new_value_;
     178             : };
     179             : 
     180             : }  // namespace internal
     181             : }  // namespace v8
     182             : 
     183             : #endif  // V8_MAP_RECONFIGURER_H_

Generated by: LCOV version 1.10