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
10namespace v8 {
11namespace internal {
12
13// This is the base class for object's body descriptors.
14//
15// Each BodyDescriptor subclass must provide the following methods:
16//
17// 1) Returns true if the object contains a tagged value at given offset.
18//    It is used for invalid slots filtering. If the offset points outside
19//    of the object or to the map word, the result is UNDEFINED (!!!).
20//
21//   static bool IsValidSlot(HeapObject* obj, int offset);
22//
23//
24// 2) Iterate object's body using stateful object visitor.
25//
26//   template <typename ObjectVisitor>
27//   static inline void IterateBody(HeapObject* obj, int object_size,
28//                                  ObjectVisitor* v);
29//
30//
31// 3) Iterate object's body using stateless object visitor.
32//
33//   template <typename StaticVisitor>
34//   static inline void IterateBody(HeapObject* obj, int object_size);
35//
36class BodyDescriptorBase BASE_EMBEDDED {
37 public:
38  template <typename ObjectVisitor>
39  static inline void IteratePointers(HeapObject* obj, int start_offset,
40                                     int end_offset, ObjectVisitor* v);
41
42  template <typename StaticVisitor>
43  static inline void IteratePointers(Heap* heap, HeapObject* obj,
44                                     int start_offset, int end_offset);
45
46  template <typename ObjectVisitor>
47  static inline void IteratePointer(HeapObject* obj, int offset,
48                                    ObjectVisitor* v);
49
50  template <typename StaticVisitor>
51  static inline void IteratePointer(Heap* heap, HeapObject* obj, int offset);
52
53 protected:
54  // Returns true for all header and internal fields.
55  static inline bool IsValidSlotImpl(HeapObject* obj, int offset);
56
57  // Treats all header and internal fields in the range as tagged.
58  template <typename ObjectVisitor>
59  static inline void IterateBodyImpl(HeapObject* obj, int start_offset,
60                                     int end_offset, ObjectVisitor* v);
61
62  // Treats all header and internal fields in the range as tagged.
63  template <typename StaticVisitor>
64  static inline void IterateBodyImpl(Heap* heap, HeapObject* obj,
65                                     int start_offset, int end_offset);
66};
67
68
69// This class describes a body of an object of a fixed size
70// in which all pointer fields are located in the [start_offset, end_offset)
71// interval.
72template <int start_offset, int end_offset, int size>
73class FixedBodyDescriptor final : public BodyDescriptorBase {
74 public:
75  static const int kStartOffset = start_offset;
76  static const int kEndOffset = end_offset;
77  static const int kSize = size;
78
79  static bool IsValidSlot(HeapObject* obj, int offset) {
80    return offset >= kStartOffset && offset < kEndOffset;
81  }
82
83  template <typename ObjectVisitor>
84  static inline void IterateBody(HeapObject* obj, ObjectVisitor* v) {
85    IterateBodyImpl(obj, start_offset, end_offset, v);
86  }
87
88  template <typename ObjectVisitor>
89  static inline void IterateBody(HeapObject* obj, int object_size,
90                                 ObjectVisitor* v) {
91    IterateBody(obj, v);
92  }
93
94  template <typename StaticVisitor>
95  static inline void IterateBody(HeapObject* obj) {
96    Heap* heap = obj->GetHeap();
97    IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, end_offset);
98  }
99
100  template <typename StaticVisitor>
101  static inline void IterateBody(HeapObject* obj, int object_size) {
102    IterateBody(obj);
103  }
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(HeapObject* obj, int offset) {
116    if (offset < kStartOffset) return false;
117    return IsValidSlotImpl(obj, offset);
118  }
119
120  template <typename ObjectVisitor>
121  static inline void IterateBody(HeapObject* obj, int object_size,
122                                 ObjectVisitor* v) {
123    IterateBodyImpl(obj, start_offset, object_size, v);
124  }
125
126  template <typename StaticVisitor>
127  static inline void IterateBody(HeapObject* obj, int object_size) {
128    Heap* heap = obj->GetHeap();
129    IterateBodyImpl<StaticVisitor>(heap, obj, start_offset, object_size);
130  }
131
132  static inline int SizeOf(Map* map, HeapObject* object);
133};
134
135
136typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
137
138}  // namespace internal
139}  // namespace v8
140
141#endif  // V8_OBJECTS_BODY_DESCRIPTORS_H_
142