summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/map.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects/map.h')
-rw-r--r--deps/v8/src/objects/map.h250
1 files changed, 115 insertions, 135 deletions
diff --git a/deps/v8/src/objects/map.h b/deps/v8/src/objects/map.h
index 5806a24ae0..d9a0a73158 100644
--- a/deps/v8/src/objects/map.h
+++ b/deps/v8/src/objects/map.h
@@ -6,6 +6,7 @@
#define V8_OBJECTS_MAP_H_
#include "src/objects.h"
+#include "src/objects/code.h"
#include "src/globals.h"
@@ -22,6 +23,7 @@ namespace internal {
V(BytecodeArray) \
V(Cell) \
V(Code) \
+ V(CodeDataContainer) \
V(ConsString) \
V(DataObject) \
V(FeedbackVector) \
@@ -84,23 +86,28 @@ typedef std::vector<Handle<Map>> MapHandles;
// +---------------+---------------------------------------------+
// | TaggedPointer | map - Always a pointer to the MetaMap root |
// +---------------+---------------------------------------------+
-// | Int | instance_sizes (the first int field) |
+// | Int | The first int field |
// `---+----------+---------------------------------------------+
// | Byte | [instance_size] |
// +----------+---------------------------------------------+
// | Byte | If Map for a primitive type: |
// | | native context index for constructor fn |
// | | If Map for an Object type: |
-// | | number of in-object properties |
+// | | inobject properties start offset in words |
// +----------+---------------------------------------------+
-// | Byte | unused |
+// | Byte | [used_or_unused_instance_size_in_words] |
+// | | For JSObject in fast mode this byte encodes |
+// | | the size of the object that includes only |
+// | | the used property fields or the slack size |
+// | | in properties backing store. |
// +----------+---------------------------------------------+
// | Byte | [visitor_id] |
// +----+----------+---------------------------------------------+
-// | Int | instance_attributes (second int field) |
+// | Int | The second int field |
// `---+----------+---------------------------------------------+
-// | Word16 | [instance_type] in low byte |
-// | | [bit_field] in high byte |
+// | Short | [instance_type] |
+// +----------+---------------------------------------------+
+// | Byte | [bit_field] |
// | | - has_non_instance_prototype (bit 0) |
// | | - is_callable (bit 1) |
// | | - has_named_interceptor (bit 2) |
@@ -114,11 +121,8 @@ typedef std::vector<Handle<Map>> MapHandles;
// | | - is_extensible (bit 0) |
// | | - is_prototype_map (bit 2) |
// | | - elements_kind (bits 3..7) |
-// +----------+---------------------------------------------+
-// | Byte | [unused_property_fields] number of unused |
-// | | property fields in JSObject (for fast-mode) |
// +----+----------+---------------------------------------------+
-// | Word | [bit_field3] |
+// | Int | [bit_field3] |
// | | - number_of_own_descriptors (bit 0..19) |
// | | - is_dictionary_map (bit 20) |
// | | - owns_descriptors (bit 21) |
@@ -131,9 +135,10 @@ typedef std::vector<Handle<Map>> MapHandles;
// | | - may_have_interesting_symbols (bit 28) |
// | | - construction_counter (bit 29..31) |
// | | |
-// | | On systems with 64bit pointer types, there |
+// +*************************************************************+
+// | Int | On systems with 64bit pointer types, there |
// | | is an unused 32bits after bit_field3 |
-// +---------------+---------------------------------------------+
+// +*************************************************************+
// | TaggedPointer | [prototype] |
// +---------------+---------------------------------------------+
// | TaggedPointer | [constructor_or_backpointer] |
@@ -146,7 +151,9 @@ typedef std::vector<Handle<Map>> MapHandles;
// | TaggedPointer | [instance_descriptors] |
// +*************************************************************+
// ! TaggedPointer ! [layout_descriptors] !
-// ! ! Field is only present on 64 bit arch !
+// ! ! Field is only present if compile-time flag !
+// ! ! FLAG_unbox_double_fields is enabled !
+// ! ! (basically on 64 bit architectures) !
// +*************************************************************+
// | TaggedPointer | [dependent_code] |
// +---------------+---------------------------------------------+
@@ -158,20 +165,21 @@ class Map : public HeapObject {
// Instance size.
// Size in bytes or kVariableSizeSentinel if instances do not have
// a fixed size.
- inline int instance_size() const;
- inline void set_instance_size(int value);
+ DECL_INT_ACCESSORS(instance_size)
+ // Size in words or kVariableSizeSentinel if instances do not have
+ // a fixed size.
+ DECL_INT_ACCESSORS(instance_size_in_words)
- // Only to clear an unused byte, remove once byte is used.
- inline void clear_unused();
+ // [inobject_properties_start_or_constructor_function_index]:
+ // Provides access to the inobject properties start offset in words in case of
+ // JSObject maps, or the constructor function index in case of primitive maps.
+ DECL_INT_ACCESSORS(inobject_properties_start_or_constructor_function_index)
- // [inobject_properties_or_constructor_function_index]: Provides access
- // to the inobject properties in case of JSObject maps, or the constructor
- // function index in case of primitive maps.
- inline int inobject_properties_or_constructor_function_index() const;
- inline void set_inobject_properties_or_constructor_function_index(int value);
+ // Get/set the in-object property area start offset in words in the object.
+ inline int GetInObjectPropertiesStartInWords() const;
+ inline void SetInObjectPropertiesStartInWords(int value);
// Count of properties allocated in the object (JSObject only).
inline int GetInObjectProperties() const;
- inline void SetInObjectProperties(int value);
// Index of the constructor function in the native context (primitives only),
// or the special sentinel value to indicate that there is no object wrapper
// for the primitive (i.e. in case of null or undefined).
@@ -189,10 +197,22 @@ class Map : public HeapObject {
inline InstanceType instance_type() const;
inline void set_instance_type(InstanceType value);
- // Tells how many unused property fields are available in the
- // instance (only used for JSObject in fast mode).
- inline int unused_property_fields() const;
- inline void set_unused_property_fields(int value);
+ // Returns the size of the used in-object area including object header
+ // (only used for JSObject in fast mode, for the other kinds of objects it
+ // is equal to the instance size).
+ inline int UsedInstanceSize() const;
+
+ // Tells how many unused property fields (in-object or out-of object) are
+ // available in the instance (only used for JSObject in fast mode).
+ inline int UnusedPropertyFields() const;
+ // Updates the counters tracking unused fields in the object.
+ inline void SetInObjectUnusedPropertyFields(int unused_property_fields);
+ // Updates the counters tracking unused fields in the property array.
+ inline void SetOutOfObjectUnusedPropertyFields(int unused_property_fields);
+ inline void CopyUnusedPropertyFields(Map* map);
+ inline void AccountAddedPropertyField();
+ inline void AccountAddedOutOfObjectPropertyField(
+ int unused_in_property_array);
// Bit field.
inline byte bit_field() const;
@@ -222,6 +242,8 @@ class Map : public HeapObject {
class NewTargetIsBase : public BitField<bool, 27, 1> {};
class MayHaveInterestingSymbols : public BitField<bool, 28, 1> {};
+ STATIC_ASSERT(NumberOfOwnDescriptorsBits::kMax >= kMaxNumberOfDescriptors);
+
// Keep this bit field at the very end for better code in
// Builtins::kJSConstructStubGeneric stub.
// This counter is used for in-object slack tracking.
@@ -293,19 +315,18 @@ class Map : public HeapObject {
// Tells whether the instance has a [[Construct]] internal method.
// This property is implemented according to ES6, section 7.2.4.
- inline void set_is_constructor(bool value);
- inline bool is_constructor() const;
+ DECL_BOOLEAN_ACCESSORS(is_constructor)
// Tells whether the instance with this map may have properties for
// interesting symbols on it.
// An "interesting symbol" is one for which Name::IsInterestingSymbol()
// returns true, i.e. a well-known symbol like @@toStringTag.
- inline void set_may_have_interesting_symbols(bool value);
- inline bool may_have_interesting_symbols() const;
+ DECL_BOOLEAN_ACCESSORS(may_have_interesting_symbols)
+
+ DECL_BOOLEAN_ACCESSORS(has_prototype_slot)
// Tells whether the instance with this map has a hidden prototype.
- inline void set_has_hidden_prototype(bool value);
- inline bool has_hidden_prototype() const;
+ DECL_BOOLEAN_ACCESSORS(has_hidden_prototype)
// Records and queries whether the instance has a named interceptor.
inline void set_has_named_interceptor();
@@ -329,12 +350,9 @@ class Map : public HeapObject {
inline void set_is_callable();
inline bool is_callable() const;
- inline void set_new_target_is_base(bool value);
- inline bool new_target_is_base() const;
- inline void set_is_extensible(bool value);
- inline bool is_extensible() const;
- inline void set_is_prototype_map(bool value);
- inline bool is_prototype_map() const;
+ DECL_BOOLEAN_ACCESSORS(new_target_is_base)
+ DECL_BOOLEAN_ACCESSORS(is_extensible)
+ DECL_BOOLEAN_ACCESSORS(is_prototype_map)
inline bool is_abandoned_prototype_map() const;
inline void set_elements_kind(ElementsKind elements_kind);
@@ -482,7 +500,8 @@ class Map : public HeapObject {
// [prototype]: implicit prototype object.
DECL_ACCESSORS(prototype, Object)
// TODO(jkummerow): make set_prototype private.
- static void SetPrototype(Handle<Map> map, Handle<Object> prototype);
+ static void SetPrototype(Handle<Map> map, Handle<Object> prototype,
+ bool enable_prototype_setup_mode = true);
// [constructor]: points back to the function or FunctionTemplateInfo
// responsible for this map.
@@ -543,16 +562,14 @@ class Map : public HeapObject {
inline int EnumLength() const;
inline void SetEnumLength(int length);
- inline bool owns_descriptors() const;
- inline void set_owns_descriptors(bool owns_descriptors);
+ DECL_BOOLEAN_ACCESSORS(owns_descriptors)
inline void mark_unstable();
inline bool is_stable() const;
inline void set_migration_target(bool value);
inline bool is_migration_target() const;
inline void set_immutable_proto(bool value);
inline bool is_immutable_proto() const;
- inline void set_construction_counter(int value);
- inline int construction_counter() const;
+ DECL_INT_ACCESSORS(construction_counter)
inline void deprecate();
inline bool is_deprecated() const;
inline bool CanBeDeprecated() const;
@@ -649,17 +666,18 @@ class Map : public HeapObject {
DECL_CAST(Map)
- // Extend the descriptor array of the map with the list of descriptors.
- // In case of duplicates, the latest descriptor is used.
- static void AppendCallbackDescriptors(Handle<Map> map,
- Handle<Object> descriptors);
-
static inline int SlackForArraySize(int old_size, int size_limit);
static void EnsureDescriptorSlack(Handle<Map> map, int slack);
+ // Returns the map to be used for instances when the given {prototype} is
+ // passed to an Object.create call. Might transition the given {prototype}.
static Handle<Map> GetObjectCreateMap(Handle<HeapObject> prototype);
+ // Similar to {GetObjectCreateMap} but does not transition {prototype} and
+ // fails gracefully by returning an empty handle instead.
+ static MaybeHandle<Map> TryGetObjectCreateMap(Handle<HeapObject> prototype);
+
// Computes a hash value for this map, to be used in HashTables and such.
int Hash();
@@ -702,8 +720,7 @@ class Map : public HeapObject {
void DictionaryMapVerify();
#endif
- inline int visitor_id() const;
- inline void set_visitor_id(int visitor_id);
+ DECL_PRIMITIVE_ACCESSORS(visitor_id, VisitorId)
static Handle<Map> TransitionToPrototype(Handle<Map> map,
Handle<Object> prototype);
@@ -713,65 +730,34 @@ class Map : public HeapObject {
static const int kMaxPreAllocatedPropertyFields = 255;
// Layout description.
- static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
- static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
- static const int kBitField3Offset = kInstanceAttributesOffset + kIntSize;
- static const int kPrototypeOffset = kBitField3Offset + kPointerSize;
- static const int kConstructorOrBackPointerOffset =
- kPrototypeOffset + kPointerSize;
- // When there is only one transition, it is stored directly in this field;
- // otherwise a transition array is used.
- // For prototype maps, this slot is used to store this map's PrototypeInfo
- // struct.
- static const int kTransitionsOrPrototypeInfoOffset =
- kConstructorOrBackPointerOffset + kPointerSize;
- static const int kDescriptorsOffset =
- kTransitionsOrPrototypeInfoOffset + kPointerSize;
-#if V8_DOUBLE_FIELDS_UNBOXING
- static const int kLayoutDescriptorOffset = kDescriptorsOffset + kPointerSize;
- static const int kDependentCodeOffset =
- kLayoutDescriptorOffset + kPointerSize;
-#else
- static const int kLayoutDescriptorOffset = 1; // Must not be ever accessed.
- static const int kDependentCodeOffset = kDescriptorsOffset + kPointerSize;
-#endif
- static const int kWeakCellCacheOffset = kDependentCodeOffset + kPointerSize;
- static const int kSize = kWeakCellCacheOffset + kPointerSize;
-
- // Layout of pointer fields. Heap iteration code relies on them
- // being continuously allocated.
- static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
- static const int kPointerFieldsEndOffset = kSize;
-
- // Byte offsets within kInstanceSizesOffset.
- static const int kInstanceSizeOffset = kInstanceSizesOffset + 0;
- static const int kInObjectPropertiesOrConstructorFunctionIndexByte = 1;
- static const int kInObjectPropertiesOrConstructorFunctionIndexOffset =
- kInstanceSizesOffset + kInObjectPropertiesOrConstructorFunctionIndexByte;
- // Note there is one byte available for use here.
- static const int kUnusedByte = 2;
- static const int kUnusedOffset = kInstanceSizesOffset + kUnusedByte;
- static const int kVisitorIdByte = 3;
- static const int kVisitorIdOffset = kInstanceSizesOffset + kVisitorIdByte;
-
-// Byte offsets within kInstanceAttributesOffset attributes.
-#if V8_TARGET_LITTLE_ENDIAN
- // Order instance type and bit field together such that they can be loaded
- // together as a 16-bit word with instance type in the lower 8 bits regardless
- // of endianess. Also provide endian-independent offset to that 16-bit word.
- static const int kInstanceTypeOffset = kInstanceAttributesOffset + 0;
- static const int kBitFieldOffset = kInstanceAttributesOffset + 1;
-#else
- static const int kBitFieldOffset = kInstanceAttributesOffset + 0;
- static const int kInstanceTypeOffset = kInstanceAttributesOffset + 1;
-#endif
- static const int kInstanceTypeAndBitFieldOffset =
- kInstanceAttributesOffset + 0;
- static const int kBitField2Offset = kInstanceAttributesOffset + 2;
- static const int kUnusedPropertyFieldsOffset = kInstanceAttributesOffset + 3;
-
- STATIC_ASSERT(kInstanceTypeAndBitFieldOffset ==
- Internals::kMapInstanceTypeAndBitFieldOffset);
+#define MAP_FIELDS(V) \
+ /* Raw data fields. */ \
+ V(kInstanceSizeInWordsOffset, kUInt8Size) \
+ V(kInObjectPropertiesStartOrConstructorFunctionIndexOffset, kUInt8Size) \
+ V(kUsedOrUnusedInstanceSizeInWordsOffset, kUInt8Size) \
+ V(kVisitorIdOffset, kUInt8Size) \
+ V(kInstanceTypeOffset, kUInt16Size) \
+ V(kBitFieldOffset, kUInt8Size) \
+ V(kBitField2Offset, kUInt8Size) \
+ V(kBitField3Offset, kUInt32Size) \
+ V(k64BitArchPaddingOffset, kPointerSize == kUInt32Size ? 0 : kUInt32Size) \
+ /* Pointer fields. */ \
+ V(kPointerFieldsBeginOffset, 0) \
+ V(kPrototypeOffset, kPointerSize) \
+ V(kConstructorOrBackPointerOffset, kPointerSize) \
+ V(kTransitionsOrPrototypeInfoOffset, kPointerSize) \
+ V(kDescriptorsOffset, kPointerSize) \
+ V(kLayoutDescriptorOffset, FLAG_unbox_double_fields ? kPointerSize : 0) \
+ V(kDependentCodeOffset, kPointerSize) \
+ V(kWeakCellCacheOffset, kPointerSize) \
+ V(kPointerFieldsEndOffset, 0) \
+ /* Total size. */ \
+ V(kSize, 0)
+
+ DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS)
+#undef MAP_FIELDS
+
+ STATIC_ASSERT(kInstanceTypeOffset == Internals::kMapInstanceTypeOffset);
// Bit positions for bit field.
static const int kHasNonInstancePrototype = 0;
@@ -781,7 +767,7 @@ class Map : public HeapObject {
static const int kIsUndetectable = 4;
static const int kIsAccessCheckNeeded = 5;
static const int kIsConstructor = 6;
- // Bit 7 is free.
+ static const int kHasPrototypeSlot = 7;
// Bit positions for bit field 2
static const int kIsExtensible = 0;
@@ -789,24 +775,6 @@ class Map : public HeapObject {
class IsPrototypeMapBits : public BitField<bool, 2, 1> {};
class ElementsKindBits : public BitField<ElementsKind, 3, 5> {};
- // Derived values from bit field 2
- static const int8_t kMaximumBitField2FastElementValue =
- static_cast<int8_t>((PACKED_ELEMENTS + 1)
- << Map::ElementsKindBits::kShift) -
- 1;
- static const int8_t kMaximumBitField2FastSmiElementValue =
- static_cast<int8_t>((PACKED_SMI_ELEMENTS + 1)
- << Map::ElementsKindBits::kShift) -
- 1;
- static const int8_t kMaximumBitField2FastHoleyElementValue =
- static_cast<int8_t>((HOLEY_ELEMENTS + 1)
- << Map::ElementsKindBits::kShift) -
- 1;
- static const int8_t kMaximumBitField2FastHoleySmiElementValue =
- static_cast<int8_t>((HOLEY_SMI_ELEMENTS + 1)
- << Map::ElementsKindBits::kShift) -
- 1;
-
typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
kPointerFieldsEndOffset, kSize>
BodyDescriptor;
@@ -821,10 +789,7 @@ class Map : public HeapObject {
// Returns true if given field is unboxed double.
inline bool IsUnboxedDoubleField(FieldIndex index) const;
-#if V8_TRACE_MAPS
- static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
- static void TraceAllTransitions(Map* map);
-#endif
+ void PrintMapDetails(std::ostream& os, JSObject* holder = nullptr);
static inline Handle<Map> AddMissingTransitionsForTesting(
Handle<Map> split_map, Handle<DescriptorArray> descriptors,
@@ -848,6 +813,19 @@ class Map : public HeapObject {
inline bool CanHaveFastTransitionableElementsKind() const;
private:
+ // This byte encodes either the instance size without the in-object slack or
+ // the slack size in properties backing store.
+ // Let H be JSObject::kHeaderSize / kPointerSize.
+ // If value >= H then:
+ // - all field properties are stored in the object.
+ // - there is no property array.
+ // - value * kPointerSize is the actual object size without the slack.
+ // Otherwise:
+ // - there is no slack in the object.
+ // - the property array has value slack slots.
+ // Note that this encoding requires that H = JSObject::kFieldsAdded.
+ DECL_INT_ACCESSORS(used_or_unused_instance_size_in_words)
+
// Returns the map that this (root) map transitions to if its elements_kind
// is changed to |elements_kind|, or |nullptr| if no such map is cached yet.
Map* LookupElementsTransitionMap(ElementsKind elements_kind);
@@ -864,7 +842,8 @@ class Map : public HeapObject {
bool EquivalentToForTransition(const Map* other) const;
bool EquivalentToForElementsKindTransition(const Map* other) const;
- static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
+ static Handle<Map> RawCopy(Handle<Map> map, int instance_size,
+ int inobject_properties);
static Handle<Map> ShareDescriptor(Handle<Map> map,
Handle<DescriptorArray> descriptors,
Descriptor* descriptor);
@@ -941,7 +920,8 @@ class NormalizedMapCache : public FixedArray {
MUST_USE_RESULT MaybeHandle<Map> Get(Handle<Map> fast_map,
PropertyNormalizationMode mode);
- void Set(Handle<Map> fast_map, Handle<Map> normalized_map);
+ void Set(Handle<Map> fast_map, Handle<Map> normalized_map,
+ Handle<WeakCell> normalized_map_weak_cell);
void Clear();