// Copyright 2017 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_OBJECTS_MAP_H_
#define V8_OBJECTS_MAP_H_

#include "src/globals.h"
#include "src/objects.h"
#include "src/objects/code.h"
#include "src/objects/heap-object.h"

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

namespace v8 {
namespace internal {

enum InstanceType : uint16_t;

#define DATA_ONLY_VISITOR_ID_LIST(V) \
  V(BigInt)                          \
  V(ByteArray)                       \
  V(DataObject)                      \
  V(FixedDoubleArray)                \
  V(SeqOneByteString)                \
  V(SeqTwoByteString)

#define POINTER_VISITOR_ID_LIST(V)     \
  V(AllocationSite)                    \
  V(BytecodeArray)                     \
  V(Cell)                              \
  V(Code)                              \
  V(CodeDataContainer)                 \
  V(ConsString)                        \
  V(Context)                           \
  V(DataHandler)                       \
  V(DescriptorArray)                   \
  V(EmbedderDataArray)                 \
  V(EphemeronHashTable)                \
  V(FeedbackCell)                      \
  V(FeedbackVector)                    \
  V(FixedArray)                        \
  V(FixedFloat64Array)                 \
  V(FixedTypedArrayBase)               \
  V(FreeSpace)                         \
  V(JSApiObject)                       \
  V(JSArrayBuffer)                     \
  V(JSDataView)                        \
  V(JSFunction)                        \
  V(JSObject)                          \
  V(JSObjectFast)                      \
  V(JSTypedArray)                      \
  V(JSWeakRef)                         \
  V(JSWeakCollection)                  \
  V(Map)                               \
  V(NativeContext)                     \
  V(Oddball)                           \
  V(PreparseData)                      \
  V(PropertyArray)                     \
  V(PropertyCell)                      \
  V(PrototypeInfo)                     \
  V(SharedFunctionInfo)                \
  V(ShortcutCandidate)                 \
  V(SlicedString)                      \
  V(SmallOrderedHashMap)               \
  V(SmallOrderedHashSet)               \
  V(SmallOrderedNameDictionary)        \
  V(Struct)                            \
  V(Symbol)                            \
  V(ThinString)                        \
  V(TransitionArray)                   \
  V(UncompiledDataWithoutPreparseData) \
  V(UncompiledDataWithPreparseData)    \
  V(WasmInstanceObject)                \
  V(WeakArray)                         \
  V(WeakCell)

// Objects with the same visitor id are processed in the same way by
// the heap visitors. The visitor ids for data only objects must precede
// other visitor ids. We rely on kDataOnlyVisitorIdCount for quick check
// of whether an object contains only data or may contain pointers.
enum VisitorId {
#define VISITOR_ID_ENUM_DECL(id) kVisit##id,
  DATA_ONLY_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) kDataOnlyVisitorIdCount,
  POINTER_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
#undef VISITOR_ID_ENUM_DECL
      kVisitorIdCount
};

enum class ObjectFields {
  kDataOnly,
  kMaybePointers,
};

typedef std::vector<Handle<Map>> MapHandles;

// All heap objects have a Map that describes their structure.
//  A Map contains information about:
//  - Size information about the object
//  - How to iterate over an object (for garbage collection)
//
// Map layout:
// +---------------+---------------------------------------------+
// |   _ Type _    | _ Description _                             |
// +---------------+---------------------------------------------+
// | TaggedPointer | map - Always a pointer to the MetaMap root  |
// +---------------+---------------------------------------------+
// | Int           | The first int field                         |
//  `---+----------+---------------------------------------------+
//      | Byte     | [instance_size]                             |
//      +----------+---------------------------------------------+
//      | Byte     | If Map for a primitive type:                |
//      |          |   native context index for constructor fn   |
//      |          | If Map for an Object type:                  |
//      |          |   inobject properties start offset in words |
//      +----------+---------------------------------------------+
//      | Byte     | [used_or_unused_instance_size_in_words]     |
//      |          | For JSObject in fast mode this byte encodes |
//      |          | the size of the object that includes only   |
//      |          | the used property fields or the slack size  |
//      |          | in properties backing store.                |
//      +----------+---------------------------------------------+
//      | Byte     | [visitor_id]                                |
// +----+----------+---------------------------------------------+
// | Int           | The second int field                        |
//  `---+----------+---------------------------------------------+
//      | Short    | [instance_type]                             |
//      +----------+---------------------------------------------+
//      | Byte     | [bit_field]                                 |
//      |          |   - has_non_instance_prototype (bit 0)      |
//      |          |   - is_callable (bit 1)                     |
//      |          |   - has_named_interceptor (bit 2)           |
//      |          |   - has_indexed_interceptor (bit 3)         |
//      |          |   - is_undetectable (bit 4)                 |
//      |          |   - is_access_check_needed (bit 5)          |
//      |          |   - is_constructor (bit 6)                  |
//      |          |   - has_prototype_slot (bit 7)              |
//      +----------+---------------------------------------------+
//      | Byte     | [bit_field2]                                |
//      |          |   - is_extensible (bit 0)                   |
//      |          |   - is_prototype_map (bit 1)                |
//      |          |   - is_in_retained_map_list (bit 2)         |
//      |          |   - elements_kind (bits 3..7)               |
// +----+----------+---------------------------------------------+
// | Int           | [bit_field3]                                |
// |               |   - enum_length (bit 0..9)                  |
// |               |   - number_of_own_descriptors (bit 10..19)  |
// |               |   - is_dictionary_map (bit 20)              |
// |               |   - owns_descriptors (bit 21)               |
// |               |   - has_hidden_prototype (bit 22)           |
// |               |   - is_deprecated (bit 23)                  |
// |               |   - is_unstable (bit 24)                    |
// |               |   - is_migration_target (bit 25)            |
// |               |   - is_immutable_proto (bit 26)             |
// |               |   - new_target_is_base (bit 27)             |
// |               |   - may_have_interesting_symbols (bit 28)   |
// |               |   - construction_counter (bit 29..31)       |
// |               |                                             |
// +*************************************************************+
// | Int           | On systems with 64bit pointer types, there  |
// |               | is an unused 32bits after bit_field3        |
// +*************************************************************+
// | TaggedPointer | [prototype]                                 |
// +---------------+---------------------------------------------+
// | TaggedPointer | [constructor_or_backpointer]                |
// +---------------+---------------------------------------------+
// | TaggedPointer | If Map is a prototype map:                  |
// |               |   [prototype_info]                          |
// |               | Else:                                       |
// |               |   [raw_transitions]                         |
// +---------------+---------------------------------------------+
// | TaggedPointer | [instance_descriptors]                      |
// +*************************************************************+
// ! TaggedPointer ! [layout_descriptors]                        !
// !               ! Field is only present if compile-time flag  !
// !               ! FLAG_unbox_double_fields is enabled         !
// !               ! (basically on 64 bit architectures)         !
// +*************************************************************+
// | TaggedPointer | [dependent_code]                            |
// +---------------+---------------------------------------------+

class Map : public HeapObject {
 public:
  // Instance size.
  // Size in bytes or kVariableSizeSentinel if instances do not have
  // a fixed size.
  DECL_INT_ACCESSORS(instance_size)
  // Size in words or kVariableSizeSentinel if instances do not have
  // a fixed size.
  DECL_INT_ACCESSORS(instance_size_in_words)

  // [inobject_properties_start_or_constructor_function_index]:
  // Provides access to the inobject properties start offset in words in case of
  // JSObject maps, or the constructor function index in case of primitive maps.
  DECL_INT_ACCESSORS(inobject_properties_start_or_constructor_function_index)

  // Get/set the in-object property area start offset in words in the object.
  inline int GetInObjectPropertiesStartInWords() const;
  inline void SetInObjectPropertiesStartInWords(int value);
  // Count of properties allocated in the object (JSObject only).
  inline int GetInObjectProperties() const;
  // Index of the constructor function in the native context (primitives only),
  // or the special sentinel value to indicate that there is no object wrapper
  // for the primitive (i.e. in case of null or undefined).
  static const int kNoConstructorFunctionIndex = 0;
  inline int GetConstructorFunctionIndex() const;
  inline void SetConstructorFunctionIndex(int value);
  static MaybeHandle<JSFunction> GetConstructorFunction(
      Handle<Map> map, Handle<Context> native_context);

  // Retrieve interceptors.
  inline InterceptorInfo GetNamedInterceptor();
  inline InterceptorInfo GetIndexedInterceptor();

  // Instance type.
  DECL_PRIMITIVE_ACCESSORS(instance_type, InstanceType)

  // Returns the size of the used in-object area including object header
  // (only used for JSObject in fast mode, for the other kinds of objects it
  // is equal to the instance size).
  inline int UsedInstanceSize() const;

  // Tells how many unused property fields (in-object or out-of object) are
  // available in the instance (only used for JSObject in fast mode).
  inline int UnusedPropertyFields() const;
  // Tells how many unused in-object property words are present.
  inline int UnusedInObjectProperties() const;
  // Updates the counters tracking unused fields in the object.
  inline void SetInObjectUnusedPropertyFields(int unused_property_fields);
  // Updates the counters tracking unused fields in the property array.
  inline void SetOutOfObjectUnusedPropertyFields(int unused_property_fields);
  inline void CopyUnusedPropertyFields(Map map);
  inline void CopyUnusedPropertyFieldsAdjustedForInstanceSize(Map map);
  inline void AccountAddedPropertyField();
  inline void AccountAddedOutOfObjectPropertyField(
      int unused_in_property_array);

  //
  // Bit field.
  //
  DECL_PRIMITIVE_ACCESSORS(bit_field, byte)

// Bit positions for |bit_field|.
#define MAP_BIT_FIELD_FIELDS(V, _)          \
  V(HasNonInstancePrototypeBit, bool, 1, _) \
  V(IsCallableBit, bool, 1, _)              \
  V(HasNamedInterceptorBit, bool, 1, _)     \
  V(HasIndexedInterceptorBit, bool, 1, _)   \
  V(IsUndetectableBit, bool, 1, _)          \
  V(IsAccessCheckNeededBit, bool, 1, _)     \
  V(IsConstructorBit, bool, 1, _)           \
  V(HasPrototypeSlotBit, bool, 1, _)

  DEFINE_BIT_FIELDS(MAP_BIT_FIELD_FIELDS)
#undef MAP_BIT_FIELD_FIELDS

  //
  // Bit field 2.
  //
  DECL_PRIMITIVE_ACCESSORS(bit_field2, byte)

// Bit positions for |bit_field2|.
#define MAP_BIT_FIELD2_FIELDS(V, _)     \
  V(IsExtensibleBit, bool, 1, _)        \
  V(IsPrototypeMapBit, bool, 1, _)      \
  V(IsInRetainedMapListBit, bool, 1, _) \
  V(ElementsKindBits, ElementsKind, 5, _)

  DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS)
#undef MAP_BIT_FIELD2_FIELDS

  //
  // Bit field 3.
  //
  DECL_PRIMITIVE_ACCESSORS(bit_field3, uint32_t)

// Bit positions for |bit_field3|.
#define MAP_BIT_FIELD3_FIELDS(V, _)                               \
  V(EnumLengthBits, int, kDescriptorIndexBitCount, _)             \
  V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \
  V(IsDictionaryMapBit, bool, 1, _)                               \
  V(OwnsDescriptorsBit, bool, 1, _)                               \
  V(HasHiddenPrototypeBit, bool, 1, _)                            \
  V(IsDeprecatedBit, bool, 1, _)                                  \
  V(IsUnstableBit, bool, 1, _)                                    \
  V(IsMigrationTargetBit, bool, 1, _)                             \
  V(IsImmutablePrototypeBit, bool, 1, _)                          \
  V(NewTargetIsBaseBit, bool, 1, _)                               \
  V(MayHaveInterestingSymbolsBit, bool, 1, _)                     \
  V(ConstructionCounterBits, int, 3, _)

  DEFINE_BIT_FIELDS(MAP_BIT_FIELD3_FIELDS)
#undef MAP_BIT_FIELD3_FIELDS

  STATIC_ASSERT(NumberOfOwnDescriptorsBits::kMax >= kMaxNumberOfDescriptors);

  static const int kSlackTrackingCounterStart = 7;
  static const int kSlackTrackingCounterEnd = 1;
  static const int kNoSlackTracking = 0;
  STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounterBits::kMax);

  // Inobject slack tracking is the way to reclaim unused inobject space.
  //
  // The instance size is initially determined by adding some slack to
  // expected_nof_properties (to allow for a few extra properties added
  // after the constructor). There is no guarantee that the extra space
  // will not be wasted.
  //
  // Here is the algorithm to reclaim the unused inobject space:
  // - Detect the first constructor call for this JSFunction.
  //   When it happens enter the "in progress" state: initialize construction
  //   counter in the initial_map.
  // - While the tracking is in progress initialize unused properties of a new
  //   object with one_pointer_filler_map instead of undefined_value (the "used"
  //   part is initialized with undefined_value as usual). This way they can
  //   be resized quickly and safely.
  // - Once enough objects have been created  compute the 'slack'
  //   (traverse the map transition tree starting from the
  //   initial_map and find the lowest value of unused_property_fields).
  // - Traverse the transition tree again and decrease the instance size
  //   of every map. Existing objects will resize automatically (they are
  //   filled with one_pointer_filler_map). All further allocations will
  //   use the adjusted instance size.
  // - SharedFunctionInfo's expected_nof_properties left unmodified since
  //   allocations made using different closures could actually create different
  //   kind of objects (see prototype inheritance pattern).
  //
  //  Important: inobject slack tracking is not attempted during the snapshot
  //  creation.

  static const int kGenerousAllocationCount =
      kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;

  // Starts the tracking by initializing object constructions countdown counter.
  void StartInobjectSlackTracking();

  // True if the object constructions countdown counter is a range
  // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
  inline bool IsInobjectSlackTrackingInProgress() const;

  // Does the tracking step.
  inline void InobjectSlackTrackingStep(Isolate* isolate);

  // Computes inobject slack for the transition tree starting at this initial
  // map.
  int ComputeMinObjectSlack(Isolate* isolate);
  inline int InstanceSizeFromSlack(int slack) const;

  // Completes inobject slack tracking for the transition tree starting at this
  // initial map.
  void CompleteInobjectSlackTracking(Isolate* isolate);

  // Tells whether the object in the prototype property will be used
  // for instances created from this function.  If the prototype
  // property is set to a value that is not a JSObject, the prototype
  // property will not be used to create instances of the function.
  // See ECMA-262, 13.2.2.
  DECL_BOOLEAN_ACCESSORS(has_non_instance_prototype)

  // Tells whether the instance has a [[Construct]] internal method.
  // This property is implemented according to ES6, section 7.2.4.
  DECL_BOOLEAN_ACCESSORS(is_constructor)

  // Tells whether the instance with this map may have properties for
  // interesting symbols on it.
  // An "interesting symbol" is one for which Name::IsInterestingSymbol()
  // returns true, i.e. a well-known symbol like @@toStringTag.
  DECL_BOOLEAN_ACCESSORS(may_have_interesting_symbols)

  DECL_BOOLEAN_ACCESSORS(has_prototype_slot)

  // Tells whether the instance with this map has a hidden prototype.
  DECL_BOOLEAN_ACCESSORS(has_hidden_prototype)

  // Records and queries whether the instance has a named interceptor.
  DECL_BOOLEAN_ACCESSORS(has_named_interceptor)

  // Records and queries whether the instance has an indexed interceptor.
  DECL_BOOLEAN_ACCESSORS(has_indexed_interceptor)

  // Tells whether the instance is undetectable.
  // An undetectable object is a special class of JSObject: 'typeof' operator
  // returns undefined, ToBoolean returns false. Otherwise it behaves like
  // a normal JS object.  It is useful for implementing undetectable
  // document.all in Firefox & Safari.
  // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
  DECL_BOOLEAN_ACCESSORS(is_undetectable)

  // Tells whether the instance has a [[Call]] internal method.
  // This property is implemented according to ES6, section 7.2.3.
  DECL_BOOLEAN_ACCESSORS(is_callable)

  DECL_BOOLEAN_ACCESSORS(new_target_is_base)
  DECL_BOOLEAN_ACCESSORS(is_extensible)
  DECL_BOOLEAN_ACCESSORS(is_prototype_map)
  inline bool is_abandoned_prototype_map() const;

  // Whether the instance has been added to the retained map list by
  // Heap::AddRetainedMap.
  DECL_BOOLEAN_ACCESSORS(is_in_retained_map_list)

  DECL_PRIMITIVE_ACCESSORS(elements_kind, ElementsKind)

  // Tells whether the instance has fast elements that are only Smis.
  inline bool has_fast_smi_elements() const;

  // Tells whether the instance has fast elements.
  inline bool has_fast_object_elements() const;
  inline bool has_fast_smi_or_object_elements() const;
  inline bool has_fast_double_elements() const;
  inline bool has_fast_elements() const;
  inline bool has_sloppy_arguments_elements() const;
  inline bool has_fast_sloppy_arguments_elements() const;
  inline bool has_fast_string_wrapper_elements() const;
  inline bool has_fixed_typed_array_elements() const;
  inline bool has_dictionary_elements() const;

  // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
  // map with DICTIONARY_ELEMENTS was found in the prototype chain.
  bool DictionaryElementsInPrototypeChainOnly(Isolate* isolate);

  inline Map ElementsTransitionMap();

  inline FixedArrayBase GetInitialElements() const;

  // [raw_transitions]: Provides access to the transitions storage field.
  // Don't call set_raw_transitions() directly to overwrite transitions, use
  // the TransitionArray::ReplaceTransitions() wrapper instead!
  DECL_ACCESSORS(raw_transitions, MaybeObject)
  // [prototype_info]: Per-prototype metadata. Aliased with transitions
  // (which prototype maps don't have).
  DECL_ACCESSORS(prototype_info, Object)
  // PrototypeInfo is created lazily using this helper (which installs it on
  // the given prototype's map).
  static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
      Handle<JSObject> prototype, Isolate* isolate);
  static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
      Handle<Map> prototype_map, Isolate* isolate);
  inline bool should_be_fast_prototype_map() const;
  static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
                                          Isolate* isolate);

  // [prototype chain validity cell]: Associated with a prototype object,
  // stored in that object's map, indicates that prototype chains through this
  // object are currently valid. The cell will be invalidated and replaced when
  // the prototype chain changes. When there's nothing to guard (for example,
  // when direct prototype is null or Proxy) this function returns Smi with
  // |kPrototypeChainValid| sentinel value.
  static Handle<Object> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
                                                              Isolate* isolate);
  static const int kPrototypeChainValid = 0;
  static const int kPrototypeChainInvalid = 1;

  static bool IsPrototypeChainInvalidated(Map map);

  // Return the map of the root of object's prototype chain.
  Map GetPrototypeChainRootMap(Isolate* isolate) const;

  Map FindRootMap(Isolate* isolate) const;
  Map FindFieldOwner(Isolate* isolate, int descriptor) const;

  inline int GetInObjectPropertyOffset(int index) const;

  class FieldCounts {
   public:
    FieldCounts(int mutable_count, int const_count)
        : mutable_count_(mutable_count), const_count_(const_count) {}

    int GetTotal() const { return mutable_count() + const_count(); }

    int mutable_count() const { return mutable_count_; }
    int const_count() const { return const_count_; }

   private:
    int mutable_count_;
    int const_count_;
  };

  FieldCounts GetFieldCounts() const;
  int NumberOfFields() const;

  bool HasOutOfObjectProperties() const;

  // Returns true if transition to the given map requires special
  // synchronization with the concurrent marker.
  bool TransitionRequiresSynchronizationWithGC(Map target) const;
  // Returns true if transition to the given map removes a tagged in-object
  // field.
  bool TransitionRemovesTaggedField(Map target) const;
  // Returns true if transition to the given map replaces a tagged in-object
  // field with an untagged in-object field.
  bool TransitionChangesTaggedFieldToUntaggedField(Map target) const;

  // TODO(ishell): candidate with JSObject::MigrateToMap().
  bool InstancesNeedRewriting(Map target) const;
  bool InstancesNeedRewriting(Map target, int target_number_of_fields,
                              int target_inobject, int target_unused,
                              int* old_number_of_fields) const;
  V8_WARN_UNUSED_RESULT static Handle<FieldType> GeneralizeFieldType(
      Representation rep1, Handle<FieldType> type1, Representation rep2,
      Handle<FieldType> type2, Isolate* isolate);
  static void GeneralizeField(Isolate* isolate, Handle<Map> map,
                              int modify_index, PropertyConstness new_constness,
                              Representation new_representation,
                              Handle<FieldType> new_field_type);
  // Returns true if the |field_type| is the most general one for
  // given |representation|.
  static inline bool IsMostGeneralFieldType(Representation representation,
                                            FieldType field_type);

  // Generalizes constness, representation and field_type if objects with given
  // instance type can have fast elements that can be transitioned by stubs or
  // optimized code to more general elements kind.
  // This generalization is necessary in order to ensure that elements kind
  // transitions performed by stubs / optimized code don't silently transition
  // PropertyConstness::kMutable fields back to VariableMode::kConst state or
  // fields with HeapObject representation and "Any" type back to "Class" type.
  static inline void GeneralizeIfCanHaveTransitionableFastElementsKind(
      Isolate* isolate, InstanceType instance_type,
      PropertyConstness* constness, Representation* representation,
      Handle<FieldType>* field_type);

  static Handle<Map> ReconfigureProperty(Isolate* isolate, Handle<Map> map,
                                         int modify_index,
                                         PropertyKind new_kind,
                                         PropertyAttributes new_attributes,
                                         Representation new_representation,
                                         Handle<FieldType> new_field_type);

  static Handle<Map> ReconfigureElementsKind(Isolate* isolate, Handle<Map> map,
                                             ElementsKind new_elements_kind);

  static Handle<Map> PrepareForDataProperty(Isolate* isolate,
                                            Handle<Map> old_map,
                                            int descriptor_number,
                                            PropertyConstness constness,
                                            Handle<Object> value);

  static Handle<Map> Normalize(Isolate* isolate, Handle<Map> map,
                               PropertyNormalizationMode mode,
                               const char* reason);

  // Tells whether the map is used for JSObjects in dictionary mode (ie
  // normalized objects, ie objects for which HasFastProperties returns false).
  // A map can never be used for both dictionary mode and fast mode JSObjects.
  // False by default and for HeapObjects that are not JSObjects.
  DECL_BOOLEAN_ACCESSORS(is_dictionary_map)

  // Tells whether the instance needs security checks when accessing its
  // properties.
  DECL_BOOLEAN_ACCESSORS(is_access_check_needed)

  // [prototype]: implicit prototype object.
  DECL_ACCESSORS(prototype, Object)
  // TODO(jkummerow): make set_prototype private.
  static void SetPrototype(Isolate* isolate, Handle<Map> map,
                           Handle<Object> prototype,
                           bool enable_prototype_setup_mode = true);

  // [constructor]: points back to the function or FunctionTemplateInfo
  // responsible for this map.
  // The field overlaps with the back pointer. All maps in a transition tree
  // have the same constructor, so maps with back pointers can walk the
  // back pointer chain until they find the map holding their constructor.
  // Returns null_value if there's neither a constructor function nor a
  // FunctionTemplateInfo available.
  DECL_ACCESSORS(constructor_or_backpointer, Object)
  inline Object GetConstructor() const;
  inline FunctionTemplateInfo GetFunctionTemplateInfo() const;
  inline void SetConstructor(Object constructor,
                             WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
  // [back pointer]: points back to the parent map from which a transition
  // leads to this map. The field overlaps with the constructor (see above).
  inline Object GetBackPointer() const;
  inline void SetBackPointer(Object value,
                             WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  // [instance descriptors]: describes the object.
  inline DescriptorArray instance_descriptors() const;
  inline DescriptorArray synchronized_instance_descriptors() const;
  void SetInstanceDescriptors(Isolate* isolate, DescriptorArray descriptors,
                              int number_of_own_descriptors);

  // [layout descriptor]: describes the object layout.
  DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
  // |layout descriptor| accessor which can be used from GC.
  inline LayoutDescriptor layout_descriptor_gc_safe() const;
  inline bool HasFastPointerLayout() const;

  // |layout descriptor| accessor that is safe to call even when
  // FLAG_unbox_double_fields is disabled (in this case Map does not contain
  // |layout_descriptor| field at all).
  inline LayoutDescriptor GetLayoutDescriptor() const;

  inline void UpdateDescriptors(Isolate* isolate, DescriptorArray descriptors,
                                LayoutDescriptor layout_descriptor,
                                int number_of_own_descriptors);
  inline void InitializeDescriptors(Isolate* isolate,
                                    DescriptorArray descriptors,
                                    LayoutDescriptor layout_descriptor);

  // [dependent code]: list of optimized codes that weakly embed this map.
  DECL_ACCESSORS(dependent_code, DependentCode)

  // [prototype_validity_cell]: Cell containing the validity bit for prototype
  // chains or Smi(0) if uninitialized.
  // The meaning of this validity cell is different for prototype maps and
  // non-prototype maps.
  // For prototype maps the validity bit "guards" modifications of prototype
  // chains going through this object. When a prototype object changes, both its
  // own validity cell and those of all "downstream" prototypes are invalidated;
  // handlers for a given receiver embed the currently valid cell for that
  // receiver's prototype during their creation and check it on execution.
  // For non-prototype maps which are used as transitioning store handlers this
  // field contains the validity cell which guards modifications of this map's
  // prototype.
  DECL_ACCESSORS(prototype_validity_cell, Object)

  // Returns true if prototype validity cell value represents "valid" prototype
  // chain state.
  inline bool IsPrototypeValidityCellValid() const;

  inline PropertyDetails GetLastDescriptorDetails() const;

  inline int LastAdded() const;

  inline int NumberOfOwnDescriptors() const;
  inline void SetNumberOfOwnDescriptors(int number);

  inline Cell RetrieveDescriptorsPointer();

  // Checks whether all properties are stored either in the map or on the object
  // (inobject, properties, or elements backing store), requiring no special
  // checks.
  bool OnlyHasSimpleProperties() const;
  inline int EnumLength() const;
  inline void SetEnumLength(int length);

  DECL_BOOLEAN_ACCESSORS(owns_descriptors)

  inline void mark_unstable();
  inline bool is_stable() const;

  DECL_BOOLEAN_ACCESSORS(is_migration_target)

  DECL_BOOLEAN_ACCESSORS(is_immutable_proto)

  // This counter is used for in-object slack tracking.
  // The in-object slack tracking is considered enabled when the counter is
  // non zero. The counter only has a valid count for initial maps. For
  // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
  // slack tracking already finished for the transition tree. Any other value
  // indicates that either inobject slack tracking is still in progress, or that
  // the map isn't part of the transition tree anymore.
  DECL_INT_ACCESSORS(construction_counter)

  DECL_BOOLEAN_ACCESSORS(is_deprecated)
  inline bool CanBeDeprecated() const;
  // Returns a non-deprecated version of the input. If the input was not
  // deprecated, it is directly returned. Otherwise, the non-deprecated version
  // is found by re-transitioning from the root of the transition tree using the
  // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
  // is found.
  static MaybeHandle<Map> TryUpdate(Isolate* isolate,
                                    Handle<Map> map) V8_WARN_UNUSED_RESULT;
  static Map TryUpdateSlow(Isolate* isolate, Map map) V8_WARN_UNUSED_RESULT;

  // Returns a non-deprecated version of the input. This method may deprecate
  // existing maps along the way if encodings conflict. Not for use while
  // gathering type feedback. Use TryUpdate in those cases instead.
  static Handle<Map> Update(Isolate* isolate, Handle<Map> map);

  static inline Handle<Map> CopyInitialMap(Isolate* isolate, Handle<Map> map);
  static Handle<Map> CopyInitialMap(Isolate* isolate, Handle<Map> map,
                                    int instance_size, int in_object_properties,
                                    int unused_property_fields);
  static Handle<Map> CopyInitialMapNormalized(
      Isolate* isolate, Handle<Map> map,
      PropertyNormalizationMode mode = CLEAR_INOBJECT_PROPERTIES);
  static Handle<Map> CopyDropDescriptors(Isolate* isolate, Handle<Map> map);
  static Handle<Map> CopyInsertDescriptor(Isolate* isolate, Handle<Map> map,
                                          Descriptor* descriptor,
                                          TransitionFlag flag);

  static MaybeObjectHandle WrapFieldType(Isolate* isolate,
                                         Handle<FieldType> type);
  static FieldType UnwrapFieldType(MaybeObject wrapped_type);

  V8_WARN_UNUSED_RESULT static MaybeHandle<Map> CopyWithField(
      Isolate* isolate, Handle<Map> map, Handle<Name> name,
      Handle<FieldType> type, PropertyAttributes attributes,
      PropertyConstness constness, Representation representation,
      TransitionFlag flag);

  V8_WARN_UNUSED_RESULT static MaybeHandle<Map> CopyWithConstant(
      Isolate* isolate, Handle<Map> map, Handle<Name> name,
      Handle<Object> constant, PropertyAttributes attributes,
      TransitionFlag flag);

  // Returns a new map with all transitions dropped from the given map and
  // the ElementsKind set.
  static Handle<Map> TransitionElementsTo(Isolate* isolate, Handle<Map> map,
                                          ElementsKind to_kind);

  static Handle<Map> AsElementsKind(Isolate* isolate, Handle<Map> map,
                                    ElementsKind kind);

  static Handle<Map> CopyAsElementsKind(Isolate* isolate, Handle<Map> map,
                                        ElementsKind kind, TransitionFlag flag);

  static Handle<Map> AsLanguageMode(Isolate* isolate, Handle<Map> initial_map,
                                    Handle<SharedFunctionInfo> shared_info);

  static Handle<Map> CopyForPreventExtensions(Isolate* isolate, Handle<Map> map,
                                              PropertyAttributes attrs_to_add,
                                              Handle<Symbol> transition_marker,
                                              const char* reason);

  static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);

  // Maximal number of fast properties. Used to restrict the number of map
  // transitions to avoid an explosion in the number of maps for objects used as
  // dictionaries.
  inline bool TooManyFastProperties(StoreOrigin store_origin) const;
  static Handle<Map> TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
                                              Handle<Name> name,
                                              Handle<Object> value,
                                              PropertyAttributes attributes,
                                              PropertyConstness constness,
                                              StoreOrigin store_origin);
  static Handle<Map> TransitionToAccessorProperty(
      Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
      Handle<Object> getter, Handle<Object> setter,
      PropertyAttributes attributes);
  static Handle<Map> ReconfigureExistingProperty(Isolate* isolate,
                                                 Handle<Map> map,
                                                 int descriptor,
                                                 PropertyKind kind,
                                                 PropertyAttributes attributes);

  inline void AppendDescriptor(Isolate* isolate, Descriptor* desc);

  // Returns a copy of the map, prepared for inserting into the transition
  // tree (if the |map| owns descriptors then the new one will share
  // descriptors with |map|).
  static Handle<Map> CopyForElementsTransition(Isolate* isolate,
                                               Handle<Map> map);

  // Returns a copy of the map, with all transitions dropped from the
  // instance descriptors.
  static Handle<Map> Copy(Isolate* isolate, Handle<Map> map,
                          const char* reason);
  static Handle<Map> Create(Isolate* isolate, int inobject_properties);

  // Returns the next free property index (only valid for FAST MODE).
  int NextFreePropertyIndex() const;

  // Returns the number of enumerable properties.
  int NumberOfEnumerableProperties() const;

  DECL_CAST(Map)

  static inline int SlackForArraySize(int old_size, int size_limit);

  static void EnsureDescriptorSlack(Isolate* isolate, Handle<Map> map,
                                    int slack);

  // Returns the map to be used for instances when the given {prototype} is
  // passed to an Object.create call. Might transition the given {prototype}.
  static Handle<Map> GetObjectCreateMap(Isolate* isolate,
                                        Handle<HeapObject> prototype);

  // Similar to {GetObjectCreateMap} but does not transition {prototype} and
  // fails gracefully by returning an empty handle instead.
  static MaybeHandle<Map> TryGetObjectCreateMap(Isolate* isolate,
                                                Handle<HeapObject> prototype);

  // Computes a hash value for this map, to be used in HashTables and such.
  int Hash();

  // Returns the transitioned map for this map with the most generic
  // elements_kind that's found in |candidates|, or |nullptr| if no match is
  // found at all.
  Map FindElementsKindTransitionedMap(Isolate* isolate,
                                      MapHandles const& candidates);

  inline bool CanTransition() const;

#define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const;
  INSTANCE_TYPE_CHECKERS(DECL_TESTER)
#undef DECL_TESTER
  inline bool IsBooleanMap() const;
  inline bool IsNullOrUndefinedMap() const;
  inline bool IsPrimitiveMap() const;
  inline bool IsSpecialReceiverMap() const;
  inline bool IsCustomElementsReceiverMap() const;

  bool IsMapInArrayPrototypeChain(Isolate* isolate) const;

  // Dispatched behavior.
  void MapPrint(std::ostream& os);
  DECL_VERIFIER(Map)

#ifdef VERIFY_HEAP
  void DictionaryMapVerify(Isolate* isolate);
#endif

  DECL_PRIMITIVE_ACCESSORS(visitor_id, VisitorId)

  static ObjectFields ObjectFieldsFrom(VisitorId visitor_id) {
    return (visitor_id < kDataOnlyVisitorIdCount)
               ? ObjectFields::kDataOnly
               : ObjectFields::kMaybePointers;
  }

  static Handle<Map> TransitionToPrototype(Isolate* isolate, Handle<Map> map,
                                           Handle<Object> prototype);

  static Handle<Map> TransitionToImmutableProto(Isolate* isolate,
                                                Handle<Map> map);

  static const int kMaxPreAllocatedPropertyFields = 255;

  // Layout description.
#define MAP_FIELDS(V)                                                     \
  /* Raw data fields. */                                                  \
  V(kInstanceSizeInWordsOffset, kUInt8Size)                               \
  V(kInObjectPropertiesStartOrConstructorFunctionIndexOffset, kUInt8Size) \
  V(kUsedOrUnusedInstanceSizeInWordsOffset, kUInt8Size)                   \
  V(kVisitorIdOffset, kUInt8Size)                                         \
  V(kInstanceTypeOffset, kUInt16Size)                                     \
  V(kBitFieldOffset, kUInt8Size)                                          \
  V(kBitField2Offset, kUInt8Size)                                         \
  V(kBitField3Offset, kUInt32Size)                                        \
  V(k64BitArchPaddingOffset,                                              \
    kSystemPointerSize == kUInt32Size ? 0 : kUInt32Size)                  \
  /* Pointer fields. */                                                   \
  V(kPointerFieldsBeginOffset, 0)                                         \
  V(kPrototypeOffset, kTaggedSize)                                        \
  V(kConstructorOrBackPointerOffset, kTaggedSize)                         \
  V(kTransitionsOrPrototypeInfoOffset, kTaggedSize)                       \
  V(kDescriptorsOffset, kTaggedSize)                                      \
  V(kLayoutDescriptorOffset, FLAG_unbox_double_fields ? kTaggedSize : 0)  \
  V(kDependentCodeOffset, kTaggedSize)                                    \
  V(kPrototypeValidityCellOffset, kTaggedSize)                            \
  V(kPointerFieldsEndOffset, 0)                                           \
  /* Total size. */                                                       \
  V(kSize, 0)

  DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS)
#undef MAP_FIELDS

  STATIC_ASSERT(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);

  class BodyDescriptor;

  // Compares this map to another to see if they describe equivalent objects.
  // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
  // it had exactly zero inobject properties.
  // The "shared" flags of both this map and |other| are ignored.
  bool EquivalentToForNormalization(const Map other,
                                    PropertyNormalizationMode mode) const;

  // Returns true if given field is unboxed double.
  inline bool IsUnboxedDoubleField(FieldIndex index) const;

  void PrintMapDetails(std::ostream& os);

  static inline Handle<Map> AddMissingTransitionsForTesting(
      Isolate* isolate, Handle<Map> split_map,
      Handle<DescriptorArray> descriptors,
      Handle<LayoutDescriptor> full_layout_descriptor);

  // Fires when the layout of an object with a leaf map changes.
  // This includes adding transitions to the leaf map or changing
  // the descriptor array.
  inline void NotifyLeafMapLayoutChange(Isolate* isolate);

  static VisitorId GetVisitorId(Map map);

  // Returns true if objects with given instance type are allowed to have
  // fast transitionable elements kinds. This predicate is used to ensure
  // that objects that can have transitionable fast elements kind will not
  // get in-place generalizable fields because the elements kind transition
  // performed by stubs or optimized code can't properly generalize such
  // fields.
  static inline bool CanHaveFastTransitionableElementsKind(
      InstanceType instance_type);
  inline bool CanHaveFastTransitionableElementsKind() const;

 private:
  // This byte encodes either the instance size without the in-object slack or
  // the slack size in properties backing store.
  // Let H be JSObject::kHeaderSize / kTaggedSize.
  // If value >= H then:
  //     - all field properties are stored in the object.
  //     - there is no property array.
  //     - value * kTaggedSize is the actual object size without the slack.
  // Otherwise:
  //     - there is no slack in the object.
  //     - the property array has value slack slots.
  // Note that this encoding requires that H = JSObject::kFieldsAdded.
  DECL_INT_ACCESSORS(used_or_unused_instance_size_in_words)

  // Returns the map that this (root) map transitions to if its elements_kind
  // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
  Map LookupElementsTransitionMap(Isolate* isolate, ElementsKind elements_kind);

  // Tries to replay property transitions starting from this (root) map using
  // the descriptor array of the |map|. The |root_map| is expected to have
  // proper elements kind and therefore elements kinds transitions are not
  // taken by this function. Returns |nullptr| if matching transition map is
  // not found.
  Map TryReplayPropertyTransitions(Isolate* isolate, Map map);

  static void ConnectTransition(Isolate* isolate, Handle<Map> parent,
                                Handle<Map> child, Handle<Name> name,
                                SimpleTransitionFlag flag);

  bool EquivalentToForTransition(const Map other) const;
  bool EquivalentToForElementsKindTransition(const Map other) const;
  static Handle<Map> RawCopy(Isolate* isolate, Handle<Map> map,
                             int instance_size, int inobject_properties);
  static Handle<Map> ShareDescriptor(Isolate* isolate, Handle<Map> map,
                                     Handle<DescriptorArray> descriptors,
                                     Descriptor* descriptor);
  static Handle<Map> AddMissingTransitions(
      Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
      Handle<LayoutDescriptor> full_layout_descriptor);
  static void InstallDescriptors(
      Isolate* isolate, Handle<Map> parent_map, Handle<Map> child_map,
      int new_descriptor, Handle<DescriptorArray> descriptors,
      Handle<LayoutDescriptor> full_layout_descriptor);
  static Handle<Map> CopyAddDescriptor(Isolate* isolate, Handle<Map> map,
                                       Descriptor* descriptor,
                                       TransitionFlag flag);
  static Handle<Map> CopyReplaceDescriptors(
      Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
      Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
      MaybeHandle<Name> maybe_name, const char* reason,
      SimpleTransitionFlag simple_flag);

  static Handle<Map> CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map,
                                           Handle<DescriptorArray> descriptors,
                                           Descriptor* descriptor, int index,
                                           TransitionFlag flag);
  static Handle<Map> CopyNormalized(Isolate* isolate, Handle<Map> map,
                                    PropertyNormalizationMode mode);

  // TODO(ishell): Move to MapUpdater.
  static Handle<Map> CopyGeneralizeAllFields(Isolate* isolate, Handle<Map> map,
                                             ElementsKind elements_kind,
                                             int modify_index,
                                             PropertyKind kind,
                                             PropertyAttributes attributes,
                                             const char* reason);

  void DeprecateTransitionTree(Isolate* isolate);

  void ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
                          LayoutDescriptor new_layout_descriptor);

  // Update field type of the given descriptor to new representation and new
  // type. The type must be prepared for storing in descriptor array:
  // it must be either a simple type or a map wrapped in a weak cell.
  void UpdateFieldType(Isolate* isolate, int descriptor_number,
                       Handle<Name> name, PropertyConstness new_constness,
                       Representation new_representation,
                       const MaybeObjectHandle& new_wrapped_type);

  // TODO(ishell): Move to MapUpdater.
  void PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index,
                            PropertyKind kind, PropertyAttributes attributes);
  // TODO(ishell): Move to MapUpdater.
  void PrintGeneralization(
      Isolate* isolate, FILE* file, const char* reason, int modify_index,
      int split, int descriptors, bool constant_to_field,
      Representation old_representation, Representation new_representation,
      MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
      MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value);

  // Use the high-level instance_descriptors/SetInstanceDescriptors instead.
  inline void set_synchronized_instance_descriptors(
      DescriptorArray array, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  static const int kFastPropertiesSoftLimit = 12;
  static const int kMaxFastProperties = 128;

  friend class MapUpdater;

  OBJECT_CONSTRUCTORS(Map, HeapObject);
};

// The cache for maps used by normalized (dictionary mode) objects.
// Such maps do not have property descriptors, so a typical program
// needs very limited number of distinct normalized maps.
class NormalizedMapCache : public WeakFixedArray {
 public:
  NEVER_READ_ONLY_SPACE
  static Handle<NormalizedMapCache> New(Isolate* isolate);

  V8_WARN_UNUSED_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
                                             PropertyNormalizationMode mode);
  void Set(Handle<Map> fast_map, Handle<Map> normalized_map);

  DECL_CAST(NormalizedMapCache)
  DECL_VERIFIER(NormalizedMapCache)

 private:
  friend bool HeapObject::IsNormalizedMapCache() const;

  static const int kEntries = 64;

  static inline int GetIndex(Handle<Map> map);

  // The following declarations hide base class methods.
  Object get(int index);
  void set(int index, Object value);

  OBJECT_CONSTRUCTORS(NormalizedMapCache, WeakFixedArray)
};

}  // namespace internal
}  // namespace v8

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

#endif  // V8_OBJECTS_MAP_H_
