• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
10 namespace v8 {
11 namespace 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(Map* map, 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(Map* map, HeapObject* obj, int object_size,
28 //                                  ObjectVisitor* v);
29 class BodyDescriptorBase BASE_EMBEDDED {
30  public:
31   template <typename ObjectVisitor>
32   static inline void IteratePointers(HeapObject* obj, int start_offset,
33                                      int end_offset, ObjectVisitor* v);
34 
35   template <typename ObjectVisitor>
36   static inline void IteratePointer(HeapObject* obj, int offset,
37                                     ObjectVisitor* v);
38 
39   template <typename ObjectVisitor>
40   static inline void IterateMaybeWeakPointers(HeapObject* obj, int start_offset,
41                                               int end_offset, ObjectVisitor* v);
42 
43   template <typename ObjectVisitor>
44   static inline void IterateMaybeWeakPointer(HeapObject* obj, int offset,
45                                              ObjectVisitor* v);
46 
47  protected:
48   // Returns true for all header and embedder fields.
49   static inline bool IsValidSlotImpl(Map* map, HeapObject* obj, int offset);
50 
51   // Treats all header and embedder fields in the range as tagged.
52   template <typename ObjectVisitor>
53   static inline void IterateBodyImpl(Map* map, HeapObject* obj,
54                                      int start_offset, int end_offset,
55                                      ObjectVisitor* v);
56 };
57 
58 
59 // This class describes a body of an object of a fixed size
60 // in which all pointer fields are located in the [start_offset, end_offset)
61 // interval.
62 template <int start_offset, int end_offset, int size>
63 class FixedBodyDescriptor final : public BodyDescriptorBase {
64  public:
65   static const int kStartOffset = start_offset;
66   static const int kEndOffset = end_offset;
67   static const int kSize = size;
68 
IsValidSlot(Map * map,HeapObject * obj,int offset)69   static bool IsValidSlot(Map* map, HeapObject* obj, int offset) {
70     return offset >= kStartOffset && offset < kEndOffset;
71   }
72 
73   template <typename ObjectVisitor>
IterateBody(Map * map,HeapObject * obj,ObjectVisitor * v)74   static inline void IterateBody(Map* map, HeapObject* obj, ObjectVisitor* v) {
75     IteratePointers(obj, start_offset, end_offset, v);
76   }
77 
78   template <typename ObjectVisitor>
IterateBody(Map * map,HeapObject * obj,int object_size,ObjectVisitor * v)79   static inline void IterateBody(Map* map, HeapObject* obj, int object_size,
80                                  ObjectVisitor* v) {
81     IterateBody(map, obj, v);
82   }
83 
SizeOf(Map * map,HeapObject * object)84   static inline int SizeOf(Map* map, HeapObject* object) { return kSize; }
85 };
86 
87 
88 // This class describes a body of an object of a variable size
89 // in which all pointer fields are located in the [start_offset, object_size)
90 // interval.
91 template <int start_offset>
92 class FlexibleBodyDescriptor final : public BodyDescriptorBase {
93  public:
94   static const int kStartOffset = start_offset;
95 
IsValidSlot(Map * map,HeapObject * obj,int offset)96   static bool IsValidSlot(Map* map, HeapObject* obj, int offset) {
97     return (offset >= kStartOffset);
98   }
99 
100   template <typename ObjectVisitor>
IterateBody(Map * map,HeapObject * obj,int object_size,ObjectVisitor * v)101   static inline void IterateBody(Map* map, HeapObject* obj, int object_size,
102                                  ObjectVisitor* v) {
103     IteratePointers(obj, start_offset, object_size, v);
104   }
105 
106   static inline int SizeOf(Map* map, HeapObject* object);
107 };
108 
109 
110 typedef FlexibleBodyDescriptor<HeapObject::kHeaderSize> StructBodyDescriptor;
111 
112 // This class describes a body of an object which has a parent class that also
113 // has a body descriptor. This represents a union of the parent's body
114 // descriptor, and a new descriptor for the child -- so, both parent and child's
115 // slots are iterated. The parent must be fixed size, and its slots be disjoint
116 // with the child's.
117 template <class ParentBodyDescriptor, class ChildBodyDescriptor>
118 class SubclassBodyDescriptor final : public BodyDescriptorBase {
119  public:
120   // The parent must end be before the child's start offset, to make sure that
121   // their slots are disjoint.
122   STATIC_ASSERT(ParentBodyDescriptor::kSize <=
123                 ChildBodyDescriptor::kStartOffset);
124 
IsValidSlot(Map * map,HeapObject * obj,int offset)125   static bool IsValidSlot(Map* map, HeapObject* obj, int offset) {
126     return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
127            ChildBodyDescriptor::IsValidSlot(map, obj, offset);
128   }
129 
130   template <typename ObjectVisitor>
IterateBody(Map * map,HeapObject * obj,ObjectVisitor * v)131   static inline void IterateBody(Map* map, HeapObject* obj, ObjectVisitor* v) {
132     ParentBodyDescriptor::IterateBody(map, obj, v);
133     ChildBodyDescriptor::IterateBody(map, obj, v);
134   }
135 
136   template <typename ObjectVisitor>
IterateBody(Map * map,HeapObject * obj,int object_size,ObjectVisitor * v)137   static inline void IterateBody(Map* map, HeapObject* obj, int object_size,
138                                  ObjectVisitor* v) {
139     ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
140     ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
141   }
142 
SizeOf(Map * map,HeapObject * object)143   static inline int SizeOf(Map* map, HeapObject* object) {
144     // The child should know its full size.
145     return ChildBodyDescriptor::SizeOf(map, object);
146   }
147 };
148 
149 }  // namespace internal
150 }  // namespace v8
151 
152 #endif  // V8_OBJECTS_BODY_DESCRIPTORS_H_
153