handler-configuration.h 11.8 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_IC_HANDLER_CONFIGURATION_H_
#define V8_IC_HANDLER_CONFIGURATION_H_

#include "src/elements-kind.h"
9
#include "src/field-index.h"
10
#include "src/globals.h"
11
#include "src/objects.h"
12
#include "src/objects/data-handler.h"
13 14
#include "src/utils.h"

15 16 17
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

18 19 20
namespace v8 {
namespace internal {

21 22 23 24
// A set of bit fields representing Smi handlers for loads and a HeapObject
// that represents load handlers that can't be encoded in a Smi.
// TODO(ishell): move to load-handler.h
class LoadHandler final : public DataHandler {
25
 public:
26 27 28 29 30
  DECL_CAST(LoadHandler)

  DECL_PRINTER(LoadHandler)
  DECL_VERIFIER(LoadHandler)

31
  enum Kind {
32
    kElement,
33
    kIndexedString,
34
    kNormal,
35
    kGlobal,
36 37
    kField,
    kConstant,
38
    kAccessor,
39 40 41
    kNativeDataProperty,
    kApiGetter,
    kApiGetterHolderIsPrototype,
42
    kInterceptor,
43
    kProxy,
44 45
    kNonExistent,
    kModuleExport
46
  };
47
  class KindBits : public BitField<Kind, 0, 4> {};
48

49
  // Defines whether access rights check should be done on receiver object.
50 51
  // Applicable to named property kinds only when loading value from prototype
  // chain. Ignored when loading from holder.
52 53 54
  class DoAccessCheckOnReceiverBits
      : public BitField<bool, KindBits::kNext, 1> {};

55
  // Defines whether a lookup should be done on receiver object before
56 57
  // proceeding to the prototype chain. Applicable to named property kinds only
  // when loading value from prototype chain. Ignored when loading from holder.
58
  class LookupOnReceiverBits
59
      : public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};
60

61 62 63
  //
  // Encoding when KindBits contains kForConstants.
  //
64

65
  // Index of a value entry in the descriptor array.
66
  class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext,
67
                                         kDescriptorIndexBitCount> {};
68
  // Make sure we don't overflow the smi.
69
  STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
70

71
  //
72
  // Encoding when KindBits contains kField.
73
  //
74 75
  class IsInobjectBits : public BitField<bool, LookupOnReceiverBits::kNext, 1> {
  };
76 77
  class IsDoubleBits : public BitField<bool, IsInobjectBits::kNext, 1> {};
  // +1 here is to cover all possible JSObject header sizes.
78 79
  class FieldIndexBits : public BitField<unsigned, IsDoubleBits::kNext,
                                         kDescriptorIndexBitCount + 1> {};
80
  // Make sure we don't overflow the smi.
81
  STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize);
82

83 84 85
  //
  // Encoding when KindBits contains kElement or kIndexedString.
  //
86 87
  class AllowOutOfBoundsBits
      : public BitField<bool, LookupOnReceiverBits::kNext, 1> {};
88

89
  //
90
  // Encoding when KindBits contains kElement.
91
  //
92 93
  class IsJsArrayBits : public BitField<bool, AllowOutOfBoundsBits::kNext, 1> {
  };
94 95 96 97 98
  class ConvertHoleBits : public BitField<bool, IsJsArrayBits::kNext, 1> {};
  class ElementsKindBits
      : public BitField<ElementsKind, ConvertHoleBits::kNext, 8> {};
  // Make sure we don't overflow the smi.
  STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize);
99

100 101 102
  //
  // Encoding when KindBits contains kModuleExport.
  //
103 104 105
  class ExportsIndexBits
      : public BitField<unsigned, LookupOnReceiverBits::kNext,
                        kSmiValueSize - LookupOnReceiverBits::kNext> {};
106

107 108 109
  // Decodes kind from Smi-handler.
  static inline Kind GetHandlerKind(Smi* smi_handler);

110
  // Creates a Smi-handler for loading a property from a slow object.
111 112
  static inline Handle<Smi> LoadNormal(Isolate* isolate);

113 114 115
  // Creates a Smi-handler for loading a property from a global object.
  static inline Handle<Smi> LoadGlobal(Isolate* isolate);

116 117 118
  // Creates a Smi-handler for loading a property from an object with an
  // interceptor.
  static inline Handle<Smi> LoadInterceptor(Isolate* isolate);
119

120
  // Creates a Smi-handler for loading a field from fast object.
121
  static inline Handle<Smi> LoadField(Isolate* isolate, FieldIndex field_index);
122

123
  // Creates a Smi-handler for loading a constant from fast object.
124
  static inline Handle<Smi> LoadConstant(Isolate* isolate, int descriptor);
125

126 127 128
  // Creates a Smi-handler for calling a getter on a fast object.
  static inline Handle<Smi> LoadAccessor(Isolate* isolate, int descriptor);

129 130 131
  // Creates a Smi-handler for calling a getter on a proxy.
  static inline Handle<Smi> LoadProxy(Isolate* isolate);

132 133 134 135 136 137 138
  // Creates a Smi-handler for loading a native data property from fast object.
  static inline Handle<Smi> LoadNativeDataProperty(Isolate* isolate,
                                                   int descriptor);

  // Creates a Smi-handler for calling a native getter on a fast object.
  static inline Handle<Smi> LoadApiGetter(Isolate* isolate,
                                          bool holder_is_receiver);
139

140 141 142 143 144
  // Creates a Smi-handler for loading a Module export.
  // |index| is the index to the "value" slot in the Module's "exports"
  // dictionary.
  static inline Handle<Smi> LoadModuleExport(Isolate* isolate, int index);

145 146 147 148 149
  // Creates a data handler that represents a load of a non-existent property.
  // {holder} is the object from which the property is loaded. If no holder is
  // needed (e.g., for "nonexistent"), null_value() may be passed in.
  static Handle<Object> LoadFullChain(Isolate* isolate,
                                      Handle<Map> receiver_map,
150
                                      Handle<Object> holder,
151 152 153 154 155
                                      Handle<Smi> smi_handler);

  // Creates a data handler that represents a prototype chain check followed
  // by given Smi-handler that encoded a load from the holder.
  // Can be used only if GetPrototypeCheckCount() returns non negative value.
156 157
  static Handle<Object> LoadFromPrototype(
      Isolate* isolate, Handle<Map> receiver_map, Handle<JSReceiver> holder,
158 159 160
      Handle<Smi> smi_handler,
      MaybeHandle<Object> maybe_data1 = MaybeHandle<Object>(),
      MaybeHandle<Object> maybe_data2 = MaybeHandle<Object>());
161

162 163
  // Creates a Smi-handler for loading a non-existent property. Works only as
  // a part of prototype chain check.
164
  static inline Handle<Smi> LoadNonExistent(Isolate* isolate);
165

166
  // Creates a Smi-handler for loading an element.
167 168 169
  static inline Handle<Smi> LoadElement(Isolate* isolate,
                                        ElementsKind elements_kind,
                                        bool convert_hole_to_undefined,
170 171
                                        bool is_js_array,
                                        KeyedAccessLoadMode load_mode);
172

173
  // Creates a Smi-handler for loading from a String.
174
  static inline Handle<Smi> LoadIndexedString(Isolate* isolate,
175 176 177
                                              KeyedAccessLoadMode load_mode);

  // Decodes the KeyedAccessLoadMode from a {handler}.
178
  static KeyedAccessLoadMode GetKeyedAccessLoadMode(MaybeObject* handler);
179 180
};

181 182 183 184
// A set of bit fields representing Smi handlers for stores and a HeapObject
// that represents store handlers that can't be encoded in a Smi.
// TODO(ishell): move to store-handler.h
class StoreHandler final : public DataHandler {
185
 public:
186 187 188 189 190
  DECL_CAST(StoreHandler)

  DECL_PRINTER(StoreHandler)
  DECL_VERIFIER(StoreHandler)

191
  enum Kind {
192 193 194
    kElement,
    kField,
    kConstField,
195
    kAccessor,
196
    kNativeDataProperty,
197 198 199 200
    kApiSetter,
    kApiSetterHolderIsPrototype,
    kGlobalProxy,
    kNormal,
201
    kProxy,
202
    kKindsNumber  // Keep last
203
  };
204
  class KindBits : public BitField<Kind, 0, 4> {};
205 206 207

  enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged };

208
  // Applicable to kGlobalProxy, kProxy kinds.
209 210 211 212 213

  // Defines whether access rights check should be done on receiver object.
  class DoAccessCheckOnReceiverBits
      : public BitField<bool, KindBits::kNext, 1> {};

214 215 216 217 218 219
  // Defines whether a lookup should be done on receiver object before
  // proceeding to the prototype chain. Applicable to named property kinds only
  // when storing through prototype chain. Ignored when storing to holder.
  class LookupOnReceiverBits
      : public BitField<bool, DoAccessCheckOnReceiverBits::kNext, 1> {};

220
  // Applicable to kField, kTransitionToField and kTransitionToConstant
221 222 223
  // kinds.

  // Index of a value entry in the descriptor array.
224 225
  class DescriptorBits : public BitField<unsigned, LookupOnReceiverBits::kNext,
                                         kDescriptorIndexBitCount> {};
226
  //
227
  // Encoding when KindBits contains kTransitionToConstant.
228
  //
229 230

  // Make sure we don't overflow the smi.
231
  STATIC_ASSERT(DescriptorBits::kNext <= kSmiValueSize);
232 233

  //
234
  // Encoding when KindBits contains kField or kTransitionToField.
235
  //
236
  class IsInobjectBits : public BitField<bool, DescriptorBits::kNext, 1> {};
237 238 239
  class FieldRepresentationBits
      : public BitField<FieldRepresentation, IsInobjectBits::kNext, 2> {};
  // +1 here is to cover all possible JSObject header sizes.
240
  class FieldIndexBits
241
      : public BitField<unsigned, FieldRepresentationBits::kNext,
242
                        kDescriptorIndexBitCount + 1> {};
243
  // Make sure we don't overflow the smi.
244
  STATIC_ASSERT(FieldIndexBits::kNext <= kSmiValueSize);
245 246

  // Creates a Smi-handler for storing a field to fast object.
247 248 249 250
  static inline Handle<Smi> StoreField(Isolate* isolate, int descriptor,
                                       FieldIndex field_index,
                                       PropertyConstness constness,
                                       Representation representation);
251

252 253
  static MaybeObjectHandle StoreTransition(Isolate* isolate,
                                           Handle<Map> transition_map);
254

255 256 257 258
  // Creates a Smi-handler for storing a native data property on a fast object.
  static inline Handle<Smi> StoreNativeDataProperty(Isolate* isolate,
                                                    int descriptor);

259 260 261
  // Creates a Smi-handler for calling a setter on a fast object.
  static inline Handle<Smi> StoreAccessor(Isolate* isolate, int descriptor);

262 263 264 265 266 267
  // Creates a Smi-handler for calling a native setter on a fast object.
  static inline Handle<Smi> StoreApiSetter(Isolate* isolate,
                                           bool holder_is_receiver);

  static Handle<Object> StoreThroughPrototype(
      Isolate* isolate, Handle<Map> receiver_map, Handle<JSReceiver> holder,
268 269 270
      Handle<Smi> smi_handler,
      MaybeHandle<Object> maybe_data1 = MaybeHandle<Object>(),
      MaybeHandle<Object> maybe_data2 = MaybeHandle<Object>());
271

272 273 274 275 276
  static Handle<Object> StoreElementTransition(Isolate* isolate,
                                               Handle<Map> receiver_map,
                                               Handle<Map> transition,
                                               KeyedAccessStoreMode store_mode);

277 278
  static Handle<Object> StoreProxy(Isolate* isolate, Handle<Map> receiver_map,
                                   Handle<JSProxy> proxy,
279
                                   Handle<JSReceiver> receiver);
280

281 282
  // Creates a handler for storing a property to the property cell of a global
  // object.
283 284
  static MaybeObjectHandle StoreGlobal(Isolate* isolate,
                                       Handle<PropertyCell> cell);
285 286 287 288

  // Creates a Smi-handler for storing a property to a global proxy object.
  static inline Handle<Smi> StoreGlobalProxy(Isolate* isolate);

289
  // Creates a Smi-handler for storing a property to a slow object.
290
  static inline Handle<Smi> StoreNormal(Isolate* isolate);
291

292 293 294
  // Creates a Smi-handler for storing a property on a proxy.
  static inline Handle<Smi> StoreProxy(Isolate* isolate);

295 296 297
 private:
  static inline Handle<Smi> StoreField(Isolate* isolate, Kind kind,
                                       int descriptor, FieldIndex field_index,
298
                                       Representation representation);
299 300
};

301 302 303
}  // namespace internal
}  // namespace v8

304 305
#include "src/objects/object-macros-undef.h"

306
#endif  // V8_IC_HANDLER_CONFIGURATION_H_