1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_BODY_DESCRIPTORS_H_
6#define V8_OBJECTS_BODY_DESCRIPTORS_H_
7
8#include "src/objects.h"
9#include "src/objects/map.h"
10
11namespace v8 {
12namespace internal {
13
14// This is the base class for object's body descriptors.
15//
16// Each BodyDescriptor subclass must provide the following methods:
17//
18// 1) Returns true if the object contains a tagged value at given offset.
19// It is used for invalid slots filtering. If the offset points outside
20// of the object or to the map word, the result is UNDEFINED (!!!).
21//
22// static bool IsValidSlot(Map map, HeapObject obj, int offset);
23//
24//
25// 2) Iterate object's body using stateful object visitor.
26//
27// template <typename ObjectVisitor>
28// static inline void IterateBody(Map map, HeapObject obj, int object_size,
29// ObjectVisitor* v);
30class BodyDescriptorBase {
31 public:
32 template <typename ObjectVisitor>
33 static inline void IteratePointers(HeapObject obj, int start_offset,
34 int end_offset, ObjectVisitor* v);
35
36 template <typename ObjectVisitor>
37 static inline void IteratePointer(HeapObject obj, int offset,
38 ObjectVisitor* v);
39
40 template <typename ObjectVisitor>
41 static inline void IterateCustomWeakPointers(HeapObject obj, int start_offset,
42 int end_offset,
43 ObjectVisitor* v);
44
45 template <typename ObjectVisitor>
46 static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
47 ObjectVisitor* v);
48
49 template <typename ObjectVisitor>
50 static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
51 int value_offset, ObjectVisitor* v);
52
53 template <typename ObjectVisitor>
54 static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
55 int end_offset, ObjectVisitor* v);
56
57 template <typename ObjectVisitor>
58 static inline void IterateMaybeWeakPointer(HeapObject obj, int offset,
59 ObjectVisitor* v);
60
61 protected:
62 // Returns true for all header and embedder fields.
63 static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject obj,
64 int offset);
65
66 // 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 int start_offset, int end_offset,
74 ObjectVisitor* v);
75};
76
77
78// This class describes a body of an object of a fixed size
79// in which all pointer fields are located in the [start_offset, end_offset)
80// interval.
81template <int start_offset, int end_offset, int size>
82class FixedBodyDescriptor final : public BodyDescriptorBase {
83 public:
84 static const int kStartOffset = start_offset;
85 static const int kEndOffset = end_offset;
86 static const int kSize = size;
87
88 static bool IsValidSlot(Map map, HeapObject obj, int offset) {
89 return offset >= kStartOffset && offset < kEndOffset;
90 }
91
92 template <typename ObjectVisitor>
93 static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
94 IteratePointers(obj, start_offset, end_offset, v);
95 }
96
97 template <typename ObjectVisitor>
98 static inline void IterateBody(Map map, HeapObject obj, int object_size,
99 ObjectVisitor* v) {
100 IterateBody(map, obj, v);
101 }
102
103 static inline int SizeOf(Map map, HeapObject object) { return kSize; }
104};
105
106
107// This class describes a body of an object of a variable size
108// in which all pointer fields are located in the [start_offset, object_size)
109// interval.
110template <int start_offset>
111class FlexibleBodyDescriptor final : public BodyDescriptorBase {
112 public:
113 static const int kStartOffset = start_offset;
114
115 static bool IsValidSlot(Map map, HeapObject obj, int offset) {
116 return (offset >= kStartOffset);
117 }
118
119 template <typename ObjectVisitor>
120 static inline void IterateBody(Map map, HeapObject obj, int object_size,
121 ObjectVisitor* v) {
122 IteratePointers(obj, start_offset, object_size, v);
123 }
124
125 static inline int SizeOf(Map map, HeapObject object);
126};
127
128typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
129
130template <int start_offset>
131class FlexibleWeakBodyDescriptor final : public BodyDescriptorBase {
132 public:
133 static const int kStartOffset = start_offset;
134
135 static bool IsValidSlot(Map map, HeapObject obj, int offset) {
136 return (offset >= kStartOffset);
137 }
138
139 template <typename ObjectVisitor>
140 static inline void IterateBody(Map map, HeapObject obj, int object_size,
141 ObjectVisitor* v) {
142 IterateMaybeWeakPointers(obj, start_offset, object_size, v);
143 }
144
145 static inline int SizeOf(Map map, HeapObject object);
146};
147
148// This class describes a body of an object which has a parent class that also
149// has a body descriptor. This represents a union of the parent's body
150// descriptor, and a new descriptor for the child -- so, both parent and child's
151// slots are iterated. The parent must be fixed size, and its slots be disjoint
152// with the child's.
153template <class ParentBodyDescriptor, class ChildBodyDescriptor>
154class SubclassBodyDescriptor final : public BodyDescriptorBase {
155 public:
156 // The parent must end be before the child's start offset, to make sure that
157 // their slots are disjoint.
158 STATIC_ASSERT(ParentBodyDescriptor::kSize <=
159 ChildBodyDescriptor::kStartOffset);
160
161 static bool IsValidSlot(Map map, HeapObject obj, int offset) {
162 return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
163 ChildBodyDescriptor::IsValidSlot(map, obj, offset);
164 }
165
166 template <typename ObjectVisitor>
167 static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
168 ParentBodyDescriptor::IterateBody(map, obj, v);
169 ChildBodyDescriptor::IterateBody(map, obj, v);
170 }
171
172 template <typename ObjectVisitor>
173 static inline void IterateBody(Map map, HeapObject obj, int object_size,
174 ObjectVisitor* v) {
175 ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
176 ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
177 }
178
179 static inline int SizeOf(Map map, HeapObject object) {
180 // The child should know its full size.
181 return ChildBodyDescriptor::SizeOf(map, object);
182 }
183};
184
185} // namespace internal
186} // namespace v8
187
188#endif // V8_OBJECTS_BODY_DESCRIPTORS_H_
189