LCOV - code coverage report
Current view: top level - src/objects - map.h (source / functions) Hit Total Coverage
Test: app.info Lines: 2 2 100.0 %
Date: 2019-04-18 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2017 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_OBJECTS_MAP_H_
       6             : #define V8_OBJECTS_MAP_H_
       7             : 
       8             : #include "src/globals.h"
       9             : #include "src/objects.h"
      10             : #include "src/objects/code.h"
      11             : #include "src/objects/heap-object.h"
      12             : 
      13             : // Has to be the last include (doesn't have include guards):
      14             : #include "src/objects/object-macros.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19             : enum InstanceType : uint16_t;
      20             : 
      21             : #define DATA_ONLY_VISITOR_ID_LIST(V) \
      22             :   V(BigInt)                          \
      23             :   V(ByteArray)                       \
      24             :   V(DataObject)                      \
      25             :   V(FixedDoubleArray)                \
      26             :   V(SeqOneByteString)                \
      27             :   V(SeqTwoByteString)
      28             : 
      29             : #define POINTER_VISITOR_ID_LIST(V)     \
      30             :   V(AllocationSite)                    \
      31             :   V(BytecodeArray)                     \
      32             :   V(Cell)                              \
      33             :   V(Code)                              \
      34             :   V(CodeDataContainer)                 \
      35             :   V(ConsString)                        \
      36             :   V(Context)                           \
      37             :   V(DataHandler)                       \
      38             :   V(DescriptorArray)                   \
      39             :   V(EmbedderDataArray)                 \
      40             :   V(EphemeronHashTable)                \
      41             :   V(FeedbackCell)                      \
      42             :   V(FeedbackVector)                    \
      43             :   V(FixedArray)                        \
      44             :   V(FixedFloat64Array)                 \
      45             :   V(FixedTypedArrayBase)               \
      46             :   V(FreeSpace)                         \
      47             :   V(JSApiObject)                       \
      48             :   V(JSArrayBuffer)                     \
      49             :   V(JSDataView)                        \
      50             :   V(JSFunction)                        \
      51             :   V(JSObject)                          \
      52             :   V(JSObjectFast)                      \
      53             :   V(JSTypedArray)                      \
      54             :   V(JSWeakRef)                         \
      55             :   V(JSWeakCollection)                  \
      56             :   V(Map)                               \
      57             :   V(NativeContext)                     \
      58             :   V(Oddball)                           \
      59             :   V(PreparseData)                      \
      60             :   V(PropertyArray)                     \
      61             :   V(PropertyCell)                      \
      62             :   V(PrototypeInfo)                     \
      63             :   V(SharedFunctionInfo)                \
      64             :   V(ShortcutCandidate)                 \
      65             :   V(SlicedString)                      \
      66             :   V(SmallOrderedHashMap)               \
      67             :   V(SmallOrderedHashSet)               \
      68             :   V(SmallOrderedNameDictionary)        \
      69             :   V(Struct)                            \
      70             :   V(Symbol)                            \
      71             :   V(ThinString)                        \
      72             :   V(TransitionArray)                   \
      73             :   V(UncompiledDataWithoutPreparseData) \
      74             :   V(UncompiledDataWithPreparseData)    \
      75             :   V(WasmInstanceObject)                \
      76             :   V(WeakArray)                         \
      77             :   V(WeakCell)
      78             : 
      79             : // Objects with the same visitor id are processed in the same way by
      80             : // the heap visitors. The visitor ids for data only objects must precede
      81             : // other visitor ids. We rely on kDataOnlyVisitorIdCount for quick check
      82             : // of whether an object contains only data or may contain pointers.
      83             : enum VisitorId {
      84             : #define VISITOR_ID_ENUM_DECL(id) kVisit##id,
      85             :   DATA_ONLY_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) kDataOnlyVisitorIdCount,
      86             :   POINTER_VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
      87             : #undef VISITOR_ID_ENUM_DECL
      88             :       kVisitorIdCount
      89             : };
      90             : 
      91             : enum class ObjectFields {
      92             :   kDataOnly,
      93             :   kMaybePointers,
      94             : };
      95             : 
      96             : using MapHandles = std::vector<Handle<Map>>;
      97             : 
      98             : // All heap objects have a Map that describes their structure.
      99             : //  A Map contains information about:
     100             : //  - Size information about the object
     101             : //  - How to iterate over an object (for garbage collection)
     102             : //
     103             : // Map layout:
     104             : // +---------------+---------------------------------------------+
     105             : // |   _ Type _    | _ Description _                             |
     106             : // +---------------+---------------------------------------------+
     107             : // | TaggedPointer | map - Always a pointer to the MetaMap root  |
     108             : // +---------------+---------------------------------------------+
     109             : // | Int           | The first int field                         |
     110             : //  `---+----------+---------------------------------------------+
     111             : //      | Byte     | [instance_size]                             |
     112             : //      +----------+---------------------------------------------+
     113             : //      | Byte     | If Map for a primitive type:                |
     114             : //      |          |   native context index for constructor fn   |
     115             : //      |          | If Map for an Object type:                  |
     116             : //      |          |   inobject properties start offset in words |
     117             : //      +----------+---------------------------------------------+
     118             : //      | Byte     | [used_or_unused_instance_size_in_words]     |
     119             : //      |          | For JSObject in fast mode this byte encodes |
     120             : //      |          | the size of the object that includes only   |
     121             : //      |          | the used property fields or the slack size  |
     122             : //      |          | in properties backing store.                |
     123             : //      +----------+---------------------------------------------+
     124             : //      | Byte     | [visitor_id]                                |
     125             : // +----+----------+---------------------------------------------+
     126             : // | Int           | The second int field                        |
     127             : //  `---+----------+---------------------------------------------+
     128             : //      | Short    | [instance_type]                             |
     129             : //      +----------+---------------------------------------------+
     130             : //      | Byte     | [bit_field]                                 |
     131             : //      |          |   - has_non_instance_prototype (bit 0)      |
     132             : //      |          |   - is_callable (bit 1)                     |
     133             : //      |          |   - has_named_interceptor (bit 2)           |
     134             : //      |          |   - has_indexed_interceptor (bit 3)         |
     135             : //      |          |   - is_undetectable (bit 4)                 |
     136             : //      |          |   - is_access_check_needed (bit 5)          |
     137             : //      |          |   - is_constructor (bit 6)                  |
     138             : //      |          |   - has_prototype_slot (bit 7)              |
     139             : //      +----------+---------------------------------------------+
     140             : //      | Byte     | [bit_field2]                                |
     141             : //      |          |   - is_extensible (bit 0)                   |
     142             : //      |          |   - is_prototype_map (bit 1)                |
     143             : //      |          |   - is_in_retained_map_list (bit 2)         |
     144             : //      |          |   - elements_kind (bits 3..7)               |
     145             : // +----+----------+---------------------------------------------+
     146             : // | Int           | [bit_field3]                                |
     147             : // |               |   - enum_length (bit 0..9)                  |
     148             : // |               |   - number_of_own_descriptors (bit 10..19)  |
     149             : // |               |   - is_dictionary_map (bit 20)              |
     150             : // |               |   - owns_descriptors (bit 21)               |
     151             : // |               |   - has_hidden_prototype (bit 22)           |
     152             : // |               |   - is_deprecated (bit 23)                  |
     153             : // |               |   - is_unstable (bit 24)                    |
     154             : // |               |   - is_migration_target (bit 25)            |
     155             : // |               |   - is_immutable_proto (bit 26)             |
     156             : // |               |   - new_target_is_base (bit 27)             |
     157             : // |               |   - may_have_interesting_symbols (bit 28)   |
     158             : // |               |   - construction_counter (bit 29..31)       |
     159             : // |               |                                             |
     160             : // +*************************************************************+
     161             : // | Int           | On systems with 64bit pointer types, there  |
     162             : // |               | is an unused 32bits after bit_field3        |
     163             : // +*************************************************************+
     164             : // | TaggedPointer | [prototype]                                 |
     165             : // +---------------+---------------------------------------------+
     166             : // | TaggedPointer | [constructor_or_backpointer]                |
     167             : // +---------------+---------------------------------------------+
     168             : // | TaggedPointer | If Map is a prototype map:                  |
     169             : // |               |   [prototype_info]                          |
     170             : // |               | Else:                                       |
     171             : // |               |   [raw_transitions]                         |
     172             : // +---------------+---------------------------------------------+
     173             : // | TaggedPointer | [instance_descriptors]                      |
     174             : // +*************************************************************+
     175             : // ! TaggedPointer ! [layout_descriptors]                        !
     176             : // !               ! Field is only present if compile-time flag  !
     177             : // !               ! FLAG_unbox_double_fields is enabled         !
     178             : // !               ! (basically on 64 bit architectures)         !
     179             : // +*************************************************************+
     180             : // | TaggedPointer | [dependent_code]                            |
     181             : // +---------------+---------------------------------------------+
     182             : 
     183             : class Map : public HeapObject {
     184             :  public:
     185             :   // Instance size.
     186             :   // Size in bytes or kVariableSizeSentinel if instances do not have
     187             :   // a fixed size.
     188             :   DECL_INT_ACCESSORS(instance_size)
     189             :   // Size in words or kVariableSizeSentinel if instances do not have
     190             :   // a fixed size.
     191             :   DECL_INT_ACCESSORS(instance_size_in_words)
     192             : 
     193             :   // [inobject_properties_start_or_constructor_function_index]:
     194             :   // Provides access to the inobject properties start offset in words in case of
     195             :   // JSObject maps, or the constructor function index in case of primitive maps.
     196             :   DECL_INT_ACCESSORS(inobject_properties_start_or_constructor_function_index)
     197             : 
     198             :   // Get/set the in-object property area start offset in words in the object.
     199             :   inline int GetInObjectPropertiesStartInWords() const;
     200             :   inline void SetInObjectPropertiesStartInWords(int value);
     201             :   // Count of properties allocated in the object (JSObject only).
     202             :   inline int GetInObjectProperties() const;
     203             :   // Index of the constructor function in the native context (primitives only),
     204             :   // or the special sentinel value to indicate that there is no object wrapper
     205             :   // for the primitive (i.e. in case of null or undefined).
     206             :   static const int kNoConstructorFunctionIndex = 0;
     207             :   inline int GetConstructorFunctionIndex() const;
     208             :   inline void SetConstructorFunctionIndex(int value);
     209             :   static MaybeHandle<JSFunction> GetConstructorFunction(
     210             :       Handle<Map> map, Handle<Context> native_context);
     211             : 
     212             :   // Retrieve interceptors.
     213             :   inline InterceptorInfo GetNamedInterceptor();
     214             :   inline InterceptorInfo GetIndexedInterceptor();
     215             : 
     216             :   // Instance type.
     217             :   DECL_PRIMITIVE_ACCESSORS(instance_type, InstanceType)
     218             : 
     219             :   // Returns the size of the used in-object area including object header
     220             :   // (only used for JSObject in fast mode, for the other kinds of objects it
     221             :   // is equal to the instance size).
     222             :   inline int UsedInstanceSize() const;
     223             : 
     224             :   // Tells how many unused property fields (in-object or out-of object) are
     225             :   // available in the instance (only used for JSObject in fast mode).
     226             :   inline int UnusedPropertyFields() const;
     227             :   // Tells how many unused in-object property words are present.
     228             :   inline int UnusedInObjectProperties() const;
     229             :   // Updates the counters tracking unused fields in the object.
     230             :   inline void SetInObjectUnusedPropertyFields(int unused_property_fields);
     231             :   // Updates the counters tracking unused fields in the property array.
     232             :   inline void SetOutOfObjectUnusedPropertyFields(int unused_property_fields);
     233             :   inline void CopyUnusedPropertyFields(Map map);
     234             :   inline void CopyUnusedPropertyFieldsAdjustedForInstanceSize(Map map);
     235             :   inline void AccountAddedPropertyField();
     236             :   inline void AccountAddedOutOfObjectPropertyField(
     237             :       int unused_in_property_array);
     238             : 
     239             :   //
     240             :   // Bit field.
     241             :   //
     242             :   DECL_PRIMITIVE_ACCESSORS(bit_field, byte)
     243             :   // Atomic accessors, used for whitelisting legitimate concurrent accesses.
     244             :   DECL_PRIMITIVE_ACCESSORS(relaxed_bit_field, byte)
     245             : 
     246             : // Bit positions for |bit_field|.
     247             : #define MAP_BIT_FIELD_FIELDS(V, _)          \
     248             :   V(HasNonInstancePrototypeBit, bool, 1, _) \
     249             :   V(IsCallableBit, bool, 1, _)              \
     250             :   V(HasNamedInterceptorBit, bool, 1, _)     \
     251             :   V(HasIndexedInterceptorBit, bool, 1, _)   \
     252             :   V(IsUndetectableBit, bool, 1, _)          \
     253             :   V(IsAccessCheckNeededBit, bool, 1, _)     \
     254             :   V(IsConstructorBit, bool, 1, _)           \
     255             :   V(HasPrototypeSlotBit, bool, 1, _)
     256             : 
     257             :   DEFINE_BIT_FIELDS(MAP_BIT_FIELD_FIELDS)
     258             : #undef MAP_BIT_FIELD_FIELDS
     259             : 
     260             :   //
     261             :   // Bit field 2.
     262             :   //
     263             :   DECL_PRIMITIVE_ACCESSORS(bit_field2, byte)
     264             : 
     265             : // Bit positions for |bit_field2|.
     266             : #define MAP_BIT_FIELD2_FIELDS(V, _)     \
     267             :   V(IsExtensibleBit, bool, 1, _)        \
     268             :   V(IsPrototypeMapBit, bool, 1, _)      \
     269             :   V(IsInRetainedMapListBit, bool, 1, _) \
     270             :   V(ElementsKindBits, ElementsKind, 5, _)
     271             : 
     272             :   DEFINE_BIT_FIELDS(MAP_BIT_FIELD2_FIELDS)
     273             : #undef MAP_BIT_FIELD2_FIELDS
     274             : 
     275             :   //
     276             :   // Bit field 3.
     277             :   //
     278             :   DECL_PRIMITIVE_ACCESSORS(bit_field3, uint32_t)
     279             : 
     280             :   // Clear uninitialized padding space. This ensures that the snapshot content
     281             :   // is deterministic. Depending on the V8 build mode there could be no padding.
     282             :   V8_INLINE void clear_padding();
     283             : 
     284             : // Bit positions for |bit_field3|.
     285             : #define MAP_BIT_FIELD3_FIELDS(V, _)                               \
     286             :   V(EnumLengthBits, int, kDescriptorIndexBitCount, _)             \
     287             :   V(NumberOfOwnDescriptorsBits, int, kDescriptorIndexBitCount, _) \
     288             :   V(IsDictionaryMapBit, bool, 1, _)                               \
     289             :   V(OwnsDescriptorsBit, bool, 1, _)                               \
     290             :   V(HasHiddenPrototypeBit, bool, 1, _)                            \
     291             :   V(IsDeprecatedBit, bool, 1, _)                                  \
     292             :   V(IsUnstableBit, bool, 1, _)                                    \
     293             :   V(IsMigrationTargetBit, bool, 1, _)                             \
     294             :   V(IsImmutablePrototypeBit, bool, 1, _)                          \
     295             :   V(NewTargetIsBaseBit, bool, 1, _)                               \
     296             :   V(MayHaveInterestingSymbolsBit, bool, 1, _)                     \
     297             :   V(ConstructionCounterBits, int, 3, _)
     298             : 
     299             :   DEFINE_BIT_FIELDS(MAP_BIT_FIELD3_FIELDS)
     300             : #undef MAP_BIT_FIELD3_FIELDS
     301             : 
     302             :   STATIC_ASSERT(NumberOfOwnDescriptorsBits::kMax >= kMaxNumberOfDescriptors);
     303             : 
     304             :   static const int kSlackTrackingCounterStart = 7;
     305             :   static const int kSlackTrackingCounterEnd = 1;
     306             :   static const int kNoSlackTracking = 0;
     307             :   STATIC_ASSERT(kSlackTrackingCounterStart <= ConstructionCounterBits::kMax);
     308             : 
     309             :   // Inobject slack tracking is the way to reclaim unused inobject space.
     310             :   //
     311             :   // The instance size is initially determined by adding some slack to
     312             :   // expected_nof_properties (to allow for a few extra properties added
     313             :   // after the constructor). There is no guarantee that the extra space
     314             :   // will not be wasted.
     315             :   //
     316             :   // Here is the algorithm to reclaim the unused inobject space:
     317             :   // - Detect the first constructor call for this JSFunction.
     318             :   //   When it happens enter the "in progress" state: initialize construction
     319             :   //   counter in the initial_map.
     320             :   // - While the tracking is in progress initialize unused properties of a new
     321             :   //   object with one_pointer_filler_map instead of undefined_value (the "used"
     322             :   //   part is initialized with undefined_value as usual). This way they can
     323             :   //   be resized quickly and safely.
     324             :   // - Once enough objects have been created  compute the 'slack'
     325             :   //   (traverse the map transition tree starting from the
     326             :   //   initial_map and find the lowest value of unused_property_fields).
     327             :   // - Traverse the transition tree again and decrease the instance size
     328             :   //   of every map. Existing objects will resize automatically (they are
     329             :   //   filled with one_pointer_filler_map). All further allocations will
     330             :   //   use the adjusted instance size.
     331             :   // - SharedFunctionInfo's expected_nof_properties left unmodified since
     332             :   //   allocations made using different closures could actually create different
     333             :   //   kind of objects (see prototype inheritance pattern).
     334             :   //
     335             :   //  Important: inobject slack tracking is not attempted during the snapshot
     336             :   //  creation.
     337             : 
     338             :   static const int kGenerousAllocationCount =
     339             :       kSlackTrackingCounterStart - kSlackTrackingCounterEnd + 1;
     340             : 
     341             :   // Starts the tracking by initializing object constructions countdown counter.
     342             :   void StartInobjectSlackTracking();
     343             : 
     344             :   // True if the object constructions countdown counter is a range
     345             :   // [kSlackTrackingCounterEnd, kSlackTrackingCounterStart].
     346             :   inline bool IsInobjectSlackTrackingInProgress() const;
     347             : 
     348             :   // Does the tracking step.
     349             :   inline void InobjectSlackTrackingStep(Isolate* isolate);
     350             : 
     351             :   // Computes inobject slack for the transition tree starting at this initial
     352             :   // map.
     353             :   int ComputeMinObjectSlack(Isolate* isolate);
     354             :   inline int InstanceSizeFromSlack(int slack) const;
     355             : 
     356             :   // Completes inobject slack tracking for the transition tree starting at this
     357             :   // initial map.
     358             :   V8_EXPORT_PRIVATE void CompleteInobjectSlackTracking(Isolate* isolate);
     359             : 
     360             :   // Tells whether the object in the prototype property will be used
     361             :   // for instances created from this function.  If the prototype
     362             :   // property is set to a value that is not a JSObject, the prototype
     363             :   // property will not be used to create instances of the function.
     364             :   // See ECMA-262, 13.2.2.
     365             :   DECL_BOOLEAN_ACCESSORS(has_non_instance_prototype)
     366             : 
     367             :   // Tells whether the instance has a [[Construct]] internal method.
     368             :   // This property is implemented according to ES6, section 7.2.4.
     369             :   DECL_BOOLEAN_ACCESSORS(is_constructor)
     370             : 
     371             :   // Tells whether the instance with this map may have properties for
     372             :   // interesting symbols on it.
     373             :   // An "interesting symbol" is one for which Name::IsInterestingSymbol()
     374             :   // returns true, i.e. a well-known symbol like @@toStringTag.
     375             :   DECL_BOOLEAN_ACCESSORS(may_have_interesting_symbols)
     376             : 
     377             :   DECL_BOOLEAN_ACCESSORS(has_prototype_slot)
     378             : 
     379             :   // Tells whether the instance with this map has a hidden prototype.
     380             :   DECL_BOOLEAN_ACCESSORS(has_hidden_prototype)
     381             : 
     382             :   // Records and queries whether the instance has a named interceptor.
     383             :   DECL_BOOLEAN_ACCESSORS(has_named_interceptor)
     384             : 
     385             :   // Records and queries whether the instance has an indexed interceptor.
     386             :   DECL_BOOLEAN_ACCESSORS(has_indexed_interceptor)
     387             : 
     388             :   // Tells whether the instance is undetectable.
     389             :   // An undetectable object is a special class of JSObject: 'typeof' operator
     390             :   // returns undefined, ToBoolean returns false. Otherwise it behaves like
     391             :   // a normal JS object.  It is useful for implementing undetectable
     392             :   // document.all in Firefox & Safari.
     393             :   // See https://bugzilla.mozilla.org/show_bug.cgi?id=248549.
     394             :   DECL_BOOLEAN_ACCESSORS(is_undetectable)
     395             : 
     396             :   // Tells whether the instance has a [[Call]] internal method.
     397             :   // This property is implemented according to ES6, section 7.2.3.
     398             :   DECL_BOOLEAN_ACCESSORS(is_callable)
     399             : 
     400             :   DECL_BOOLEAN_ACCESSORS(new_target_is_base)
     401             :   DECL_BOOLEAN_ACCESSORS(is_extensible)
     402             :   DECL_BOOLEAN_ACCESSORS(is_prototype_map)
     403             :   inline bool is_abandoned_prototype_map() const;
     404             : 
     405             :   // Whether the instance has been added to the retained map list by
     406             :   // Heap::AddRetainedMap.
     407             :   DECL_BOOLEAN_ACCESSORS(is_in_retained_map_list)
     408             : 
     409             :   DECL_PRIMITIVE_ACCESSORS(elements_kind, ElementsKind)
     410             : 
     411             :   // Tells whether the instance has fast elements that are only Smis.
     412             :   inline bool has_fast_smi_elements() const;
     413             : 
     414             :   // Tells whether the instance has fast elements.
     415             :   inline bool has_fast_object_elements() const;
     416             :   inline bool has_fast_smi_or_object_elements() const;
     417             :   inline bool has_fast_double_elements() const;
     418             :   inline bool has_fast_elements() const;
     419             :   inline bool has_sloppy_arguments_elements() const;
     420             :   inline bool has_fast_sloppy_arguments_elements() const;
     421             :   inline bool has_fast_string_wrapper_elements() const;
     422             :   inline bool has_fixed_typed_array_elements() const;
     423             :   inline bool has_dictionary_elements() const;
     424             :   inline bool has_frozen_or_sealed_elements() const;
     425             :   inline bool has_sealed_elements() const;
     426             :   inline bool has_frozen_elements() const;
     427             : 
     428             :   // Returns true if the current map doesn't have DICTIONARY_ELEMENTS but if a
     429             :   // map with DICTIONARY_ELEMENTS was found in the prototype chain.
     430             :   bool DictionaryElementsInPrototypeChainOnly(Isolate* isolate);
     431             : 
     432             :   inline Map ElementsTransitionMap();
     433             : 
     434             :   inline FixedArrayBase GetInitialElements() const;
     435             : 
     436             :   // [raw_transitions]: Provides access to the transitions storage field.
     437             :   // Don't call set_raw_transitions() directly to overwrite transitions, use
     438             :   // the TransitionArray::ReplaceTransitions() wrapper instead!
     439             :   DECL_ACCESSORS(raw_transitions, MaybeObject)
     440             :   // [prototype_info]: Per-prototype metadata. Aliased with transitions
     441             :   // (which prototype maps don't have).
     442             :   DECL_ACCESSORS(prototype_info, Object)
     443             :   // PrototypeInfo is created lazily using this helper (which installs it on
     444             :   // the given prototype's map).
     445             :   static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
     446             :       Handle<JSObject> prototype, Isolate* isolate);
     447             :   static Handle<PrototypeInfo> GetOrCreatePrototypeInfo(
     448             :       Handle<Map> prototype_map, Isolate* isolate);
     449             :   inline bool should_be_fast_prototype_map() const;
     450             :   static void SetShouldBeFastPrototypeMap(Handle<Map> map, bool value,
     451             :                                           Isolate* isolate);
     452             : 
     453             :   // [prototype chain validity cell]: Associated with a prototype object,
     454             :   // stored in that object's map, indicates that prototype chains through this
     455             :   // object are currently valid. The cell will be invalidated and replaced when
     456             :   // the prototype chain changes. When there's nothing to guard (for example,
     457             :   // when direct prototype is null or Proxy) this function returns Smi with
     458             :   // |kPrototypeChainValid| sentinel value.
     459             :   static Handle<Object> GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
     460             :                                                               Isolate* isolate);
     461             :   static const int kPrototypeChainValid = 0;
     462             :   static const int kPrototypeChainInvalid = 1;
     463             : 
     464             :   static bool IsPrototypeChainInvalidated(Map map);
     465             : 
     466             :   // Return the map of the root of object's prototype chain.
     467             :   Map GetPrototypeChainRootMap(Isolate* isolate) const;
     468             : 
     469             :   V8_EXPORT_PRIVATE Map FindRootMap(Isolate* isolate) const;
     470             :   V8_EXPORT_PRIVATE Map FindFieldOwner(Isolate* isolate, int descriptor) const;
     471             : 
     472             :   inline int GetInObjectPropertyOffset(int index) const;
     473             : 
     474             :   class FieldCounts {
     475             :    public:
     476             :     FieldCounts(int mutable_count, int const_count)
     477             :         : mutable_count_(mutable_count), const_count_(const_count) {}
     478             : 
     479     2556712 :     int GetTotal() const { return mutable_count() + const_count(); }
     480             : 
     481             :     int mutable_count() const { return mutable_count_; }
     482             :     int const_count() const { return const_count_; }
     483             : 
     484             :    private:
     485             :     int mutable_count_;
     486             :     int const_count_;
     487             :   };
     488             : 
     489             :   FieldCounts GetFieldCounts() const;
     490             :   int NumberOfFields() const;
     491             : 
     492             :   bool HasOutOfObjectProperties() const;
     493             : 
     494             :   // Returns true if transition to the given map requires special
     495             :   // synchronization with the concurrent marker.
     496             :   bool TransitionRequiresSynchronizationWithGC(Map target) const;
     497             :   // Returns true if transition to the given map removes a tagged in-object
     498             :   // field.
     499             :   bool TransitionRemovesTaggedField(Map target) const;
     500             :   // Returns true if transition to the given map replaces a tagged in-object
     501             :   // field with an untagged in-object field.
     502             :   bool TransitionChangesTaggedFieldToUntaggedField(Map target) const;
     503             : 
     504             :   // TODO(ishell): candidate with JSObject::MigrateToMap().
     505             :   bool InstancesNeedRewriting(Map target) const;
     506             :   bool InstancesNeedRewriting(Map target, int target_number_of_fields,
     507             :                               int target_inobject, int target_unused,
     508             :                               int* old_number_of_fields) const;
     509             :   V8_WARN_UNUSED_RESULT static Handle<FieldType> GeneralizeFieldType(
     510             :       Representation rep1, Handle<FieldType> type1, Representation rep2,
     511             :       Handle<FieldType> type2, Isolate* isolate);
     512             :   static void GeneralizeField(Isolate* isolate, Handle<Map> map,
     513             :                               int modify_index, PropertyConstness new_constness,
     514             :                               Representation new_representation,
     515             :                               Handle<FieldType> new_field_type);
     516             :   // Returns true if the |field_type| is the most general one for
     517             :   // given |representation|.
     518             :   static inline bool IsMostGeneralFieldType(Representation representation,
     519             :                                             FieldType field_type);
     520             : 
     521             :   // Generalizes constness, representation and field_type if objects with given
     522             :   // instance type can have fast elements that can be transitioned by stubs or
     523             :   // optimized code to more general elements kind.
     524             :   // This generalization is necessary in order to ensure that elements kind
     525             :   // transitions performed by stubs / optimized code don't silently transition
     526             :   // PropertyConstness::kMutable fields back to VariableMode::kConst state or
     527             :   // fields with HeapObject representation and "Any" type back to "Class" type.
     528             :   static inline void GeneralizeIfCanHaveTransitionableFastElementsKind(
     529             :       Isolate* isolate, InstanceType instance_type,
     530             :       PropertyConstness* constness, Representation* representation,
     531             :       Handle<FieldType>* field_type);
     532             : 
     533             :   V8_EXPORT_PRIVATE static Handle<Map> ReconfigureProperty(
     534             :       Isolate* isolate, Handle<Map> map, int modify_index,
     535             :       PropertyKind new_kind, PropertyAttributes new_attributes,
     536             :       Representation new_representation, Handle<FieldType> new_field_type);
     537             : 
     538             :   V8_EXPORT_PRIVATE static Handle<Map> ReconfigureElementsKind(
     539             :       Isolate* isolate, Handle<Map> map, ElementsKind new_elements_kind);
     540             : 
     541             :   V8_EXPORT_PRIVATE static Handle<Map> PrepareForDataProperty(
     542             :       Isolate* isolate, Handle<Map> old_map, int descriptor_number,
     543             :       PropertyConstness constness, Handle<Object> value);
     544             : 
     545             :   V8_EXPORT_PRIVATE static Handle<Map> Normalize(Isolate* isolate,
     546             :                                                  Handle<Map> map,
     547             :                                                  PropertyNormalizationMode mode,
     548             :                                                  const char* reason);
     549             : 
     550             :   // Tells whether the map is used for JSObjects in dictionary mode (ie
     551             :   // normalized objects, ie objects for which HasFastProperties returns false).
     552             :   // A map can never be used for both dictionary mode and fast mode JSObjects.
     553             :   // False by default and for HeapObjects that are not JSObjects.
     554             :   DECL_BOOLEAN_ACCESSORS(is_dictionary_map)
     555             : 
     556             :   // Tells whether the instance needs security checks when accessing its
     557             :   // properties.
     558             :   DECL_BOOLEAN_ACCESSORS(is_access_check_needed)
     559             : 
     560             :   // [prototype]: implicit prototype object.
     561             :   DECL_ACCESSORS(prototype, HeapObject)
     562             :   // TODO(jkummerow): make set_prototype private.
     563             :   V8_EXPORT_PRIVATE static void SetPrototype(
     564             :       Isolate* isolate, Handle<Map> map, Handle<HeapObject> prototype,
     565             :       bool enable_prototype_setup_mode = true);
     566             : 
     567             :   // [constructor]: points back to the function or FunctionTemplateInfo
     568             :   // responsible for this map.
     569             :   // The field overlaps with the back pointer. All maps in a transition tree
     570             :   // have the same constructor, so maps with back pointers can walk the
     571             :   // back pointer chain until they find the map holding their constructor.
     572             :   // Returns null_value if there's neither a constructor function nor a
     573             :   // FunctionTemplateInfo available.
     574             :   DECL_ACCESSORS(constructor_or_backpointer, Object)
     575             :   inline Object GetConstructor() const;
     576             :   inline FunctionTemplateInfo GetFunctionTemplateInfo() const;
     577             :   inline void SetConstructor(Object constructor,
     578             :                              WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     579             :   // [back pointer]: points back to the parent map from which a transition
     580             :   // leads to this map. The field overlaps with the constructor (see above).
     581             :   inline HeapObject GetBackPointer() const;
     582             :   inline void SetBackPointer(Object value,
     583             :                              WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     584             : 
     585             :   // [instance descriptors]: describes the object.
     586             :   inline DescriptorArray instance_descriptors() const;
     587             :   inline DescriptorArray synchronized_instance_descriptors() const;
     588             :   V8_EXPORT_PRIVATE void SetInstanceDescriptors(Isolate* isolate,
     589             :                                                 DescriptorArray descriptors,
     590             :                                                 int number_of_own_descriptors);
     591             : 
     592             :   // [layout descriptor]: describes the object layout.
     593             :   DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
     594             :   // |layout descriptor| accessor which can be used from GC.
     595             :   inline LayoutDescriptor layout_descriptor_gc_safe() const;
     596             :   inline bool HasFastPointerLayout() const;
     597             : 
     598             :   // |layout descriptor| accessor that is safe to call even when
     599             :   // FLAG_unbox_double_fields is disabled (in this case Map does not contain
     600             :   // |layout_descriptor| field at all).
     601             :   inline LayoutDescriptor GetLayoutDescriptor() const;
     602             : 
     603             :   inline void UpdateDescriptors(Isolate* isolate, DescriptorArray descriptors,
     604             :                                 LayoutDescriptor layout_descriptor,
     605             :                                 int number_of_own_descriptors);
     606             :   inline void InitializeDescriptors(Isolate* isolate,
     607             :                                     DescriptorArray descriptors,
     608             :                                     LayoutDescriptor layout_descriptor);
     609             : 
     610             :   // [dependent code]: list of optimized codes that weakly embed this map.
     611             :   DECL_ACCESSORS(dependent_code, DependentCode)
     612             : 
     613             :   // [prototype_validity_cell]: Cell containing the validity bit for prototype
     614             :   // chains or Smi(0) if uninitialized.
     615             :   // The meaning of this validity cell is different for prototype maps and
     616             :   // non-prototype maps.
     617             :   // For prototype maps the validity bit "guards" modifications of prototype
     618             :   // chains going through this object. When a prototype object changes, both its
     619             :   // own validity cell and those of all "downstream" prototypes are invalidated;
     620             :   // handlers for a given receiver embed the currently valid cell for that
     621             :   // receiver's prototype during their creation and check it on execution.
     622             :   // For non-prototype maps which are used as transitioning store handlers this
     623             :   // field contains the validity cell which guards modifications of this map's
     624             :   // prototype.
     625             :   DECL_ACCESSORS(prototype_validity_cell, Object)
     626             : 
     627             :   // Returns true if prototype validity cell value represents "valid" prototype
     628             :   // chain state.
     629             :   inline bool IsPrototypeValidityCellValid() const;
     630             : 
     631             :   inline PropertyDetails GetLastDescriptorDetails() const;
     632             : 
     633             :   inline int LastAdded() const;
     634             : 
     635             :   inline int NumberOfOwnDescriptors() const;
     636             :   inline void SetNumberOfOwnDescriptors(int number);
     637             : 
     638             :   inline Cell RetrieveDescriptorsPointer();
     639             : 
     640             :   // Checks whether all properties are stored either in the map or on the object
     641             :   // (inobject, properties, or elements backing store), requiring no special
     642             :   // checks.
     643             :   bool OnlyHasSimpleProperties() const;
     644             :   inline int EnumLength() const;
     645             :   inline void SetEnumLength(int length);
     646             : 
     647             :   DECL_BOOLEAN_ACCESSORS(owns_descriptors)
     648             : 
     649             :   inline void mark_unstable();
     650             :   inline bool is_stable() const;
     651             : 
     652             :   DECL_BOOLEAN_ACCESSORS(is_migration_target)
     653             : 
     654             :   DECL_BOOLEAN_ACCESSORS(is_immutable_proto)
     655             : 
     656             :   // This counter is used for in-object slack tracking.
     657             :   // The in-object slack tracking is considered enabled when the counter is
     658             :   // non zero. The counter only has a valid count for initial maps. For
     659             :   // transitioned maps only kNoSlackTracking has a meaning, namely that inobject
     660             :   // slack tracking already finished for the transition tree. Any other value
     661             :   // indicates that either inobject slack tracking is still in progress, or that
     662             :   // the map isn't part of the transition tree anymore.
     663             :   DECL_INT_ACCESSORS(construction_counter)
     664             : 
     665             :   DECL_BOOLEAN_ACCESSORS(is_deprecated)
     666             :   inline bool CanBeDeprecated() const;
     667             :   // Returns a non-deprecated version of the input. If the input was not
     668             :   // deprecated, it is directly returned. Otherwise, the non-deprecated version
     669             :   // is found by re-transitioning from the root of the transition tree using the
     670             :   // descriptor array of the map. Returns MaybeHandle<Map>() if no updated map
     671             :   // is found.
     672             :   V8_EXPORT_PRIVATE static MaybeHandle<Map> TryUpdate(
     673             :       Isolate* isolate, Handle<Map> map) V8_WARN_UNUSED_RESULT;
     674             :   V8_EXPORT_PRIVATE static Map TryUpdateSlow(Isolate* isolate,
     675             :                                              Map map) V8_WARN_UNUSED_RESULT;
     676             : 
     677             :   // Returns a non-deprecated version of the input. This method may deprecate
     678             :   // existing maps along the way if encodings conflict. Not for use while
     679             :   // gathering type feedback. Use TryUpdate in those cases instead.
     680             :   V8_EXPORT_PRIVATE static Handle<Map> Update(Isolate* isolate,
     681             :                                               Handle<Map> map);
     682             : 
     683             :   static inline Handle<Map> CopyInitialMap(Isolate* isolate, Handle<Map> map);
     684             :   V8_EXPORT_PRIVATE static Handle<Map> CopyInitialMap(
     685             :       Isolate* isolate, Handle<Map> map, int instance_size,
     686             :       int in_object_properties, int unused_property_fields);
     687             :   static Handle<Map> CopyInitialMapNormalized(
     688             :       Isolate* isolate, Handle<Map> map,
     689             :       PropertyNormalizationMode mode = CLEAR_INOBJECT_PROPERTIES);
     690             :   static Handle<Map> CopyDropDescriptors(Isolate* isolate, Handle<Map> map);
     691             :   V8_EXPORT_PRIVATE static Handle<Map> CopyInsertDescriptor(
     692             :       Isolate* isolate, Handle<Map> map, Descriptor* descriptor,
     693             :       TransitionFlag flag);
     694             : 
     695             :   static MaybeObjectHandle WrapFieldType(Isolate* isolate,
     696             :                                          Handle<FieldType> type);
     697             :   V8_EXPORT_PRIVATE static FieldType UnwrapFieldType(MaybeObject wrapped_type);
     698             : 
     699             :   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Map> CopyWithField(
     700             :       Isolate* isolate, Handle<Map> map, Handle<Name> name,
     701             :       Handle<FieldType> type, PropertyAttributes attributes,
     702             :       PropertyConstness constness, Representation representation,
     703             :       TransitionFlag flag);
     704             : 
     705             :   V8_EXPORT_PRIVATE V8_WARN_UNUSED_RESULT static MaybeHandle<Map>
     706             :   CopyWithConstant(Isolate* isolate, Handle<Map> map, Handle<Name> name,
     707             :                    Handle<Object> constant, PropertyAttributes attributes,
     708             :                    TransitionFlag flag);
     709             : 
     710             :   // Returns a new map with all transitions dropped from the given map and
     711             :   // the ElementsKind set.
     712             :   static Handle<Map> TransitionElementsTo(Isolate* isolate, Handle<Map> map,
     713             :                                           ElementsKind to_kind);
     714             : 
     715             :   V8_EXPORT_PRIVATE static Handle<Map> AsElementsKind(Isolate* isolate,
     716             :                                                       Handle<Map> map,
     717             :                                                       ElementsKind kind);
     718             : 
     719             :   static Handle<Map> CopyAsElementsKind(Isolate* isolate, Handle<Map> map,
     720             :                                         ElementsKind kind, TransitionFlag flag);
     721             : 
     722             :   static Handle<Map> AsLanguageMode(Isolate* isolate, Handle<Map> initial_map,
     723             :                                     Handle<SharedFunctionInfo> shared_info);
     724             : 
     725             :   V8_EXPORT_PRIVATE static Handle<Map> CopyForPreventExtensions(
     726             :       Isolate* isolate, Handle<Map> map, PropertyAttributes attrs_to_add,
     727             :       Handle<Symbol> transition_marker, const char* reason);
     728             : 
     729             :   static Handle<Map> FixProxy(Handle<Map> map, InstanceType type, int size);
     730             : 
     731             :   // Maximal number of fast properties. Used to restrict the number of map
     732             :   // transitions to avoid an explosion in the number of maps for objects used as
     733             :   // dictionaries.
     734             :   inline bool TooManyFastProperties(StoreOrigin store_origin) const;
     735             :   V8_EXPORT_PRIVATE static Handle<Map> TransitionToDataProperty(
     736             :       Isolate* isolate, Handle<Map> map, Handle<Name> name,
     737             :       Handle<Object> value, PropertyAttributes attributes,
     738             :       PropertyConstness constness, StoreOrigin store_origin);
     739             :   V8_EXPORT_PRIVATE static Handle<Map> TransitionToAccessorProperty(
     740             :       Isolate* isolate, Handle<Map> map, Handle<Name> name, int descriptor,
     741             :       Handle<Object> getter, Handle<Object> setter,
     742             :       PropertyAttributes attributes);
     743             :   V8_EXPORT_PRIVATE static Handle<Map> ReconfigureExistingProperty(
     744             :       Isolate* isolate, Handle<Map> map, int descriptor, PropertyKind kind,
     745             :       PropertyAttributes attributes);
     746             : 
     747             :   inline void AppendDescriptor(Isolate* isolate, Descriptor* desc);
     748             : 
     749             :   // Returns a copy of the map, prepared for inserting into the transition
     750             :   // tree (if the |map| owns descriptors then the new one will share
     751             :   // descriptors with |map|).
     752             :   static Handle<Map> CopyForElementsTransition(Isolate* isolate,
     753             :                                                Handle<Map> map);
     754             : 
     755             :   // Returns a copy of the map, with all transitions dropped from the
     756             :   // instance descriptors.
     757             :   static Handle<Map> Copy(Isolate* isolate, Handle<Map> map,
     758             :                           const char* reason);
     759             :   V8_EXPORT_PRIVATE static Handle<Map> Create(Isolate* isolate,
     760             :                                               int inobject_properties);
     761             : 
     762             :   // Returns the next free property index (only valid for FAST MODE).
     763             :   int NextFreePropertyIndex() const;
     764             : 
     765             :   // Returns the number of enumerable properties.
     766             :   int NumberOfEnumerableProperties() const;
     767             : 
     768             :   DECL_CAST(Map)
     769             : 
     770             :   static inline int SlackForArraySize(int old_size, int size_limit);
     771             : 
     772             :   V8_EXPORT_PRIVATE static void EnsureDescriptorSlack(Isolate* isolate,
     773             :                                                       Handle<Map> map,
     774             :                                                       int slack);
     775             : 
     776             :   // Returns the map to be used for instances when the given {prototype} is
     777             :   // passed to an Object.create call. Might transition the given {prototype}.
     778             :   static Handle<Map> GetObjectCreateMap(Isolate* isolate,
     779             :                                         Handle<HeapObject> prototype);
     780             : 
     781             :   // Similar to {GetObjectCreateMap} but does not transition {prototype} and
     782             :   // fails gracefully by returning an empty handle instead.
     783             :   static MaybeHandle<Map> TryGetObjectCreateMap(Isolate* isolate,
     784             :                                                 Handle<HeapObject> prototype);
     785             : 
     786             :   // Computes a hash value for this map, to be used in HashTables and such.
     787             :   int Hash();
     788             : 
     789             :   // Returns the transitioned map for this map with the most generic
     790             :   // elements_kind that's found in |candidates|, or |nullptr| if no match is
     791             :   // found at all.
     792             :   V8_EXPORT_PRIVATE Map FindElementsKindTransitionedMap(
     793             :       Isolate* isolate, MapHandles const& candidates);
     794             : 
     795             :   inline bool CanTransition() const;
     796             : 
     797             : #define DECL_TESTER(Type, ...) inline bool Is##Type##Map() const;
     798             :   INSTANCE_TYPE_CHECKERS(DECL_TESTER)
     799             : #undef DECL_TESTER
     800             :   inline bool IsBooleanMap() const;
     801             :   inline bool IsNullOrUndefinedMap() const;
     802             :   inline bool IsPrimitiveMap() const;
     803             :   inline bool IsSpecialReceiverMap() const;
     804             :   inline bool IsCustomElementsReceiverMap() const;
     805             : 
     806             :   bool IsMapInArrayPrototypeChain(Isolate* isolate) const;
     807             : 
     808             :   // Dispatched behavior.
     809             :   void MapPrint(std::ostream& os);
     810             :   DECL_VERIFIER(Map)
     811             : 
     812             : #ifdef VERIFY_HEAP
     813             :   void DictionaryMapVerify(Isolate* isolate);
     814             : #endif
     815             : 
     816             :   DECL_PRIMITIVE_ACCESSORS(visitor_id, VisitorId)
     817             : 
     818             :   static ObjectFields ObjectFieldsFrom(VisitorId visitor_id) {
     819             :     return (visitor_id < kDataOnlyVisitorIdCount)
     820             :                ? ObjectFields::kDataOnly
     821    60370230 :                : ObjectFields::kMaybePointers;
     822             :   }
     823             : 
     824             :   V8_EXPORT_PRIVATE static Handle<Map> TransitionToPrototype(
     825             :       Isolate* isolate, Handle<Map> map, Handle<HeapObject> prototype);
     826             : 
     827             :   static Handle<Map> TransitionToImmutableProto(Isolate* isolate,
     828             :                                                 Handle<Map> map);
     829             : 
     830             :   static const int kMaxPreAllocatedPropertyFields = 255;
     831             : 
     832             :   // Layout description.
     833             : #define MAP_FIELDS(V)                                                       \
     834             :   /* Raw data fields. */                                                    \
     835             :   V(kInstanceSizeInWordsOffset, kUInt8Size)                                 \
     836             :   V(kInObjectPropertiesStartOrConstructorFunctionIndexOffset, kUInt8Size)   \
     837             :   V(kUsedOrUnusedInstanceSizeInWordsOffset, kUInt8Size)                     \
     838             :   V(kVisitorIdOffset, kUInt8Size)                                           \
     839             :   V(kInstanceTypeOffset, kUInt16Size)                                       \
     840             :   V(kBitFieldOffset, kUInt8Size)                                            \
     841             :   V(kBitField2Offset, kUInt8Size)                                           \
     842             :   V(kBitField3Offset, kUInt32Size)                                          \
     843             :   /* Adds padding to make tagged fields kTaggedSize-aligned. */             \
     844             :   V(kOptionalPaddingOffset, OBJECT_POINTER_PADDING(kOptionalPaddingOffset)) \
     845             :   /* Pointer fields. */                                                     \
     846             :   V(kPointerFieldsBeginOffset, 0)                                           \
     847             :   V(kPrototypeOffset, kTaggedSize)                                          \
     848             :   V(kConstructorOrBackPointerOffset, kTaggedSize)                           \
     849             :   V(kTransitionsOrPrototypeInfoOffset, kTaggedSize)                         \
     850             :   V(kDescriptorsOffset, kTaggedSize)                                        \
     851             :   V(kLayoutDescriptorOffset, FLAG_unbox_double_fields ? kTaggedSize : 0)    \
     852             :   V(kDependentCodeOffset, kTaggedSize)                                      \
     853             :   V(kPrototypeValidityCellOffset, kTaggedSize)                              \
     854             :   V(kPointerFieldsEndOffset, 0)                                             \
     855             :   /* Total size. */                                                         \
     856             :   V(kSize, 0)
     857             : 
     858             :   DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS)
     859             : #undef MAP_FIELDS
     860             : 
     861             :   STATIC_ASSERT(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
     862             : 
     863             :   class BodyDescriptor;
     864             : 
     865             :   // Compares this map to another to see if they describe equivalent objects.
     866             :   // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
     867             :   // it had exactly zero inobject properties.
     868             :   // The "shared" flags of both this map and |other| are ignored.
     869             :   bool EquivalentToForNormalization(const Map other,
     870             :                                     PropertyNormalizationMode mode) const;
     871             : 
     872             :   // Returns true if given field is unboxed double.
     873             :   inline bool IsUnboxedDoubleField(FieldIndex index) const;
     874             : 
     875             :   void PrintMapDetails(std::ostream& os);
     876             : 
     877             :   static inline Handle<Map> AddMissingTransitionsForTesting(
     878             :       Isolate* isolate, Handle<Map> split_map,
     879             :       Handle<DescriptorArray> descriptors,
     880             :       Handle<LayoutDescriptor> full_layout_descriptor);
     881             : 
     882             :   // Fires when the layout of an object with a leaf map changes.
     883             :   // This includes adding transitions to the leaf map or changing
     884             :   // the descriptor array.
     885             :   inline void NotifyLeafMapLayoutChange(Isolate* isolate);
     886             : 
     887             :   V8_EXPORT_PRIVATE static VisitorId GetVisitorId(Map map);
     888             : 
     889             :   // Returns true if objects with given instance type are allowed to have
     890             :   // fast transitionable elements kinds. This predicate is used to ensure
     891             :   // that objects that can have transitionable fast elements kind will not
     892             :   // get in-place generalizable fields because the elements kind transition
     893             :   // performed by stubs or optimized code can't properly generalize such
     894             :   // fields.
     895             :   static inline bool CanHaveFastTransitionableElementsKind(
     896             :       InstanceType instance_type);
     897             :   inline bool CanHaveFastTransitionableElementsKind() const;
     898             : 
     899             :   // Whether this is the map of the given native context's global proxy.
     900             :   bool IsMapOfGlobalProxy(Handle<NativeContext> native_context) const;
     901             : 
     902             :  private:
     903             :   // This byte encodes either the instance size without the in-object slack or
     904             :   // the slack size in properties backing store.
     905             :   // Let H be JSObject::kHeaderSize / kTaggedSize.
     906             :   // If value >= H then:
     907             :   //     - all field properties are stored in the object.
     908             :   //     - there is no property array.
     909             :   //     - value * kTaggedSize is the actual object size without the slack.
     910             :   // Otherwise:
     911             :   //     - there is no slack in the object.
     912             :   //     - the property array has value slack slots.
     913             :   // Note that this encoding requires that H = JSObject::kFieldsAdded.
     914             :   DECL_INT_ACCESSORS(used_or_unused_instance_size_in_words)
     915             : 
     916             :   // Returns the map that this (root) map transitions to if its elements_kind
     917             :   // is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
     918             :   Map LookupElementsTransitionMap(Isolate* isolate, ElementsKind elements_kind);
     919             : 
     920             :   // Tries to replay property transitions starting from this (root) map using
     921             :   // the descriptor array of the |map|. The |root_map| is expected to have
     922             :   // proper elements kind and therefore elements kinds transitions are not
     923             :   // taken by this function. Returns |nullptr| if matching transition map is
     924             :   // not found.
     925             :   Map TryReplayPropertyTransitions(Isolate* isolate, Map map);
     926             : 
     927             :   static void ConnectTransition(Isolate* isolate, Handle<Map> parent,
     928             :                                 Handle<Map> child, Handle<Name> name,
     929             :                                 SimpleTransitionFlag flag);
     930             : 
     931             :   bool EquivalentToForTransition(const Map other) const;
     932             :   bool EquivalentToForElementsKindTransition(const Map other) const;
     933             :   static Handle<Map> RawCopy(Isolate* isolate, Handle<Map> map,
     934             :                              int instance_size, int inobject_properties);
     935             :   static Handle<Map> ShareDescriptor(Isolate* isolate, Handle<Map> map,
     936             :                                      Handle<DescriptorArray> descriptors,
     937             :                                      Descriptor* descriptor);
     938             :   V8_EXPORT_PRIVATE static Handle<Map> AddMissingTransitions(
     939             :       Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
     940             :       Handle<LayoutDescriptor> full_layout_descriptor);
     941             :   static void InstallDescriptors(
     942             :       Isolate* isolate, Handle<Map> parent_map, Handle<Map> child_map,
     943             :       int new_descriptor, Handle<DescriptorArray> descriptors,
     944             :       Handle<LayoutDescriptor> full_layout_descriptor);
     945             :   static Handle<Map> CopyAddDescriptor(Isolate* isolate, Handle<Map> map,
     946             :                                        Descriptor* descriptor,
     947             :                                        TransitionFlag flag);
     948             :   static Handle<Map> CopyReplaceDescriptors(
     949             :       Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
     950             :       Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
     951             :       MaybeHandle<Name> maybe_name, const char* reason,
     952             :       SimpleTransitionFlag simple_flag);
     953             : 
     954             :   static Handle<Map> CopyReplaceDescriptor(Isolate* isolate, Handle<Map> map,
     955             :                                            Handle<DescriptorArray> descriptors,
     956             :                                            Descriptor* descriptor, int index,
     957             :                                            TransitionFlag flag);
     958             :   static Handle<Map> CopyNormalized(Isolate* isolate, Handle<Map> map,
     959             :                                     PropertyNormalizationMode mode);
     960             : 
     961             :   // TODO(ishell): Move to MapUpdater.
     962             :   static Handle<Map> CopyGeneralizeAllFields(Isolate* isolate, Handle<Map> map,
     963             :                                              ElementsKind elements_kind,
     964             :                                              int modify_index,
     965             :                                              PropertyKind kind,
     966             :                                              PropertyAttributes attributes,
     967             :                                              const char* reason);
     968             : 
     969             :   void DeprecateTransitionTree(Isolate* isolate);
     970             : 
     971             :   void ReplaceDescriptors(Isolate* isolate, DescriptorArray new_descriptors,
     972             :                           LayoutDescriptor new_layout_descriptor);
     973             : 
     974             :   // Update field type of the given descriptor to new representation and new
     975             :   // type. The type must be prepared for storing in descriptor array:
     976             :   // it must be either a simple type or a map wrapped in a weak cell.
     977             :   void UpdateFieldType(Isolate* isolate, int descriptor_number,
     978             :                        Handle<Name> name, PropertyConstness new_constness,
     979             :                        Representation new_representation,
     980             :                        const MaybeObjectHandle& new_wrapped_type);
     981             : 
     982             :   // TODO(ishell): Move to MapUpdater.
     983             :   void PrintReconfiguration(Isolate* isolate, FILE* file, int modify_index,
     984             :                             PropertyKind kind, PropertyAttributes attributes);
     985             :   // TODO(ishell): Move to MapUpdater.
     986             :   void PrintGeneralization(
     987             :       Isolate* isolate, FILE* file, const char* reason, int modify_index,
     988             :       int split, int descriptors, bool constant_to_field,
     989             :       Representation old_representation, Representation new_representation,
     990             :       MaybeHandle<FieldType> old_field_type, MaybeHandle<Object> old_value,
     991             :       MaybeHandle<FieldType> new_field_type, MaybeHandle<Object> new_value);
     992             : 
     993             :   // Use the high-level instance_descriptors/SetInstanceDescriptors instead.
     994             :   inline void set_synchronized_instance_descriptors(
     995             :       DescriptorArray array, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
     996             : 
     997             :   static const int kFastPropertiesSoftLimit = 12;
     998             :   static const int kMaxFastProperties = 128;
     999             : 
    1000             :   friend class MapUpdater;
    1001             : 
    1002             :   OBJECT_CONSTRUCTORS(Map, HeapObject);
    1003             : };
    1004             : 
    1005             : // The cache for maps used by normalized (dictionary mode) objects.
    1006             : // Such maps do not have property descriptors, so a typical program
    1007             : // needs very limited number of distinct normalized maps.
    1008             : class NormalizedMapCache : public WeakFixedArray {
    1009             :  public:
    1010             :   NEVER_READ_ONLY_SPACE
    1011             :   static Handle<NormalizedMapCache> New(Isolate* isolate);
    1012             : 
    1013             :   V8_WARN_UNUSED_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
    1014             :                                              PropertyNormalizationMode mode);
    1015             :   void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
    1016             : 
    1017             :   DECL_CAST(NormalizedMapCache)
    1018             :   DECL_VERIFIER(NormalizedMapCache)
    1019             : 
    1020             :  private:
    1021             :   friend bool HeapObject::IsNormalizedMapCache() const;
    1022             : 
    1023             :   static const int kEntries = 64;
    1024             : 
    1025             :   static inline int GetIndex(Handle<Map> map);
    1026             : 
    1027             :   // The following declarations hide base class methods.
    1028             :   Object get(int index);
    1029             :   void set(int index, Object value);
    1030             : 
    1031             :   OBJECT_CONSTRUCTORS(NormalizedMapCache, WeakFixedArray);
    1032             : };
    1033             : 
    1034             : }  // namespace internal
    1035             : }  // namespace v8
    1036             : 
    1037             : #include "src/objects/object-macros-undef.h"
    1038             : 
    1039             : #endif  // V8_OBJECTS_MAP_H_

Generated by: LCOV version 1.10