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 kTransitionToField, 125 kTransitionToConstant 126 }; 127 class KindBits : public BitField<Kind, 0, 2> {}; 128 129 enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; 130 131 // Applicable to kStoreField, kTransitionToField and kTransitionToConstant 132 // kinds. 133 134 // Index of a value entry in the descriptor array. 135 // +2 here is because each descriptor entry occupies 3 slots in array. 136 class DescriptorValueIndexBits 137 : public BitField<unsigned, KindBits::kNext, 138 kDescriptorIndexBitCount + 2> {}; 139 // 140 // Encoding when KindBits contains kTransitionToConstant. 141 // 142 143 // Make sure we don't overflow the smi. 144 STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize); 145 146 // 147 // Encoding when KindBits contains kStoreField or kTransitionToField. 148 // 149 class ExtendStorageBits 150 : public BitField<bool, DescriptorValueIndexBits::kNext, 1> {}; 151 class IsInobjectBits : public BitField<bool, ExtendStorageBits::kNext, 1> {}; 152 class FieldRepresentationBits 153 : public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {}; 154 // +1 here is to cover all possible JSObject header sizes. 155 class FieldOffsetBits 156 : public BitField<unsigned, FieldRepresentationBits::kNext, 157 kDescriptorIndexBitCount + 1 + kPointerSizeLog2> {}; 158 // Make sure we don't overflow the smi. 159 STATIC_ASSERT(FieldOffsetBits::kNext <= kSmiValueSize); 160 161 // The layout of an Tuple3 handler representing a transitioning store 162 // when prototype chain checks do not include non-existing lookups or access 163 // checks. 164 static const int kTransitionCellOffset = Tuple3::kValue1Offset; 165 static const int kSmiHandlerOffset = Tuple3::kValue2Offset; 166 static const int kValidityCellOffset = Tuple3::kValue3Offset; 167 168 // The layout of an array handler representing a transitioning store 169 // when prototype chain checks include non-existing lookups and access checks. 170 static const int kSmiHandlerIndex = 0; 171 static const int kValidityCellIndex = 1; 172 static const int kTransitionCellIndex = 2; 173 static const int kFirstPrototypeIndex = 3; 174 175 // Creates a Smi-handler for storing a field to fast object. 176 static inline Handle<Object> StoreField(Isolate* isolate, int descriptor, 177 FieldIndex field_index, 178 Representation representation); 179 180 // Creates a Smi-handler for transitioning store to a field. 181 static inline Handle<Object> TransitionToField(Isolate* isolate, 182 int descriptor, 183 FieldIndex field_index, 184 Representation representation, 185 bool extend_storage); 186 187 // Creates a Smi-handler for transitioning store to a constant field (in this 188 // case the only thing that needs to be done is an update of a map). 189 static inline Handle<Object> TransitionToConstant(Isolate* isolate, 190 int descriptor); 191 192 private: 193 static inline Handle<Object> StoreField(Isolate* isolate, Kind kind, 194 int descriptor, 195 FieldIndex field_index, 196 Representation representation, 197 bool extend_storage); 198 }; 199 200 } // namespace internal 201 } // namespace v8 202 203 #endif // V8_IC_HANDLER_CONFIGURATION_H_ 204