summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects/descriptor-array.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects/descriptor-array.h')
-rw-r--r--deps/v8/src/objects/descriptor-array.h192
1 files changed, 129 insertions, 63 deletions
diff --git a/deps/v8/src/objects/descriptor-array.h b/deps/v8/src/objects/descriptor-array.h
index c24deb68ad..3e67e94bf1 100644
--- a/deps/v8/src/objects/descriptor-array.h
+++ b/deps/v8/src/objects/descriptor-array.h
@@ -7,6 +7,8 @@
#include "src/objects.h"
#include "src/objects/fixed-array.h"
+#include "src/objects/struct.h"
+#include "src/utils.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -31,62 +33,57 @@ class EnumCache : public Tuple2 {
static const int kKeysOffset = kValue1Offset;
static const int kIndicesOffset = kValue2Offset;
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(EnumCache);
+ OBJECT_CONSTRUCTORS(EnumCache, Tuple2);
};
-// A DescriptorArray is a fixed array used to hold instance descriptors.
-// The format of these objects is:
-// [0]: Number of descriptors
-// [1]: Enum cache.
-// [2]: first key (and internalized String)
-// [3]: first descriptor details (see PropertyDetails)
-// [4]: first value for constants | Smi(1) when not used
-//
-// [2 + number of descriptors * 3]: start of slack
+// A DescriptorArray is a custom array that holds instance descriptors.
+// It has the following layout:
+// Header:
+// [16:0 bits]: number_of_all_descriptors (including slack)
+// [32:16 bits]: number_of_descriptors
+// [48:32 bits]: raw_number_of_marked_descriptors (used by GC)
+// [64:48 bits]: alignment filler
+// [kEnumCacheOffset]: enum cache
+// Elements:
+// [kHeaderSize + 0]: first key (and internalized String)
+// [kHeaderSize + 1]: first descriptor details (see PropertyDetails)
+// [kHeaderSize + 2]: first value for constants / Smi(1) when not used
+// Slack:
+// [kHeaderSize + number of descriptors * 3]: start of slack
// The "value" fields store either values or field types. A field type is either
// FieldType::None(), FieldType::Any() or a weak reference to a Map. All other
// references are strong.
-class DescriptorArray : public WeakFixedArray {
+class DescriptorArray : public HeapObject {
public:
- // Returns the number of descriptors in the array.
- inline int number_of_descriptors() const;
- inline int number_of_descriptors_storage() const;
- inline int NumberOfSlackDescriptors() const;
-
- inline void SetNumberOfDescriptors(int number_of_descriptors);
+ DECL_INT16_ACCESSORS(number_of_all_descriptors)
+ DECL_INT16_ACCESSORS(number_of_descriptors)
+ inline int16_t number_of_slack_descriptors() const;
inline int number_of_entries() const;
-
- inline EnumCache* GetEnumCache();
+ DECL_ACCESSORS(enum_cache, EnumCache)
void ClearEnumCache();
- inline void CopyEnumCacheFrom(DescriptorArray* array);
- // Initialize or change the enum cache,
- static void SetEnumCache(Handle<DescriptorArray> descriptors,
- Isolate* isolate, Handle<FixedArray> keys,
- Handle<FixedArray> indices);
+ inline void CopyEnumCacheFrom(DescriptorArray array);
+ static void InitializeOrChangeEnumCache(Handle<DescriptorArray> descriptors,
+ Isolate* isolate,
+ Handle<FixedArray> keys,
+ Handle<FixedArray> indices);
// Accessors for fetching instance descriptor at descriptor number.
- inline Name* GetKey(int descriptor_number);
- inline Object** GetKeySlot(int descriptor_number);
- inline Object* GetStrongValue(int descriptor_number);
- inline void SetValue(int descriptor_number, Object* value);
- inline MaybeObject* GetValue(int descriptor_number);
- inline MaybeObject** GetValueSlot(int descriptor_number);
- static inline int GetValueOffset(int descriptor_number);
- inline MaybeObject** GetDescriptorStartSlot(int descriptor_number);
- inline MaybeObject** GetDescriptorEndSlot(int descriptor_number);
+ inline Name GetKey(int descriptor_number) const;
+ inline Object GetStrongValue(int descriptor_number);
+ inline void SetValue(int descriptor_number, Object value);
+ inline MaybeObject GetValue(int descriptor_number);
inline PropertyDetails GetDetails(int descriptor_number);
inline int GetFieldIndex(int descriptor_number);
- inline FieldType* GetFieldType(int descriptor_number);
+ inline FieldType GetFieldType(int descriptor_number);
- inline Name* GetSortedKey(int descriptor_number);
+ inline Name GetSortedKey(int descriptor_number);
inline int GetSortedKeyIndex(int descriptor_number);
inline void SetSortedKey(int pointer, int descriptor_number);
// Accessor for complete descriptor.
inline void Set(int descriptor_number, Descriptor* desc);
- inline void Set(int descriptor_number, Name* key, MaybeObject* value,
+ inline void Set(int descriptor_number, Name key, MaybeObject value,
PropertyDetails details);
void Replace(int descriptor_number, Descriptor* descriptor);
@@ -115,34 +112,66 @@ class DescriptorArray : public WeakFixedArray {
void Sort();
// Search the instance descriptors for given name.
- V8_INLINE int Search(Name* name, int number_of_own_descriptors);
- V8_INLINE int Search(Name* name, Map* map);
+ V8_INLINE int Search(Name name, int number_of_own_descriptors);
+ V8_INLINE int Search(Name name, Map map);
// As the above, but uses DescriptorLookupCache and updates it when
// necessary.
- V8_INLINE int SearchWithCache(Isolate* isolate, Name* name, Map* map);
+ V8_INLINE int SearchWithCache(Isolate* isolate, Name name, Map map);
- bool IsEqualUpTo(DescriptorArray* desc, int nof_descriptors);
+ bool IsEqualUpTo(DescriptorArray desc, int nof_descriptors);
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
static Handle<DescriptorArray> Allocate(
- Isolate* isolate, int number_of_descriptors, int slack,
+ Isolate* isolate, int nof_descriptors, int slack,
PretenureFlag pretenure = NOT_TENURED);
+ void Initialize(EnumCache enum_cache, HeapObject undefined_value,
+ int nof_descriptors, int slack);
+
DECL_CAST(DescriptorArray)
// Constant for denoting key was not found.
static const int kNotFound = -1;
- static const int kDescriptorLengthIndex = 0;
- static const int kEnumCacheIndex = 1;
- static const int kFirstIndex = 2;
-
// Layout description.
- static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
- static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
- static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
+#define DESCRIPTOR_ARRAY_FIELDS(V) \
+ V(kNumberOfAllDescriptorsOffset, kUInt16Size) \
+ V(kNumberOfDescriptorsOffset, kUInt16Size) \
+ V(kRawNumberOfMarkedDescriptorsOffset, kUInt16Size) \
+ V(kFiller16BitsOffset, kUInt16Size) \
+ V(kPointersStartOffset, 0) \
+ V(kEnumCacheOffset, kTaggedSize) \
+ V(kHeaderSize, 0)
+
+ DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
+ DESCRIPTOR_ARRAY_FIELDS)
+#undef DESCRIPTOR_ARRAY_FIELDS
+
+ STATIC_ASSERT(IsAligned(kPointersStartOffset, kTaggedSize));
+ STATIC_ASSERT(IsAligned(kHeaderSize, kTaggedSize));
+
+ // Garbage collection support.
+ DECL_INT16_ACCESSORS(raw_number_of_marked_descriptors)
+ // Atomic compare-and-swap operation on the raw_number_of_marked_descriptors.
+ int16_t CompareAndSwapRawNumberOfMarkedDescriptors(int16_t expected,
+ int16_t value);
+ int16_t UpdateNumberOfMarkedDescriptors(unsigned mark_compact_epoch,
+ int16_t number_of_marked_descriptors);
+
+ static constexpr int SizeFor(int number_of_all_descriptors) {
+ return offset(number_of_all_descriptors * kEntrySize);
+ }
+ static constexpr int OffsetOfDescriptorAt(int descriptor) {
+ return offset(descriptor * kEntrySize);
+ }
+ inline ObjectSlot GetFirstPointerSlot();
+ inline ObjectSlot GetDescriptorSlot(int descriptor);
+ inline ObjectSlot GetKeySlot(int descriptor);
+ inline MaybeObjectSlot GetValueSlot(int descriptor);
+
+ typedef FlexibleWeakBodyDescriptor<kPointersStartOffset> BodyDescriptor;
// Layout of descriptor.
// Naming is consistent with Dictionary classes for easy templating.
@@ -164,40 +193,77 @@ class DescriptorArray : public WeakFixedArray {
bool IsSortedNoDuplicates(int valid_descriptors = -1);
// Are two DescriptorArrays equal?
- bool IsEqualTo(DescriptorArray* other);
+ bool IsEqualTo(DescriptorArray other);
#endif
- // Returns the fixed array length required to hold number_of_descriptors
- // descriptors.
- static constexpr int LengthFor(int number_of_descriptors) {
- return ToKeyIndex(number_of_descriptors);
- }
-
static constexpr int ToDetailsIndex(int descriptor_number) {
- return kFirstIndex + (descriptor_number * kEntrySize) + kEntryDetailsIndex;
+ return (descriptor_number * kEntrySize) + kEntryDetailsIndex;
}
// Conversion from descriptor number to array indices.
static constexpr int ToKeyIndex(int descriptor_number) {
- return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
+ return (descriptor_number * kEntrySize) + kEntryKeyIndex;
}
static constexpr int ToValueIndex(int descriptor_number) {
- return kFirstIndex + (descriptor_number * kEntrySize) + kEntryValueIndex;
+ return (descriptor_number * kEntrySize) + kEntryValueIndex;
}
private:
- inline MaybeObject* get(int index) const;
- inline void set(int index, MaybeObject* value);
+ DECL_INT16_ACCESSORS(filler16bits)
+ // Low-level per-element accessors.
+ static constexpr int offset(int index) {
+ return kHeaderSize + index * kTaggedSize;
+ }
+ inline int length() const;
+ inline MaybeObject get(int index) const;
+ inline void set(int index, MaybeObject value);
// Transfer a complete descriptor from the src descriptor array to this
// descriptor array.
- void CopyFrom(int index, DescriptorArray* src);
+ void CopyFrom(int index, DescriptorArray src);
// Swap first and second descriptor.
inline void SwapSortedKeys(int first, int second);
- DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
+ OBJECT_CONSTRUCTORS(DescriptorArray, HeapObject);
+};
+
+class NumberOfMarkedDescriptors {
+ public:
+// Bit positions for |bit_field|.
+#define BIT_FIELD_FIELDS(V, _) \
+ V(Epoch, unsigned, 2, _) \
+ V(Marked, int16_t, 14, _)
+ DEFINE_BIT_FIELDS(BIT_FIELD_FIELDS)
+#undef BIT_FIELD_FIELDS
+ static const int kMaxNumberOfMarkedDescriptors = Marked::kMax;
+ // Decodes the raw value of the number of marked descriptors for the
+ // given mark compact garbage collection epoch.
+ static inline int16_t decode(unsigned mark_compact_epoch, int16_t raw_value) {
+ unsigned epoch_from_value = Epoch::decode(static_cast<uint16_t>(raw_value));
+ int16_t marked_from_value =
+ Marked::decode(static_cast<uint16_t>(raw_value));
+ unsigned actual_epoch = mark_compact_epoch & Epoch::kMask;
+ if (actual_epoch == epoch_from_value) return marked_from_value;
+ // If the epochs do not match, then either the raw_value is zero (freshly
+ // allocated descriptor array) or the epoch from value lags by 1.
+ DCHECK_IMPLIES(raw_value != 0,
+ Epoch::decode(epoch_from_value + 1) == actual_epoch);
+ // Not matching epochs means that the no descriptors were marked in the
+ // current epoch.
+ return 0;
+ }
+
+ // Encodes the number of marked descriptors for the given mark compact
+ // garbage collection epoch.
+ static inline int16_t encode(unsigned mark_compact_epoch, int16_t value) {
+ // TODO(ulan): avoid casting to int16_t by adding support for uint16_t
+ // atomics.
+ return static_cast<int16_t>(
+ Epoch::encode(mark_compact_epoch & Epoch::kMask) |
+ Marked::encode(value));
+ }
};
} // namespace internal