blob: 8135e1f1701ff08f9b1888f4048155bb2b25a81e [file] [log] [blame]
// 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.
#ifndef V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
#define V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_
#include "src/objects/map.h"
#include "src/objects/objects.h"
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 (!!!).
//
// static bool IsValidSlot(Map map, HeapObject obj, int offset);
//
//
// 2) Iterate object's body using stateful object visitor.
//
// template <typename ObjectVisitor>
// static inline void IterateBody(Map map, HeapObject obj, int object_size,
// ObjectVisitor* v);
class BodyDescriptorBase {
public:
template <typename ObjectVisitor>
static inline void IteratePointers(HeapObject obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IteratePointer(HeapObject obj, int offset,
ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateCustomWeakPointers(HeapObject obj, int start_offset,
int end_offset,
ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateCustomWeakPointer(HeapObject obj, int offset,
ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateEphemeron(HeapObject obj, int index, int key_offset,
int value_offset, ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateMaybeWeakPointers(HeapObject obj, int start_offset,
int end_offset, ObjectVisitor* v);
template <typename ObjectVisitor>
static inline void IterateMaybeWeakPointer(HeapObject obj, int offset,
ObjectVisitor* v);
protected:
// Returns true for all header and embedder fields.
static inline bool IsValidJSObjectSlotImpl(Map map, HeapObject obj,
int offset);
// Returns true for all header and embedder fields.
static inline bool IsValidEmbedderJSObjectSlotImpl(Map map, HeapObject obj,
int offset);
// Treats all header and embedder fields in the range as tagged.
template <typename ObjectVisitor>
static inline void IterateJSObjectBodyImpl(Map map, HeapObject obj,
int start_offset, int end_offset,
ObjectVisitor* v);
};
// 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 {
public:
static const int kStartOffset = start_offset;
static const int kEndOffset = end_offset;
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return offset >= kStartOffset && offset < kEndOffset;
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
IteratePointers(obj, start_offset, end_offset, v);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IterateBody(map, obj, v);
}
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 fixed size
// 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, 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.
template <int start_offset>
class SuffixRangeBodyDescriptor : public BodyDescriptorBase {
public:
static const int kStartOffset = start_offset;
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return (offset >= kStartOffset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, start_offset, object_size, v);
}
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:
static inline int SizeOf(Map map, HeapObject object);
};
using StructBodyDescriptor = FlexibleBodyDescriptor<HeapObject::kHeaderSize>;
// 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.
template <int start_offset>
class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase {
public:
static const int kStartOffset = start_offset;
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return (offset >= kStartOffset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IterateMaybeWeakPointers(obj, start_offset, object_size, v);
}
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:
static inline int SizeOf(Map map, HeapObject object);
};
// 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();
}
};
// 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);
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
return ParentBodyDescriptor::IsValidSlot(map, obj, offset) ||
ChildBodyDescriptor::IsValidSlot(map, obj, offset);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, ObjectVisitor* v) {
ParentBodyDescriptor::IterateBody(map, obj, v);
ChildBodyDescriptor::IterateBody(map, obj, v);
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
ParentBodyDescriptor::IterateBody(map, obj, object_size, v);
ChildBodyDescriptor::IterateBody(map, obj, object_size, v);
}
static inline int SizeOf(Map map, HeapObject object) {
// The child should know its full size.
return ChildBodyDescriptor::SizeOf(map, object);
}
};
} // namespace internal
} // namespace v8
#endif // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_