descriptor-array.h 7.31 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_H_
#define V8_OBJECTS_DESCRIPTOR_ARRAY_H_

#include "src/objects.h"
9
#include "src/objects/fixed-array.h"
10 11 12 13 14 15 16 17 18 19 20 21

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

template <typename T>
class Handle;

class Isolate;

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
// An EnumCache is a pair used to hold keys and indices caches.
class EnumCache : public Tuple2 {
 public:
  DECL_ACCESSORS(keys, FixedArray)
  DECL_ACCESSORS(indices, FixedArray)

  DECL_CAST(EnumCache)

  // Layout description.
  static const int kKeysOffset = kValue1Offset;
  static const int kIndicesOffset = kValue2Offset;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(EnumCache);
};

38
// A DescriptorArray is a fixed array used to hold instance descriptors.
39
// The format of these objects is:
40
//   [0]: Number of descriptors
41
//   [1]: Enum cache.
42 43
//   [2]: first key (and internalized String)
//   [3]: first descriptor details (see PropertyDetails)
44
//   [4]: first value for constants | Smi(1) when not used
45 46
//
//   [2 + number of descriptors * 3]: start of slack
47 48 49 50
// 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 {
51 52
 public:
  // Returns the number of descriptors in the array.
53 54 55
  inline int number_of_descriptors() const;
  inline int number_of_descriptors_storage() const;
  inline int NumberOfSlackDescriptors() const;
56 57

  inline void SetNumberOfDescriptors(int number_of_descriptors);
58
  inline int number_of_entries() const;
59

60
  inline EnumCache* GetEnumCache();
61 62

  void ClearEnumCache();
63
  inline void CopyEnumCacheFrom(DescriptorArray* array);
64 65
  // Initialize or change the enum cache,
  static void SetEnumCache(Handle<DescriptorArray> descriptors,
66 67
                           Isolate* isolate, Handle<FixedArray> keys,
                           Handle<FixedArray> indices);
68 69 70 71

  // Accessors for fetching instance descriptor at descriptor number.
  inline Name* GetKey(int descriptor_number);
  inline Object** GetKeySlot(int descriptor_number);
72
  inline Object* GetStrongValue(int descriptor_number);
73
  inline void SetValue(int descriptor_number, Object* value);
74 75
  inline MaybeObject* GetValue(int descriptor_number);
  inline MaybeObject** GetValueSlot(int descriptor_number);
76
  static inline int GetValueOffset(int descriptor_number);
77 78
  inline MaybeObject** GetDescriptorStartSlot(int descriptor_number);
  inline MaybeObject** GetDescriptorEndSlot(int descriptor_number);
79 80 81 82 83 84 85 86 87 88
  inline PropertyDetails GetDetails(int descriptor_number);
  inline int GetFieldIndex(int descriptor_number);
  inline FieldType* GetFieldType(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);
89
  inline void Set(int descriptor_number, Name* key, MaybeObject* value,
90 91 92 93 94 95 96 97 98 99 100 101
                  PropertyDetails details);
  void Replace(int descriptor_number, Descriptor* descriptor);

  // Generalizes constness, representation and field type of all field
  // descriptors.
  void GeneralizeAllFields();

  // Append automatically sets the enumeration index. This should only be used
  // to add descriptors in bulk at the end, followed by sorting the descriptor
  // array.
  inline void Append(Descriptor* desc);

102 103
  static Handle<DescriptorArray> CopyUpTo(Isolate* isolate,
                                          Handle<DescriptorArray> desc,
104 105 106
                                          int enumeration_index, int slack = 0);

  static Handle<DescriptorArray> CopyUpToAddAttributes(
107
      Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
108 109
      PropertyAttributes attributes, int slack = 0);

110 111 112 113
  static Handle<DescriptorArray> CopyForFastObjectClone(
      Isolate* isolate, Handle<DescriptorArray> desc, int enumeration_index,
      int slack = 0);

114 115 116 117
  // Sort the instance descriptors by the hash codes of their keys.
  void Sort();

  // Search the instance descriptors for given name.
118 119
  V8_INLINE int Search(Name* name, int number_of_own_descriptors);
  V8_INLINE int Search(Name* name, Map* map);
120 121 122

  // As the above, but uses DescriptorLookupCache and updates it when
  // necessary.
123
  V8_INLINE int SearchWithCache(Isolate* isolate, Name* name, Map* map);
124 125 126 127 128 129 130 131 132

  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,
      PretenureFlag pretenure = NOT_TENURED);

133
  DECL_CAST(DescriptorArray)
134 135 136 137 138

  // Constant for denoting key was not found.
  static const int kNotFound = -1;

  static const int kDescriptorLengthIndex = 0;
139
  static const int kEnumCacheIndex = 1;
140 141 142 143
  static const int kFirstIndex = 2;

  // Layout description.
  static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
144 145
  static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
  static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
146 147 148 149 150 151 152 153 154

  // Layout of descriptor.
  // Naming is consistent with Dictionary classes for easy templating.
  static const int kEntryKeyIndex = 0;
  static const int kEntryDetailsIndex = 1;
  static const int kEntryValueIndex = 2;
  static const int kEntrySize = 3;

  // Print all the descriptors.
155
  void PrintDescriptors(std::ostream& os);
156 157
  void PrintDescriptorDetails(std::ostream& os, int descriptor,
                              PropertyDetails::PrintMode mode);
158

159
  DECL_PRINTER(DescriptorArray)
160 161
  DECL_VERIFIER(DescriptorArray)

162 163
#ifdef DEBUG
  // Is the descriptor array sorted and without duplicates?
164
  bool IsSortedNoDuplicates(int valid_descriptors = -1);
165 166 167 168 169 170 171

  // Are two DescriptorArrays equal?
  bool IsEqualTo(DescriptorArray* other);
#endif

  // Returns the fixed array length required to hold number_of_descriptors
  // descriptors.
172
  static constexpr int LengthFor(int number_of_descriptors) {
173 174 175
    return ToKeyIndex(number_of_descriptors);
  }

176
  static constexpr int ToDetailsIndex(int descriptor_number) {
177 178 179 180
    return kFirstIndex + (descriptor_number * kEntrySize) + kEntryDetailsIndex;
  }

  // Conversion from descriptor number to array indices.
181
  static constexpr int ToKeyIndex(int descriptor_number) {
182 183 184
    return kFirstIndex + (descriptor_number * kEntrySize) + kEntryKeyIndex;
  }

185
  static constexpr int ToValueIndex(int descriptor_number) {
186 187 188 189
    return kFirstIndex + (descriptor_number * kEntrySize) + kEntryValueIndex;
  }

 private:
190 191 192
  inline MaybeObject* get(int index) const;
  inline void set(int index, MaybeObject* value);

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
  // Transfer a complete descriptor from the src descriptor array to this
  // descriptor array.
  void CopyFrom(int index, DescriptorArray* src);

  // Swap first and second descriptor.
  inline void SwapSortedKeys(int first, int second);

  DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_DESCRIPTOR_ARRAY_H_