Home | History | Annotate | Download | only in src
      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   FieldIndex() : bit_field_(0) {}
     23 
     24   static FieldIndex ForPropertyIndex(Map* map,
     25                                      int index,
     26                                      bool is_double = false);
     27   static FieldIndex ForInObjectOffset(int offset, Map* map = NULL);
     28   static FieldIndex ForDescriptor(Map* map, int descriptor_index);
     29   static FieldIndex ForLoadByFieldIndex(Map* map, int index);
     30   static FieldIndex FromFieldAccessStubKey(int key);
     31 
     32   int GetLoadByFieldIndex() const;
     33 
     34   bool is_inobject() const {
     35     return IsInObjectBits::decode(bit_field_);
     36   }
     37 
     38   bool is_hidden_field() const { return IsHiddenField::decode(bit_field_); }
     39 
     40   bool is_double() const {
     41     return IsDoubleBits::decode(bit_field_);
     42   }
     43 
     44   int offset() const {
     45     return index() * kPointerSize;
     46   }
     47 
     48   // Zero-indexed from beginning of the object.
     49   int index() const {
     50     return IndexBits::decode(bit_field_);
     51   }
     52 
     53   int outobject_array_index() const {
     54     DCHECK(!is_inobject());
     55     return index() - first_inobject_property_offset() / kPointerSize;
     56   }
     57 
     58   // Zero-based from the first inobject property. Overflows to out-of-object
     59   // properties.
     60   int property_index() const {
     61     DCHECK(!is_hidden_field());
     62     int result = index() - first_inobject_property_offset() / kPointerSize;
     63     if (!is_inobject()) {
     64       result += InObjectPropertyBits::decode(bit_field_);
     65     }
     66     return result;
     67   }
     68 
     69   int GetFieldAccessStubKey() const {
     70     return bit_field_ &
     71         (IsInObjectBits::kMask | IsDoubleBits::kMask | IndexBits::kMask);
     72   }
     73 
     74   bool operator==(FieldIndex const& other) const {
     75     return bit_field_ == other.bit_field_;
     76   }
     77   bool operator!=(FieldIndex const& other) const { return !(*this == other); }
     78 
     79  private:
     80   FieldIndex(bool is_inobject, int local_index, bool is_double,
     81              int inobject_properties, int first_inobject_property_offset,
     82              bool is_hidden = false) {
     83     DCHECK((first_inobject_property_offset & (kPointerSize - 1)) == 0);
     84     bit_field_ = IsInObjectBits::encode(is_inobject) |
     85       IsDoubleBits::encode(is_double) |
     86       FirstInobjectPropertyOffsetBits::encode(first_inobject_property_offset) |
     87       IsHiddenField::encode(is_hidden) |
     88       IndexBits::encode(local_index) |
     89       InObjectPropertyBits::encode(inobject_properties);
     90   }
     91 
     92   explicit FieldIndex(int bit_field) : bit_field_(bit_field) {}
     93 
     94   int first_inobject_property_offset() const {
     95     DCHECK(!is_hidden_field());
     96     return FirstInobjectPropertyOffsetBits::decode(bit_field_);
     97   }
     98 
     99   static const int kIndexBitsSize = kDescriptorIndexBitCount + 1;
    100 
    101   // Index from beginning of object.
    102   class IndexBits: public BitField<int, 0, kIndexBitsSize> {};
    103   class IsInObjectBits: public BitField<bool, IndexBits::kNext, 1> {};
    104   class IsDoubleBits: public BitField<bool, IsInObjectBits::kNext, 1> {};
    105   // Number of inobject properties.
    106   class InObjectPropertyBits
    107       : public BitField<int, IsDoubleBits::kNext, kDescriptorIndexBitCount> {};
    108   // Offset of first inobject property from beginning of object.
    109   class FirstInobjectPropertyOffsetBits
    110       : public BitField<int, InObjectPropertyBits::kNext, 7> {};
    111   class IsHiddenField
    112       : public BitField<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {};
    113   STATIC_ASSERT(IsHiddenField::kNext <= 32);
    114 
    115   int bit_field_;
    116 };
    117 
    118 }  // namespace internal
    119 }  // namespace v8
    120 
    121 #endif
    122