objects-body-descriptors.h 9.11 KB
Newer Older
1 2 3 4
// Copyright 2015 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.

5 6
#ifndef V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
#define V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
7

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

namespace v8 {
namespace internal {

// This is the base class for object's body descriptors.
//
// Each BodyDescriptor subclass must provide the following methods:
//
// 1) Returns true if the object contains a tagged value at given offset.
//    It is used for invalid slots filtering. If the offset points outside
//    of the object or to the map word, the result is UNDEFINED (!!!).
//
22
//   static bool IsValidSlot(Map map, HeapObject obj, int offset);
23 24 25 26 27
//
//
// 2) Iterate object's body using stateful object visitor.
//
//   template <typename ObjectVisitor>
28
//   static inline void IterateBody(Map map, HeapObject obj, int object_size,
29
//                                  ObjectVisitor* v);
30
class BodyDescriptorBase {
31 32
 public:
  template <typename ObjectVisitor>
33
  static inline void IteratePointers(HeapObject obj, int start_offset,
34 35 36
                                     int end_offset, ObjectVisitor* v);

  template <typename ObjectVisitor>
37
  static inline void IteratePointer(HeapObject obj, int offset,
38 39
                                    ObjectVisitor* v);

40
  template <typename ObjectVisitor>
41 42
  static inline void IterateCustomWeakPointers(HeapObject obj, int start_offset,
                                               int end_offset,
43 44 45
                                               ObjectVisitor* v);

  template <typename ObjectVisitor>
46
  static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
47 48
                                              ObjectVisitor* v);

49 50 51 52
  template <typename ObjectVisitor>
  static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
                                      int value_offset, ObjectVisitor* v);

53
  template <typename ObjectVisitor>
54
  static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
55 56
                                              int end_offset, ObjectVisitor* v);

57
  template <typename ObjectVisitor>
58
  static inline void IterateMaybeWeakPointer(HeapObject obj, int offset,
59 60
                                             ObjectVisitor* v);

61
 protected:
62
  // Returns true for all header and embedder fields.
63
  static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject obj,
64 65 66
                                             int offset);

  // Returns true for all header and embedder fields.
67
  static inline bool IsValidEmbedderJSObjectSlotImpl(Map map, HeapObject obj,
68
                                                     int offset);
69

70
  // Treats all header and embedder fields in the range as tagged.
71
  template <typename ObjectVisitor>
72
  static inline void IterateJSObjectBodyImpl(Map map, HeapObject obj,
73 74
                                             int start_offset, int end_offset,
                                             ObjectVisitor* v);
75 76
};

77 78 79 80 81
// This class describes a body of an object in which all pointer fields are
// located in the [start_offset, end_offset) interval.
// All pointers have to be strong.
template <int start_offset, int end_offset>
class FixedRangeBodyDescriptor : public BodyDescriptorBase {
82 83 84 85
 public:
  static const int kStartOffset = start_offset;
  static const int kEndOffset = end_offset;

86
  static bool IsValidSlot(Map map, HeapObject obj, int offset) {
87 88 89 90
    return offset >= kStartOffset && offset < kEndOffset;
  }

  template <typename ObjectVisitor>
91
  static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
92
    IteratePointers(obj, start_offset, end_offset, v);
93 94 95
  }

  template <typename ObjectVisitor>
96
  static inline void IterateBody(Map map, HeapObject obj, int object_size,
97
                                 ObjectVisitor* v) {
98
    IterateBody(map, obj, v);
99 100
  }

101 102 103 104 105
 private:
  static inline int SizeOf(Map map, HeapObject object) {
    // Has to be implemented by the subclass.
    UNREACHABLE();
  }
106 107
};

108 109
// 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)
110
// interval.
111 112 113 114 115 116 117 118 119 120 121 122
// All pointers have to be strong.
template <int start_offset, int end_offset, int size>
class FixedBodyDescriptor
    : public FixedRangeBodyDescriptor<start_offset, end_offset> {
 public:
  static const int kSize = size;
  static inline int SizeOf(Map map, HeapObject object) { return kSize; }
};

// This class describes a body of an object in which all pointer fields are
// located in the [start_offset, object_size) interval.
// All pointers have to be strong.
123
template <int start_offset>
124
class SuffixRangeBodyDescriptor : public BodyDescriptorBase {
125 126 127
 public:
  static const int kStartOffset = start_offset;

128
  static bool IsValidSlot(Map map, HeapObject obj, int offset) {
129
    return (offset >= kStartOffset);
130 131 132
  }

  template <typename ObjectVisitor>
133
  static inline void IterateBody(Map map, HeapObject obj, int object_size,
134
                                 ObjectVisitor* v) {
135
    IteratePointers(obj, start_offset, object_size, v);
136 137
  }

138 139 140 141 142 143 144 145 146 147 148 149 150 151
 private:
  static inline int SizeOf(Map map, HeapObject object) {
    // Has to be implemented by the subclass.
    UNREACHABLE();
  }
};

// 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.
// All pointers have to be strong.
template <int start_offset>
class FlexibleBodyDescriptor : public SuffixRangeBodyDescriptor<start_offset> {
 public:
152
  static inline int SizeOf(Map map, HeapObject object);
153 154
};

155 156 157 158 159
// A forward-declacable descriptor body alias for most of the Struct successors.
class StructBodyDescriptor
    : public FlexibleBodyDescriptor<HeapObject::kHeaderSize> {
 public:
};
160

161 162 163
// This class describes a body of an object in which all pointer fields are
// located in the [start_offset, object_size) interval.
// Pointers may be strong or may be MaybeObject-style weak pointers.
164
template <int start_offset>
165
class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase {
166 167 168
 public:
  static const int kStartOffset = start_offset;

169
  static bool IsValidSlot(Map map, HeapObject obj, int offset) {
170 171 172 173
    return (offset >= kStartOffset);
  }

  template <typename ObjectVisitor>
174
  static inline void IterateBody(Map map, HeapObject obj, int object_size,
175 176 177 178
                                 ObjectVisitor* v) {
    IterateMaybeWeakPointers(obj, start_offset, object_size, v);
  }

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
 private:
  static inline int SizeOf(Map map, HeapObject object) {
    // Has to be implemented by the subclass.
    UNREACHABLE();
  }
};

// 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.
// Pointers may be strong or may be MaybeObject-style weak pointers.
template <int start_offset>
class FlexibleWeakBodyDescriptor
    : public SuffixRangeWeakBodyDescriptor<start_offset> {
 public:
194
  static inline int SizeOf(Map map, HeapObject object);
195 196
};

197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
// This class describes a body of an object without any pointers.
class DataOnlyBodyDescriptor : public BodyDescriptorBase {
 public:
  static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }

  template <typename ObjectVisitor>
  static inline void IterateBody(Map map, HeapObject obj, int object_size,
                                 ObjectVisitor* v) {}

 private:
  static inline int SizeOf(Map map, HeapObject object) {
    // Has to be implemented by the subclass.
    UNREACHABLE();
  }
};

213 214 215 216 217 218 219 220 221 222 223 224 225
// This class describes a body of an object which has a parent class that also
// has a body descriptor. This represents a union of the parent's body
// descriptor, and a new descriptor for the child -- so, both parent and child's
// slots are iterated. The parent must be fixed size, and its slots be disjoint
// with the child's.
template <class ParentBodyDescriptor, class ChildBodyDescriptor>
class SubclassBodyDescriptor final : public BodyDescriptorBase {
 public:
  // The parent must end be before the child's start offset, to make sure that
  // their slots are disjoint.
  STATIC_ASSERT(ParentBodyDescriptor::kSize <=
                ChildBodyDescriptor::kStartOffset);

226
  static bool IsValidSlot(Map map, HeapObject obj, int offset) {
227 228 229 230 231
    return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
           ChildBodyDescriptor::IsValidSlot(map, obj, offset);
  }

  template <typename ObjectVisitor>
232
  static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
233 234 235 236 237
    ParentBodyDescriptor::IterateBody(map, obj, v);
    ChildBodyDescriptor::IterateBody(map, obj, v);
  }

  template <typename ObjectVisitor>
238
  static inline void IterateBody(Map map, HeapObject obj, int object_size,
239 240 241 242 243
                                 ObjectVisitor* v) {
    ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
    ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
  }

244
  static inline int SizeOf(Map map, HeapObject object) {
245 246 247 248 249
    // The child should know its full size.
    return ChildBodyDescriptor::SizeOf(map, object);
  }
};

250 251 252
}  // namespace internal
}  // namespace v8

253
#endif  // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_