// 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" #include "src/field-index.h" #include "src/globals.h" #include "src/utils.h" namespace v8 { namespace internal { // A set of bit fields representing Smi handlers for loads. class LoadHandler { public: enum Kind { kForElements, kForFields, kForConstants, kForNonExistent }; class KindBits : public BitField {}; // Defines whether access rights check should be done on receiver object. // Applicable to kForFields, kForConstants and kForNonExistent kinds only when // loading value from prototype chain. Ignored when loading from holder. class DoAccessCheckOnReceiverBits : public BitField {}; // Defines whether negative lookup check should be done on receiver object. // Applicable to kForFields, kForConstants and kForNonExistent kinds only when // loading value from prototype chain. Ignored when loading from holder. class DoNegativeLookupOnReceiverBits : public BitField {}; // // Encoding when KindBits contains kForConstants. // class IsAccessorInfoBits : public BitField {}; // Index of a value entry in the descriptor array. // +2 here is because each descriptor entry occupies 3 slots in array. class DescriptorValueIndexBits : public BitField {}; // Make sure we don't overflow the smi. STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize); // // Encoding when KindBits contains kForFields. // class IsInobjectBits : public BitField {}; class IsDoubleBits : public BitField {}; // +1 here is to cover all possible JSObject header sizes. class FieldOffsetBits : public BitField {}; // Make sure we don't overflow the smi. STATIC_ASSERT(FieldOffsetBits::kNext <= kSmiValueSize); // // Encoding when KindBits contains kForElements. // class IsJsArrayBits : public BitField {}; class ConvertHoleBits : public BitField {}; class ElementsKindBits : public BitField {}; // Make sure we don't overflow the smi. STATIC_ASSERT(ElementsKindBits::kNext <= kSmiValueSize); // The layout of an Tuple3 handler representing a load of a field from // prototype when prototype chain checks do not include non-existing lookups // or access checks. static const int kHolderCellOffset = Tuple3::kValue1Offset; static const int kSmiHandlerOffset = Tuple3::kValue2Offset; static const int kValidityCellOffset = Tuple3::kValue3Offset; // The layout of an array handler representing a load of a field from // prototype when prototype chain checks include non-existing lookups and // access checks. static const int kSmiHandlerIndex = 0; static const int kValidityCellIndex = 1; static const int kHolderCellIndex = 2; static const int kFirstPrototypeIndex = 3; // Creates a Smi-handler for loading a field from fast object. static inline Handle LoadField(Isolate* isolate, FieldIndex field_index); // Creates a Smi-handler for loading a constant from fast object. static inline Handle LoadConstant(Isolate* isolate, int descriptor); // Creates a Smi-handler for loading an Api getter property from fast object. static inline Handle LoadApiGetter(Isolate* isolate, int descriptor); // Sets DoAccessCheckOnReceiverBits in given Smi-handler. The receiver // check is a part of a prototype chain check. static inline Handle EnableAccessCheckOnReceiver( Isolate* isolate, Handle smi_handler); // Sets DoNegativeLookupOnReceiverBits in given Smi-handler. The receiver // check is a part of a prototype chain check. static inline Handle EnableNegativeLookupOnReceiver( Isolate* isolate, Handle smi_handler); // Creates a Smi-handler for loading a non-existent property. Works only as // a part of prototype chain check. static inline Handle LoadNonExistent( Isolate* isolate, bool do_negative_lookup_on_receiver); // Creates a Smi-handler for loading an element. static inline Handle LoadElement(Isolate* isolate, ElementsKind elements_kind, bool convert_hole_to_undefined, bool is_js_array); }; // A set of bit fields representing Smi handlers for stores. class StoreHandler { public: enum Kind { kStoreElement, kStoreField, kStoreConstField, kTransitionToField, // TODO(ishell): remove once constant field tracking is done. kTransitionToConstant = kStoreConstField }; class KindBits : public BitField {}; enum FieldRepresentation { kSmi, kDouble, kHeapObject, kTagged }; // Applicable to kStoreField, kTransitionToField and kTransitionToConstant // kinds. // Index of a value entry in the descriptor array. // +2 here is because each descriptor entry occupies 3 slots in array. class DescriptorValueIndexBits : public BitField {}; // // Encoding when KindBits contains kTransitionToConstant. // // Make sure we don't overflow the smi. STATIC_ASSERT(DescriptorValueIndexBits::kNext <= kSmiValueSize); // // Encoding when KindBits contains kStoreField or kTransitionToField. // class ExtendStorageBits : public BitField {}; class IsInobjectBits : public BitField {}; class FieldRepresentationBits : public BitField {}; // +1 here is to cover all possible JSObject header sizes. class FieldOffsetBits : public BitField {}; // Make sure we don't overflow the smi. STATIC_ASSERT(FieldOffsetBits::kNext <= kSmiValueSize); // The layout of an Tuple3 handler representing a transitioning store // when prototype chain checks do not include non-existing lookups or access // checks. static const int kTransitionCellOffset = Tuple3::kValue1Offset; static const int kSmiHandlerOffset = Tuple3::kValue2Offset; static const int kValidityCellOffset = Tuple3::kValue3Offset; // The layout of an array handler representing a transitioning store // when prototype chain checks include non-existing lookups and access checks. static const int kSmiHandlerIndex = 0; static const int kValidityCellIndex = 1; static const int kTransitionCellIndex = 2; static const int kFirstPrototypeIndex = 3; // Creates a Smi-handler for storing a field to fast object. static inline Handle StoreField(Isolate* isolate, int descriptor, FieldIndex field_index, PropertyConstness constness, Representation representation); // Creates a Smi-handler for transitioning store to a field. static inline Handle TransitionToField(Isolate* isolate, int descriptor, FieldIndex field_index, Representation representation, bool extend_storage); // Creates a Smi-handler for transitioning store to a constant field (in this // case the only thing that needs to be done is an update of a map). static inline Handle TransitionToConstant(Isolate* isolate, int descriptor); private: static inline Handle StoreField(Isolate* isolate, Kind kind, int descriptor, FieldIndex field_index, Representation representation, bool extend_storage); }; } // namespace internal } // namespace v8 #endif // V8_IC_HANDLER_CONFIGURATION_H_