• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
FieldIndex()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 
is_inobject()34   bool is_inobject() const {
35     return IsInObjectBits::decode(bit_field_);
36   }
37 
is_hidden_field()38   bool is_hidden_field() const { return IsHiddenField::decode(bit_field_); }
39 
is_double()40   bool is_double() const {
41     return IsDoubleBits::decode(bit_field_);
42   }
43 
offset()44   int offset() const {
45     return index() * kPointerSize;
46   }
47 
48   // Zero-indexed from beginning of the object.
index()49   int index() const {
50     return IndexBits::decode(bit_field_);
51   }
52 
outobject_array_index()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.
property_index()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 
GetFieldAccessStubKey()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 
FieldIndex(int bit_field)92   explicit FieldIndex(int bit_field) : bit_field_(bit_field) {}
93 
first_inobject_property_offset()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