1 // Copyright 2016 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_IC_HANDLER_CONFIGURATION_H_ 6 #define V8_IC_HANDLER_CONFIGURATION_H_ 7 8 #include "src/elements-kind.h" 9 #include "src/field-index.h" 10 #include "src/globals.h" 11 #include "src/utils.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // A set of bit fields representing Smi handlers for loads. 17 class LoadHandler { 18 public: 19 enum Kind { kForElements, kForFields, kForConstants, kForNonExistent }; 20 class KindBits : public BitField<Kind, 0, 2> {}; 21 22 // Defines whether access rights check should be done on receiver object. 23 // Applicable to kForFields, kForConstants and kForNonExistent kinds only when 24 // loading value from prototype chain. Ignored when loading from holder. 25 class DoAccessCheckOnReceiverBits 26 : public BitField<bool, KindBits::kNext, 1> {}; 27 28 // Defines whether negative lookup check should be done on receiver object. 29 // Applicable to kForFields, kForConstants and kForNonExistent kinds only when 30 // loading value from prototype chain. Ignored when loading from holder. 31 class DoNegativeLookupOnReceiverBits 32 : public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {}; 33 34 // 35 // Encoding when KindBits contains kForConstants. 36 // 37 38 class IsAccessorInfoBits 39 : public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {}; 40 // Index of a value entry in the descriptor array. 41 // +2 here is because each descriptor entry occupies 3 slots in array. 42 class DescriptorValueIndexBits 43 : public BitField<unsigned, IsAccessorInfoBits::kNext, 44 kDescriptorIndexBitCount + 2> {}; 45 // Make sure we don't overflow the smi. 46 STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize); 47 48 // 49 // Encoding when KindBits contains kForFields. 50 // 51 class IsInobjectBits 52 : public BitField<bool, DoNegativeLookupOnReceiverBits::kNext, 1> {}; 53 class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {}; 54 // +1 here is to cover all possible JSObject header sizes. 55 class FieldOffsetBits 56 : public BitField<unsigned, IsDoubleBits::kNext, 57 kDescriptorIndexBitCount + 1 + kPointerSizeLog2> {}; 58 // Make sure we don't overflow the smi. 59 STATIC_ASSERT(FieldOffsetBits::kNext <= kSmiValueSize); 60 61 // 62 // Encoding when KindBits contains kForElements. 63 // 64 class IsJsArrayBits : public BitField<bool, KindBits::kNext, 1> {}; 65 class ConvertHoleBits : public BitField<bool, IsJsArrayBits::kNext, 1> {}; 66 class ElementsKindBits 67 : public BitField<ElementsKind, ConvertHoleBits::kNext, 8> {}; 68 // Make sure we don't overflow the smi. 69 STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize); 70 71 // The layout of an Tuple3 handler representing a load of a field from 72 // prototype when prototype chain checks do not include non-existing lookups 73 // or access checks. 74 static const int kHolderCellOffset = Tuple3::kValue1Offset; 75 static const int kSmiHandlerOffset = Tuple3::kValue2Offset; 76 static const int kValidityCellOffset = Tuple3::kValue3Offset; 77 78 // The layout of an array handler representing a load of a field from 79 // prototype when prototype chain checks include non-existing lookups and 80 // access checks. 81 static const int kSmiHandlerIndex = 0; 82 static const int kValidityCellIndex = 1; 83 static const int kHolderCellIndex = 2; 84 static const int kFirstPrototypeIndex = 3; 85 86 // Creates a Smi-handler for loading a field from fast object. 87 static inline Handle<Object> LoadField(Isolate* isolate, 88 FieldIndex field_index); 89 90 // Creates a Smi-handler for loading a constant from fast object. 91 static inline Handle<Object> LoadConstant(Isolate* isolate, int descriptor); 92 93 // Creates a Smi-handler for loading an Api getter property from fast object. 94 static inline Handle<Object> LoadApiGetter(Isolate* isolate, int descriptor); 95 96 // Sets DoAccessCheckOnReceiverBits in given Smi-handler. The receiver 97 // check is a part of a prototype chain check. 98 static inline Handle<Object> EnableAccessCheckOnReceiver( 99 Isolate* isolate, Handle<Object> smi_handler); 100 101 // Sets DoNegativeLookupOnReceiverBits in given Smi-handler. The receiver 102 // check is a part of a prototype chain check. 103 static inline Handle<Object> EnableNegativeLookupOnReceiver( 104 Isolate* isolate, Handle<Object> smi_handler); 105 106 // Creates a Smi-handler for loading a non-existent property. Works only as 107 // a part of prototype chain check. 108 static inline Handle<Object> LoadNonExistent( 109 Isolate* isolate, bool do_negative_lookup_on_receiver); 110 111 // Creates a Smi-handler for loading an element. 112 static inline Handle<Object> LoadElement(Isolate* isolate, 113 ElementsKind elements_kind, 114 bool convert_hole_to_undefined, 115 bool is_js_array); 116 }; 117 118 // A set of bit fields representing Smi handlers for stores. 119 class StoreHandler { 120 public: 121 enum Kind { 122 kStoreElement, 123 kStoreField, 124 kStoreConstField, 125 kTransitionToField, 126 // TODO(ishell): remove once constant field tracking is done. 127 kTransitionToConstant = kStoreConstField 128 }; 129 class KindBits : public BitField<Kind, 0, 2> {}; 130 131 enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; 132 133 // Applicable to kStoreField, kTransitionToField and kTransitionToConstant 134 // kinds. 135 136 // Index of a value entry in the descriptor array. 137 // +2 here is because each descriptor entry occupies 3 slots in array. 138 class DescriptorValueIndexBits 139 : public BitField<unsigned, KindBits::kNext, 140 kDescriptorIndexBitCount + 2> {}; 141 // 142 // Encoding when KindBits contains kTransitionToConstant. 143 // 144 145 // Make sure we don't overflow the smi. 146 STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize); 147 148 // 149 // Encoding when KindBits contains kStoreField or kTransitionToField. 150 // 151 class ExtendStorageBits 152 : public BitField<bool, DescriptorValueIndexBits::kNext, 1> {}; 153 class IsInobjectBits : public BitField<bool, ExtendStorageBits::kNext, 1> {}; 154 class FieldRepresentationBits 155 : public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {}; 156 // +1 here is to cover all possible JSObject header sizes. 157 class FieldOffsetBits 158 : public BitField<unsigned, FieldRepresentationBits::kNext, 159 kDescriptorIndexBitCount + 1 + kPointerSizeLog2> {}; 160 // Make sure we don't overflow the smi. 161 STATIC_ASSERT(FieldOffsetBits::kNext <= kSmiValueSize); 162 163 // The layout of an Tuple3 handler representing a transitioning store 164 // when prototype chain checks do not include non-existing lookups or access 165 // checks. 166 static const int kTransitionCellOffset = Tuple3::kValue1Offset; 167 static const int kSmiHandlerOffset = Tuple3::kValue2Offset; 168 static const int kValidityCellOffset = Tuple3::kValue3Offset; 169 170 // The layout of an array handler representing a transitioning store 171 // when prototype chain checks include non-existing lookups and access checks. 172 static const int kSmiHandlerIndex = 0; 173 static const int kValidityCellIndex = 1; 174 static const int kTransitionCellIndex = 2; 175 static const int kFirstPrototypeIndex = 3; 176 177 // Creates a Smi-handler for storing a field to fast object. 178 static inline Handle<Object> StoreField(Isolate* isolate, int descriptor, 179 FieldIndex field_index, 180 PropertyConstness constness, 181 Representation representation); 182 183 // Creates a Smi-handler for transitioning store to a field. 184 static inline Handle<Object> TransitionToField(Isolate* isolate, 185 int descriptor, 186 FieldIndex field_index, 187 Representation representation, 188 bool extend_storage); 189 190 // Creates a Smi-handler for transitioning store to a constant field (in this 191 // case the only thing that needs to be done is an update of a map). 192 static inline Handle<Object> TransitionToConstant(Isolate* isolate, 193 int descriptor); 194 195 private: 196 static inline Handle<Object> StoreField(Isolate* isolate, Kind kind, 197 int descriptor, 198 FieldIndex field_index, 199 Representation representation, 200 bool extend_storage); 201 }; 202 203 } // namespace internal 204 } // namespace v8 205 206 #endif // V8_IC_HANDLER_CONFIGURATION_H_ 207