code); // Casting. static inline HeapObject* cast(Object* obj); // 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(StringStream* accumulator); #ifdef OBJECT_PRINT void PrintHeader(FILE* out, const char* id); #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(); inline void set_value(double value); // Casting. static inline HeapNumber* cast(Object* obj); // Dispatched behavior. bool HeapNumberBooleanValue(); void HeapNumberPrint(FILE* out = stdout); void HeapNumberPrint(StringStream* accumulator); 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 }; // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas // a keyed store is of the form a[expression] = foo. enum StoreFromKeyed { MAY_BE_STORE_FROM_KEYED, CERTAINLY_NOT_STORE_FROM_KEYED }; // Internal properties (e.g. the hidden properties dictionary) might // be added even though the receiver is non-extensible. enum ExtensibilityCheck { PERFORM_EXTENSIBILITY_CHECK, OMIT_EXTENSIBILITY_CHECK }; // Casting. static inline JSReceiver* cast(Object* obj); // Implementation of [[Put]], ECMA-262 5th edition, section 8.12.5. MUST_USE_RESULT static MaybeHandle SetProperty( Handle object, Handle key, Handle value, PropertyAttributes attributes, StrictMode strict_mode, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED); 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. static inline bool HasProperty(Handle object, Handle name); static inline bool HasOwnProperty(Handle, Handle name); static inline bool HasElement(Handle object, uint32_t index); static inline bool 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(); static inline PropertyAttributes GetPropertyAttributes( Handle object, Handle name); static PropertyAttributes GetPropertyAttributes(LookupIterator* it); static PropertyAttributes GetOwnPropertyAttributes( Handle object, Handle name); static inline PropertyAttributes GetElementAttribute( Handle object, uint32_t index); static inline PropertyAttributes GetOwnElementAttribute( Handle object, uint32_t index); // Return the object's prototype (might be Heap::null_value()). inline Object* GetPrototype(); // 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); // Lookup a property. If found, the result is valid and has // detailed information. void LookupOwn(Handle name, LookupResult* result, bool search_hidden_prototypes = false); void Lookup(Handle name, LookupResult* result); 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: MUST_USE_RESULT static MaybeHandle SetProperty( Handle receiver, LookupResult* result, Handle key, Handle value, PropertyAttributes attributes, StrictMode strict_mode, StoreFromKeyed store_from_keyed); 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( Handle object, Handle name, Handle value, PropertyAttributes attributes, StrictMode strict_mode); MUST_USE_RESULT static MaybeHandle SetPropertyForResult( Handle object, LookupResult* result, Handle name, Handle value, PropertyAttributes attributes, StrictMode strict_mode, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED); // 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, ValueType value_type = OPTIMAL_REPRESENTATION, StoreMode mode = ALLOW_AS_CONSTANT, ExtensibilityCheck extensibility_check = PERFORM_EXTENSIBILITY_CHECK, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED, ExecutableAccessorInfoHandling handling = DEFAULT_HANDLING); static inline Handle ExpectedTransitionKey(Handle map); static inline Handle ExpectedTransitionTarget(Handle map); // Try to follow an existing transition to a field with attributes NONE. The // return value indicates whether the transition was successful. static inline Handle FindTransitionToField(Handle map, Handle key); // 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); // Retrieve a value in a normalized object given a lookup result. // Handles the special representation of JS global objects. Object* GetNormalizedProperty(const LookupResult* result); static Handle GetNormalizedProperty(Handle object, const LookupResult* result); // Sets the property value in a normalized object given a lookup result. // Handles the special representation of JS global objects. static void SetNormalizedProperty(Handle object, const LookupResult* result, Handle value); // 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); // Retrieve interceptors. InterceptorInfo* GetNamedInterceptor(); InterceptorInfo* GetIndexedInterceptor(); // Used from JSReceiver. static Maybe GetPropertyAttributesWithInterceptor( Handle holder, Handle receiver, Handle name); static PropertyAttributes GetPropertyAttributesWithFailedAccessCheck( LookupIterator* it); static PropertyAttributes 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() and return empty handle on // exception instead of letting callers check for scheduled exception. static void DefineAccessor(Handle object, Handle name, Handle getter, Handle setter, PropertyAttributes attributes, v8::AccessControl access_control = v8::DEFAULT); // 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 GetOwnPropertyAccessorPair( Handle object, Handle name); 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). static bool HasRealNamedProperty(Handle object, Handle key); static bool HasRealElementProperty(Handle object, uint32_t index); static bool 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); // The following lookup functions skip interceptors. void LookupOwnRealNamedProperty(Handle name, LookupResult* result); void LookupRealNamedProperty(Handle name, LookupResult* result); void LookupRealNamedPropertyInPrototypes(Handle name, LookupResult* result); // 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); // TODO(mstarzinger): Both public because of ConvertAndSetOwnProperty(). static void MigrateToMap(Handle object, Handle new_map); static void GeneralizeFieldRepresentation(Handle object, int modify_index, Representation new_representation, Handle new_field_type, StoreMode store_mode); // 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 TransformToFastProperties(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 skip_hidden_prototypes = false); // 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, kObjectIsShallowArray = 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); // Casting. static inline JSObject* cast(Object* obj); // Dispatched behavior. void JSObjectShortPrint(StringStream* accumulator); DECLARE_PRINTER(JSObject) DECLARE_VERIFIER(JSObject) #ifdef OBJECT_PRINT void PrintProperties(FILE* out = stdout); void PrintElements(FILE* out = stdout); void PrintTransitions(FILE* out = stdout); #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 fast properties for the JSObject. Used to // restrict the number of map transitions to avoid an explosion in // the number of maps for objects used as dictionaries. inline bool TooManyFastProperties( StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED); // 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 ASSERT 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 kFastPropertiesSoftLimit = 12; static const int kMaxFastProperties = 128; 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); private: friend class DictionaryElementsAccessor; friend class JSReceiver; friend class Object; 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 structure, uint32_t index, Handle holder); static PropertyAttributes GetElementAttributeWithInterceptor( Handle object, Handle receiver, uint32_t index, bool continue_search); static PropertyAttributes GetElementAttributeWithoutInterceptor( Handle object, Handle