LCOV - code coverage report
Current view: top level - src - field-index.h (source / functions) Hit Total Coverage
Test: app.info Lines: 14 17 82.4 %
Date: 2019-04-17 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2014 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_FIELD_INDEX_H_
       6             : #define V8_FIELD_INDEX_H_
       7             : 
       8             : #include "src/property-details.h"
       9             : #include "src/utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : class Map;
      15             : 
      16             : // Wrapper class to hold a field index, usually but not necessarily generated
      17             : // from a property index. When available, the wrapper class captures additional
      18             : // information to allow the field index to be translated back into the property
      19             : // index it was originally generated from.
      20             : class FieldIndex final {
      21             :  public:
      22             :   enum Encoding { kTagged, kDouble, kWord32 };
      23             : 
      24      402422 :   FieldIndex() : bit_field_(0) {}
      25             : 
      26             :   static inline FieldIndex ForPropertyIndex(
      27             :       const Map map, int index,
      28             :       Representation representation = Representation::Tagged());
      29             :   static inline FieldIndex ForInObjectOffset(int offset, Encoding encoding);
      30             :   static inline FieldIndex ForDescriptor(const Map map, int descriptor_index);
      31             : 
      32             :   inline int GetLoadByFieldIndex() const;
      33             : 
      34             :   bool is_inobject() const {
      35      329490 :     return IsInObjectBits::decode(bit_field_);
      36             :   }
      37             : 
      38             :   bool is_hidden_field() const { return IsHiddenField::decode(bit_field_); }
      39             : 
      40     1117410 :   bool is_double() const { return EncodingBits::decode(bit_field_) == kDouble; }
      41             : 
      42      307008 :   int offset() const { return OffsetBits::decode(bit_field_); }
      43             : 
      44             :   // Zero-indexed from beginning of the object.
      45             :   int index() const {
      46             :     DCHECK(IsAligned(offset(), kTaggedSize));
      47   130974684 :     return offset() / kTaggedSize;
      48             :   }
      49             : 
      50             :   int outobject_array_index() const {
      51             :     DCHECK(!is_inobject());
      52   106497924 :     return index() - first_inobject_property_offset() / kTaggedSize;
      53             :   }
      54             : 
      55             :   // Zero-based from the first inobject property. Overflows to out-of-object
      56             :   // properties.
      57             :   int property_index() const {
      58             :     DCHECK(!is_hidden_field());
      59    22620553 :     int result = index() - first_inobject_property_offset() / kTaggedSize;
      60    22620553 :     if (!is_inobject()) {
      61           0 :       result += InObjectPropertyBits::decode(bit_field_);
      62             :     }
      63             :     return result;
      64             :   }
      65             : 
      66             :   int GetFieldAccessStubKey() const {
      67       22702 :     return bit_field_ &
      68       22702 :            (IsInObjectBits::kMask | EncodingBits::kMask | OffsetBits::kMask);
      69             :   }
      70             : 
      71             :   bool operator==(FieldIndex const& other) const {
      72             :     return bit_field_ == other.bit_field_;
      73             :   }
      74             :   bool operator!=(FieldIndex const& other) const { return !(*this == other); }
      75             : 
      76             :  private:
      77             :   FieldIndex(bool is_inobject, int offset, Encoding encoding,
      78             :              int inobject_properties, int first_inobject_property_offset,
      79             :              bool is_hidden = false) {
      80             :     DCHECK(IsAligned(first_inobject_property_offset, kTaggedSize));
      81   173579726 :     bit_field_ = IsInObjectBits::encode(is_inobject) |
      82   173579726 :                  EncodingBits::encode(encoding) |
      83             :                  FirstInobjectPropertyOffsetBits::encode(
      84             :                      first_inobject_property_offset) |
      85   347159452 :                  IsHiddenField::encode(is_hidden) | OffsetBits::encode(offset) |
      86             :                  InObjectPropertyBits::encode(inobject_properties);
      87             :   }
      88             : 
      89   173579702 :   static Encoding FieldEncoding(Representation representation) {
      90             :     switch (representation.kind()) {
      91             :       case Representation::kNone:
      92             :       case Representation::kSmi:
      93             :       case Representation::kHeapObject:
      94             :       case Representation::kTagged:
      95             :         return kTagged;
      96             :       case Representation::kDouble:
      97             :         return kDouble;
      98             :       default:
      99             :         break;
     100             :     }
     101           0 :     PrintF("%s\n", representation.Mnemonic());
     102           0 :     UNREACHABLE();
     103             :     return kTagged;
     104             :   }
     105             : 
     106             :   int first_inobject_property_offset() const {
     107             :     DCHECK(!is_hidden_field());
     108             :     return FirstInobjectPropertyOffsetBits::decode(bit_field_);
     109             :   }
     110             : 
     111             :   static const int kOffsetBitsSize =
     112             :       (kDescriptorIndexBitCount + 1 + kTaggedSizeLog2);
     113             : 
     114             :   // Index from beginning of object.
     115             :   class OffsetBits : public BitField64<int, 0, kOffsetBitsSize> {};
     116             :   class IsInObjectBits : public BitField64<bool, OffsetBits::kNext, 1> {};
     117             :   class EncodingBits : public BitField64<Encoding, IsInObjectBits::kNext, 2> {};
     118             :   // Number of inobject properties.
     119             :   class InObjectPropertyBits
     120             :       : public BitField64<int, EncodingBits::kNext, kDescriptorIndexBitCount> {
     121             :   };
     122             :   // Offset of first inobject property from beginning of object.
     123             :   class FirstInobjectPropertyOffsetBits
     124             :       : public BitField64<int, InObjectPropertyBits::kNext,
     125             :                           kFirstInobjectPropertyOffsetBitCount> {};
     126             :   class IsHiddenField
     127             :       : public BitField64<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {};
     128             :   STATIC_ASSERT(IsHiddenField::kNext <= 64);
     129             : 
     130             :   uint64_t bit_field_;
     131             : };
     132             : 
     133             : }  // namespace internal
     134             : }  // namespace v8
     135             : 
     136             : #endif  // V8_FIELD_INDEX_H_

Generated by: LCOV version 1.10