chromium/v8/src/objects/objects-body-descriptors.h

// 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::internal {

// This is the base class for object's body descriptors.
//
// Each BodyDescriptor subclass must provide the following methods:
//
// 1) Iterate object's body using stateful object visitor.
//
//   template <typename ObjectVisitor>
//   static inline void IterateBody(Tagged<Map> map, HeapObject obj, int
//   object_size,
//                                  ObjectVisitor* v);
class BodyDescriptorBase {};

// This class describes a body of an object without any pointers.
class DataOnlyBodyDescriptor : public BodyDescriptorBase {};

// 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 {};

// 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 std::conditional_t<
          start_offset == end_offset, DataOnlyBodyDescriptor,
          FixedRangeBodyDescriptor<start_offset, end_offset>> {};

FixedBodyDescriptorFor;

// 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 {};

// 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> {};

// A forward-declarable descriptor body alias for most of the Struct successors.
class StructBodyDescriptor
    : public 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 Tagged<MaybeObject>-style weak pointers.
template <int start_offset>
class SuffixRangeWeakBodyDescriptor : public BodyDescriptorBase {};

// 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 Tagged<MaybeObject>-style weak pointers.
template <int start_offset>
class FlexibleWeakBodyDescriptor
    : public SuffixRangeWeakBodyDescriptor<start_offset> {};

// 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 : public BodyDescriptorBase {};

// Visitor for exposed trusted objects with fixed layout according to
// FixedBodyDescriptor.
template <typename T, IndirectPointerTag kTag>
class FixedExposedTrustedObjectBodyDescriptor
    : public FixedBodyDescriptorFor<T> {};

// A mix-in for visiting a trusted pointer field.
template <size_t kFieldOffset, IndirectPointerTag kTag>
struct WithStrongTrustedPointer {};

WithStrongCodePointer;

// A mix-in for visiting an external pointer field.
template <size_t kFieldOffset, ExternalPointerTag kTag>
struct WithExternalPointer {};

// A mix-in for visiting an external pointer field.
template <size_t kFieldOffset>
struct WithProtectedPointer {};

// Stack multiple body descriptors; the first template argument is the base,
// followed by mix-ins.
template <typename Base, typename FirstMixin, typename... MoreMixins>
class StackedBodyDescriptor
    : public StackedBodyDescriptor<
          typename FirstMixin::template BodyDescriptor<Base>, MoreMixins...> {};

// Define a specialization for the base case of only one mixin.
StackedBodyDescriptor<Base, FirstMixin>;

}  // namespace v8::internal

#endif  // V8_OBJECTS_OBJECTS_BODY_DESCRIPTORS_H_