code); DECLARE_CAST(HeapObject) // Return the write barrier mode for this. Callers of this function // must be able to present a reference to an DisallowHeapAllocation // object as a sign that they are not going to use this function // from code that allocates and thus invalidates the returned write // barrier mode. inline WriteBarrierMode GetWriteBarrierMode( const DisallowHeapAllocation& promise); // Dispatched behavior. void HeapObjectShortPrint(OStream& os); // NOLINT #ifdef OBJECT_PRINT void PrintHeader(OStream& os, const char* id); // NOLINT #endif DECLARE_PRINTER(HeapObject) DECLARE_VERIFIER(HeapObject) #ifdef VERIFY_HEAP inline void VerifyObjectField(int offset); inline void VerifySmiField(int offset); // Verify a pointer is a valid HeapObject pointer that points to object // areas in the heap. static void VerifyHeapPointer(Object* p); #endif // Layout description. // First field in a heap object is map. static const int kMapOffset = Object::kHeaderSize; static const int kHeaderSize = kMapOffset + kPointerSize; STATIC_ASSERT(kMapOffset == Internals::kHeapObjectMapOffset); protected: // helpers for calling an ObjectVisitor to iterate over pointers in the // half-open range [start, end) specified as integer offsets inline void IteratePointers(ObjectVisitor* v, int start, int end); // as above, for the single element at "offset" inline void IteratePointer(ObjectVisitor* v, int offset); // as above, for the next code link of a code object. inline void IterateNextCodeLink(ObjectVisitor* v, int offset); private: DISALLOW_IMPLICIT_CONSTRUCTORS(HeapObject); }; // This class describes a body of an object of a fixed size // in which all pointer fields are located in the [start_offset, end_offset) // interval. template class FixedBodyDescriptor { public: static const int kStartOffset = start_offset; static const int kEndOffset = end_offset; static const int kSize = size; static inline void IterateBody(HeapObject* obj, ObjectVisitor* v); template static inline void IterateBody(HeapObject* obj) { StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset), HeapObject::RawField(obj, end_offset)); } }; // This class describes a body of an object of a variable size // in which all pointer fields are located in the [start_offset, object_size) // interval. template class FlexibleBodyDescriptor { public: static const int kStartOffset = start_offset; static inline void IterateBody(HeapObject* obj, int object_size, ObjectVisitor* v); template static inline void IterateBody(HeapObject* obj, int object_size) { StaticVisitor::VisitPointers(HeapObject::RawField(obj, start_offset), HeapObject::RawField(obj, object_size)); } }; // The HeapNumber class describes heap allocated numbers that cannot be // represented in a Smi (small integer) class HeapNumber: public HeapObject { public: // [value]: number value. inline double value() const; inline void set_value(double value); DECLARE_CAST(HeapNumber) // Dispatched behavior. bool HeapNumberBooleanValue(); void HeapNumberPrint(OStream& os); // NOLINT DECLARE_VERIFIER(HeapNumber) inline int get_exponent(); inline int get_sign(); // Layout description. static const int kValueOffset = HeapObject::kHeaderSize; // IEEE doubles are two 32 bit words. The first is just mantissa, the second // is a mixture of sign, exponent and mantissa. The offsets of two 32 bit // words within double numbers are endian dependent and they are set // accordingly. #if defined(V8_TARGET_LITTLE_ENDIAN) static const int kMantissaOffset = kValueOffset; static const int kExponentOffset = kValueOffset + 4; #elif defined(V8_TARGET_BIG_ENDIAN) static const int kMantissaOffset = kValueOffset + 4; static const int kExponentOffset = kValueOffset; #else #error Unknown byte ordering #endif static const int kSize = kValueOffset + kDoubleSize; static const uint32_t kSignMask = 0x80000000u; static const uint32_t kExponentMask = 0x7ff00000u; static const uint32_t kMantissaMask = 0xfffffu; static const int kMantissaBits = 52; static const int kExponentBits = 11; static const int kExponentBias = 1023; static const int kExponentShift = 20; static const int kInfinityOrNanExponent = (kExponentMask >> kExponentShift) - kExponentBias; static const int kMantissaBitsInTopWord = 20; static const int kNonMantissaBitsInTopWord = 12; private: DISALLOW_IMPLICIT_CONSTRUCTORS(HeapNumber); }; enum EnsureElementsMode { DONT_ALLOW_DOUBLE_ELEMENTS, ALLOW_COPIED_DOUBLE_ELEMENTS, ALLOW_CONVERTED_DOUBLE_ELEMENTS }; // Indicates whether a property should be set or (re)defined. Setting of a // property causes attributes to remain unchanged, writability to be checked // and callbacks to be called. Defining of a property causes attributes to // be updated and callbacks to be overridden. enum SetPropertyMode { SET_PROPERTY, DEFINE_PROPERTY }; // Indicator for one component of an AccessorPair. enum AccessorComponent { ACCESSOR_GETTER, ACCESSOR_SETTER }; // JSReceiver includes types on which properties can be defined, i.e., // JSObject and JSProxy. class JSReceiver: public HeapObject { public: enum DeleteMode { NORMAL_DELETION, STRICT_DELETION, FORCE_DELETION }; DECLARE_CAST(JSReceiver) MUST_USE_RESULT static MaybeHandle SetElement( Handle object, uint32_t index, Handle value, PropertyAttributes attributes, StrictMode strict_mode); // Implementation of [[HasProperty]], ECMA-262 5th edition, section 8.12.6. MUST_USE_RESULT static inline Maybe HasProperty( Handle object, Handle name); MUST_USE_RESULT static inline Maybe HasOwnProperty(Handle, Handle name); MUST_USE_RESULT static inline Maybe HasElement( Handle object, uint32_t index); MUST_USE_RESULT static inline Maybe HasOwnElement( Handle object, uint32_t index); // Implementation of [[Delete]], ECMA-262 5th edition, section 8.12.7. MUST_USE_RESULT static MaybeHandle DeleteProperty( Handle object, Handle name, DeleteMode mode = NORMAL_DELETION); MUST_USE_RESULT static MaybeHandle DeleteElement( Handle object, uint32_t index, DeleteMode mode = NORMAL_DELETION); // Tests for the fast common case for property enumeration. bool IsSimpleEnum(); // Returns the class name ([[Class]] property in the specification). String* class_name(); // Returns the constructor name (the name (possibly, inferred name) of the // function that was used to instantiate the object). String* constructor_name(); MUST_USE_RESULT static inline Maybe GetPropertyAttributes( Handle object, Handle name); MUST_USE_RESULT static Maybe GetPropertyAttributes( LookupIterator* it); MUST_USE_RESULT static Maybe GetOwnPropertyAttributes( Handle object, Handle name); MUST_USE_RESULT static inline Maybe GetElementAttribute( Handle object, uint32_t index); MUST_USE_RESULT static inline Maybe GetOwnElementAttribute(Handle object, uint32_t index); // Return the constructor function (may be Heap::null_value()). inline Object* GetConstructor(); // Retrieves a permanent object identity hash code. The undefined value might // be returned in case no hash was created yet. inline Object* GetIdentityHash(); // Retrieves a permanent object identity hash code. May create and store a // hash code if needed and none exists. inline static Handle GetOrCreateIdentityHash( Handle object); enum KeyCollectionType { OWN_ONLY, INCLUDE_PROTOS }; // Computes the enumerable keys for a JSObject. Used for implementing // "for (n in object) { }". MUST_USE_RESULT static MaybeHandle GetKeys( Handle object, KeyCollectionType type); private: DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver); }; // Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable. class ObjectHashTable; // Forward declaration for JSObject::Copy. class AllocationSite; // The JSObject describes real heap allocated JavaScript objects with // properties. // Note that the map of JSObject changes during execution to enable inline // caching. class JSObject: public JSReceiver { public: // [properties]: Backing storage for properties. // properties is a FixedArray in the fast case and a Dictionary in the // slow case. DECL_ACCESSORS(properties, FixedArray) // Get and set fast properties. inline void initialize_properties(); inline bool HasFastProperties(); inline NameDictionary* property_dictionary(); // Gets slow properties. // [elements]: The elements (properties with names that are integers). // // Elements can be in two general modes: fast and slow. Each mode // corrensponds to a set of object representations of elements that // have something in common. // // In the fast mode elements is a FixedArray and so each element can // be quickly accessed. This fact is used in the generated code. The // elements array can have one of three maps in this mode: // fixed_array_map, sloppy_arguments_elements_map or // fixed_cow_array_map (for copy-on-write arrays). In the latter case // the elements array may be shared by a few objects and so before // writing to any element the array must be copied. Use // EnsureWritableFastElements in this case. // // In the slow mode the elements is either a NumberDictionary, an // ExternalArray, or a FixedArray parameter map for a (sloppy) // arguments object. DECL_ACCESSORS(elements, FixedArrayBase) inline void initialize_elements(); static void ResetElements(Handle object); static inline void SetMapAndElements(Handle object, Handle map, Handle elements); inline ElementsKind GetElementsKind(); inline ElementsAccessor* GetElementsAccessor(); // Returns true if an object has elements of FAST_SMI_ELEMENTS ElementsKind. inline bool HasFastSmiElements(); // Returns true if an object has elements of FAST_ELEMENTS ElementsKind. inline bool HasFastObjectElements(); // Returns true if an object has elements of FAST_ELEMENTS or // FAST_SMI_ONLY_ELEMENTS. inline bool HasFastSmiOrObjectElements(); // Returns true if an object has any of the fast elements kinds. inline bool HasFastElements(); // Returns true if an object has elements of FAST_DOUBLE_ELEMENTS // ElementsKind. inline bool HasFastDoubleElements(); // Returns true if an object has elements of FAST_HOLEY_*_ELEMENTS // ElementsKind. inline bool HasFastHoleyElements(); inline bool HasSloppyArgumentsElements(); inline bool HasDictionaryElements(); inline bool HasExternalUint8ClampedElements(); inline bool HasExternalArrayElements(); inline bool HasExternalInt8Elements(); inline bool HasExternalUint8Elements(); inline bool HasExternalInt16Elements(); inline bool HasExternalUint16Elements(); inline bool HasExternalInt32Elements(); inline bool HasExternalUint32Elements(); inline bool HasExternalFloat32Elements(); inline bool HasExternalFloat64Elements(); inline bool HasFixedTypedArrayElements(); inline bool HasFixedUint8ClampedElements(); inline bool HasFixedArrayElements(); inline bool HasFixedInt8Elements(); inline bool HasFixedUint8Elements(); inline bool HasFixedInt16Elements(); inline bool HasFixedUint16Elements(); inline bool HasFixedInt32Elements(); inline bool HasFixedUint32Elements(); inline bool HasFixedFloat32Elements(); inline bool HasFixedFloat64Elements(); bool HasFastArgumentsElements(); bool HasDictionaryArgumentsElements(); inline SeededNumberDictionary* element_dictionary(); // Gets slow elements. // Requires: HasFastElements(). static Handle EnsureWritableFastElements( Handle object); // Collects elements starting at index 0. // Undefined values are placed after non-undefined values. // Returns the number of non-undefined values. static Handle PrepareElementsForSort(Handle object, uint32_t limit); // As PrepareElementsForSort, but only on objects where elements is // a dictionary, and it will stay a dictionary. Collates undefined and // unexisting elements below limit from position zero of the elements. static Handle PrepareSlowElementsForSort(Handle object, uint32_t limit); MUST_USE_RESULT static MaybeHandle SetPropertyWithInterceptor( LookupIterator* it, Handle value); // SetLocalPropertyIgnoreAttributes converts callbacks to fields. We need to // grant an exemption to ExecutableAccessor callbacks in some cases. enum ExecutableAccessorInfoHandling { DEFAULT_HANDLING, DONT_FORCE_FIELD }; MUST_USE_RESULT static MaybeHandle SetOwnPropertyIgnoreAttributes( Handle object, Handle key, Handle value, PropertyAttributes attributes, ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); static void AddProperty(Handle object, Handle key, Handle value, PropertyAttributes attributes); // Extend the receiver with a single fast property appeared first in the // passed map. This also extends the property backing store if necessary. static void AllocateStorageForMap(Handle object, Handle map); // Migrates the given object to a map whose field representations are the // lowest upper bound of all known representations for that field. static void MigrateInstance(Handle instance); // Migrates the given object only if the target map is already available, // or returns false if such a map is not yet available. static bool TryMigrateInstance(Handle instance); // Sets the property value in a normalized object given (key, value, details). // Handles the special representation of JS global objects. static void SetNormalizedProperty(Handle object, Handle key, Handle value, PropertyDetails details); static void OptimizeAsPrototype(Handle object, PrototypeOptimizationMode mode); static void ReoptimizeIfPrototype(Handle object); // Retrieve interceptors. InterceptorInfo* GetNamedInterceptor(); InterceptorInfo* GetIndexedInterceptor(); // Used from JSReceiver. MUST_USE_RESULT static Maybe GetPropertyAttributesWithInterceptor(Handle holder, Handle receiver, Handle name); MUST_USE_RESULT static Maybe GetPropertyAttributesWithFailedAccessCheck(LookupIterator* it); MUST_USE_RESULT static Maybe GetElementAttributeWithReceiver(Handle object, Handle receiver, uint32_t index, bool check_prototype); // Retrieves an AccessorPair property from the given object. Might return // undefined if the property doesn't exist or is of a different kind. MUST_USE_RESULT static MaybeHandle GetAccessor( Handle object, Handle name, AccessorComponent component); // Defines an AccessorPair property on the given object. // TODO(mstarzinger): Rename to SetAccessor(). static MaybeHandle DefineAccessor(Handle object, Handle name, Handle getter, Handle setter, PropertyAttributes attributes); // Defines an AccessorInfo property on the given object. MUST_USE_RESULT static MaybeHandle SetAccessor( Handle object, Handle info); MUST_USE_RESULT static MaybeHandle GetPropertyWithInterceptor( Handle object, Handle receiver, Handle name); // Returns true if this is an instance of an api function and has // been modified since it was created. May give false positives. bool IsDirty(); // Accessors for hidden properties object. // // Hidden properties are not own properties of the object itself. // Instead they are stored in an auxiliary structure kept as an own // property with a special name Heap::hidden_string(). But if the // receiver is a JSGlobalProxy then the auxiliary object is a property // of its prototype, and if it's a detached proxy, then you can't have // hidden properties. // Sets a hidden property on this object. Returns this object if successful, // undefined if called on a detached proxy. static Handle SetHiddenProperty(Handle object, Handle key, Handle value); // Gets the value of a hidden property with the given key. Returns the hole // if the property doesn't exist (or if called on a detached proxy), // otherwise returns the value set for the key. Object* GetHiddenProperty(Handle key); // Deletes a hidden property. Deleting a non-existing property is // considered successful. static void DeleteHiddenProperty(Handle object, Handle key); // Returns true if the object has a property with the hidden string as name. static bool HasHiddenProperties(Handle object); static void SetIdentityHash(Handle object, Handle hash); static inline void ValidateElements(Handle object); // Makes sure that this object can contain HeapObject as elements. static inline void EnsureCanContainHeapObjectElements(Handle obj); // Makes sure that this object can contain the specified elements. static inline void EnsureCanContainElements( Handle object, Object** elements, uint32_t count, EnsureElementsMode mode); static inline void EnsureCanContainElements( Handle object, Handle elements, uint32_t length, EnsureElementsMode mode); static void EnsureCanContainElements( Handle object, Arguments* arguments, uint32_t first_arg, uint32_t arg_count, EnsureElementsMode mode); // Would we convert a fast elements array to dictionary mode given // an access at key? bool WouldConvertToSlowElements(Handle key); // Do we want to keep the elements in fast case when increasing the // capacity? bool ShouldConvertToSlowElements(int new_capacity); // Returns true if the backing storage for the slow-case elements of // this object takes up nearly as much space as a fast-case backing // storage would. In that case the JSObject should have fast // elements. bool ShouldConvertToFastElements(); // Returns true if the elements of JSObject contains only values that can be // represented in a FixedDoubleArray and has at least one value that can only // be represented as a double and not a Smi. bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements); // Computes the new capacity when expanding the elements of a JSObject. static int NewElementsCapacity(int old_capacity) { // (old_capacity + 50%) + 16 return old_capacity + (old_capacity >> 1) + 16; } // These methods do not perform access checks! MUST_USE_RESULT static MaybeHandle GetOwnElementAccessorPair( Handle object, uint32_t index); MUST_USE_RESULT static MaybeHandle SetFastElement( Handle object, uint32_t index, Handle value, StrictMode strict_mode, bool check_prototype); MUST_USE_RESULT static MaybeHandle SetOwnElement( Handle object, uint32_t index, Handle value, StrictMode strict_mode); // Empty handle is returned if the element cannot be set to the given value. MUST_USE_RESULT static MaybeHandle SetElement( Handle object, uint32_t index, Handle value, PropertyAttributes attributes, StrictMode strict_mode, bool check_prototype = true, SetPropertyMode set_mode = SET_PROPERTY); // Returns the index'th element. // The undefined object if index is out of bounds. MUST_USE_RESULT static MaybeHandle GetElementWithInterceptor( Handle object, Handle receiver, uint32_t index); enum SetFastElementsCapacitySmiMode { kAllowSmiElements, kForceSmiElements, kDontAllowSmiElements }; // Replace the elements' backing store with fast elements of the given // capacity. Update the length for JSArrays. Returns the new backing // store. static Handle SetFastElementsCapacityAndLength( Handle object, int capacity, int length, SetFastElementsCapacitySmiMode smi_mode); static void SetFastDoubleElementsCapacityAndLength( Handle object, int capacity, int length); // Lookup interceptors are used for handling properties controlled by host // objects. inline bool HasNamedInterceptor(); inline bool HasIndexedInterceptor(); // Computes the enumerable keys from interceptors. Used for debug mirrors and // by JSReceiver::GetKeys. MUST_USE_RESULT static MaybeHandle GetKeysForNamedInterceptor( Handle object, Handle receiver); MUST_USE_RESULT static MaybeHandle GetKeysForIndexedInterceptor( Handle object, Handle receiver); // Support functions for v8 api (needed for correct interceptor behavior). MUST_USE_RESULT static Maybe HasRealNamedProperty( Handle object, Handle key); MUST_USE_RESULT static Maybe HasRealElementProperty( Handle object, uint32_t index); MUST_USE_RESULT static Maybe HasRealNamedCallbackProperty( Handle object, Handle key); // Get the header size for a JSObject. Used to compute the index of // internal fields as well as the number of internal fields. inline int GetHeaderSize(); inline int GetInternalFieldCount(); inline int GetInternalFieldOffset(int index); inline Object* GetInternalField(int index); inline void SetInternalField(int index, Object* value); inline void SetInternalField(int index, Smi* value); // Returns the number of properties on this object filtering out properties // with the specified attributes (ignoring interceptors). int NumberOfOwnProperties(PropertyAttributes filter = NONE); // Fill in details for properties into storage starting at the specified // index. void GetOwnPropertyNames( FixedArray* storage, int index, PropertyAttributes filter = NONE); // Returns the number of properties on this object filtering out properties // with the specified attributes (ignoring interceptors). int NumberOfOwnElements(PropertyAttributes filter); // Returns the number of enumerable elements (ignoring interceptors). int NumberOfEnumElements(); // Returns the number of elements on this object filtering out elements // with the specified attributes (ignoring interceptors). int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter); // Count and fill in the enumerable elements into storage. // (storage->length() == NumberOfEnumElements()). // If storage is NULL, will count the elements without adding // them to any storage. // Returns the number of enumerable elements. int GetEnumElementKeys(FixedArray* storage); // Returns a new map with all transitions dropped from the object's current // map and the ElementsKind set. static Handle GetElementsTransitionMap(Handle object, ElementsKind to_kind); static void TransitionElementsKind(Handle object, ElementsKind to_kind); static void MigrateToMap(Handle object, Handle new_map); // Convert the object to use the canonical dictionary // representation. If the object is expected to have additional properties // added this number can be indicated to have the backing store allocated to // an initial capacity for holding these properties. static void NormalizeProperties(Handle object, PropertyNormalizationMode mode, int expected_additional_properties); // Convert and update the elements backing store to be a // SeededNumberDictionary dictionary. Returns the backing after conversion. static Handle NormalizeElements( Handle object); // Transform slow named properties to fast variants. static void MigrateSlowToFast(Handle object, int unused_property_fields); // Access fast-case object properties at index. static Handle FastPropertyAt(Handle object, Representation representation, FieldIndex index); inline Object* RawFastPropertyAt(FieldIndex index); inline void FastPropertyAtPut(FieldIndex index, Object* value); void WriteToField(int descriptor, Object* value); // Access to in object properties. inline int GetInObjectPropertyOffset(int index); inline Object* InObjectPropertyAt(int index); inline Object* InObjectPropertyAtPut(int index, Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); // Set the object's prototype (only JSReceiver and null are allowed values). MUST_USE_RESULT static MaybeHandle SetPrototype( Handle object, Handle value, bool from_javascript); // Initializes the body after properties slot, properties slot is // initialized by set_properties. Fill the pre-allocated fields with // pre_allocated_value and the rest with filler_value. // Note: this call does not update write barrier, the caller is responsible // to ensure that |filler_value| can be collected without WB here. inline void InitializeBody(Map* map, Object* pre_allocated_value, Object* filler_value); // Check whether this object references another object bool ReferencesObject(Object* obj); // Disalow further properties to be added to the object. MUST_USE_RESULT static MaybeHandle PreventExtensions( Handle object); // ES5 Object.freeze MUST_USE_RESULT static MaybeHandle Freeze(Handle object); // Called the first time an object is observed with ES7 Object.observe. static void SetObserved(Handle object); // Copy object. enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 }; static Handle Copy(Handle object); MUST_USE_RESULT static MaybeHandle DeepCopy( Handle object, AllocationSiteUsageContext* site_context, DeepCopyHints hints = kNoHints); MUST_USE_RESULT static MaybeHandle DeepWalk( Handle object, AllocationSiteCreationContext* site_context); static Handle GetDataProperty(Handle object, Handle key); static Handle GetDataProperty(LookupIterator* it); DECLARE_CAST(JSObject) // Dispatched behavior. void JSObjectShortPrint(StringStream* accumulator); DECLARE_PRINTER(JSObject) DECLARE_VERIFIER(JSObject) #ifdef OBJECT_PRINT void PrintProperties(OStream& os); // NOLINT void PrintElements(OStream& os); // NOLINT void PrintTransitions(OStream& os); // NOLINT #endif static void PrintElementsTransition( FILE* file, Handle object, ElementsKind from_kind, Handle from_elements, ElementsKind to_kind, Handle to_elements); void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map); #ifdef DEBUG // Structure for collecting spill information about JSObjects. class SpillInformation { public: void Clear(); void Print(); int number_of_objects_; int number_of_objects_with_fast_properties_; int number_of_objects_with_fast_elements_; int number_of_fast_used_fields_; int number_of_fast_unused_fields_; int number_of_slow_used_properties_; int number_of_slow_unused_properties_; int number_of_fast_used_elements_; int number_of_fast_unused_elements_; int number_of_slow_used_elements_; int number_of_slow_unused_elements_; }; void IncrementSpillStatistics(SpillInformation* info); #endif #ifdef VERIFY_HEAP // If a GC was caused while constructing this object, the elements pointer // may point to a one pointer filler map. The object won't be rooted, but // our heap verification code could stumble across it. bool ElementsAreSafeToExamine(); #endif Object* SlowReverseLookup(Object* value); // Maximal number of elements (numbered 0 .. kMaxElementCount - 1). // Also maximal value of JSArray's length property. static const uint32_t kMaxElementCount = 0xffffffffu; // Constants for heuristics controlling conversion of fast elements // to slow elements. // Maximal gap that can be introduced by adding an element beyond // the current elements length. static const uint32_t kMaxGap = 1024; // Maximal length of fast elements array that won't be checked for // being dense enough on expansion. static const int kMaxUncheckedFastElementsLength = 5000; // Same as above but for old arrays. This limit is more strict. We // don't want to be wasteful with long lived objects. static const int kMaxUncheckedOldFastElementsLength = 500; // Note that Page::kMaxRegularHeapObjectSize puts a limit on // permissible values (see the DCHECK in heap.cc). static const int kInitialMaxFastElementArray = 100000; // This constant applies only to the initial map of "$Object" aka // "global.Object" and not to arbitrary other JSObject maps. static const int kInitialGlobalObjectUnusedPropertiesCount = 4; static const int kMaxInstanceSize = 255 * kPointerSize; // When extending the backing storage for property values, we increase // its size by more than the 1 entry necessary, so sequentially adding fields // to the same object requires fewer allocations and copies. static const int kFieldsAdded = 3; // Layout description. static const int kPropertiesOffset = HeapObject::kHeaderSize; static const int kElementsOffset = kPropertiesOffset + kPointerSize; static const int kHeaderSize = kElementsOffset + kPointerSize; STATIC_ASSERT(kHeaderSize == Internals::kJSObjectHeaderSize); class BodyDescriptor : public FlexibleBodyDescriptor { public: static inline int SizeOf(Map* map, HeapObject* object); }; Context* GetCreationContext(); // Enqueue change record for Object.observe. May cause GC. static void EnqueueChangeRecord(Handle object, const char* type, Handle name, Handle old_value); static void MigrateToNewProperty(Handle object, Handle transition, Handle value); private: friend class DictionaryElementsAccessor; friend class JSReceiver; friend class Object; static void MigrateFastToFast(Handle object, Handle new_map); static void MigrateFastToSlow(Handle object, Handle new_map, int expected_additional_properties); static void GeneralizeFieldRepresentation(Handle object, int modify_index, Representation new_representation, Handle new_field_type); static void UpdateAllocationSite(Handle object, ElementsKind to_kind); // Used from Object::GetProperty(). MUST_USE_RESULT static MaybeHandle GetPropertyWithFailedAccessCheck( LookupIterator* it); MUST_USE_RESULT static MaybeHandle GetElementWithCallback( Handle object, Handle receiver, Handle