Home | History | Annotate | Download | only in ic
      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