Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions core/foundation/inc/ROOT/BitUtils.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <type_traits>

#ifdef _MSC_VER
Expand All @@ -41,6 +42,13 @@ inline constexpr T AlignUp(T value, T align) noexcept
return (value + align - 1) & ~(align - 1);
}

/// Storage type whose alignment matches \a Align bytes.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Storage type whose alignment matches \a Align bytes.
/// Storage type whose alignment matches \a AlignT bytes.

/// Used to instantiate std::vector specializations with guaranteed buffer alignment.
template <std::size_t AlignT>
struct alignas(AlignT) RAlignedStorage {
char data[AlignT] = {};
};

/// Given an integer `x`, returns the number of leading 0-bits starting at the most significant bit position.
/// If `x` is 0, it returns the size of `x` in bits.
///
Expand Down Expand Up @@ -148,6 +156,11 @@ inline std::size_t TrailingZeroes(T x)
#endif // _MSC_VER
}

inline bool IsPowerOfTwo(std::uint64_t v)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may (or may not) want to use this in IsValidAlignment (which is only different as it reject 0)

{
return (v & (v - 1)) == 0;
}

} // namespace Internal
} // namespace ROOT

Expand Down
35 changes: 15 additions & 20 deletions io/io/inc/TEmulatedCollectionProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,22 @@ class TEmulatedCollectionProxy : public TGenCollectionProxy {
friend class TCollectionProxy;

public:
/// Storage type whose alignment matches \a Align bytes.
/// Used to instantiate std::vector specializations with guaranteed buffer alignment.
template <std::size_t Align>
struct alignas(Align) AlignedStorage {
char data[Align] = {};
};

// Convenience vector aliases for each supported alignment.
using Cont1_t = std::vector<AlignedStorage< 1>>;
using Cont2_t = std::vector<AlignedStorage< 2>>;
using Cont4_t = std::vector<AlignedStorage< 4>>;
using Cont8_t = std::vector<AlignedStorage< 8>>;
using Cont16_t = std::vector<AlignedStorage< 16>>;
using Cont32_t = std::vector<AlignedStorage< 32>>;
using Cont64_t = std::vector<AlignedStorage< 64>>;
using Cont128_t = std::vector<AlignedStorage< 128>>;
using Cont256_t = std::vector<AlignedStorage< 256>>;
using Cont512_t = std::vector<AlignedStorage< 512>>;
using Cont1024_t = std::vector<AlignedStorage<1024>>;
using Cont2048_t = std::vector<AlignedStorage<2048>>;
using Cont4096_t = std::vector<AlignedStorage<4096>>;
// clang-format off
using Cont1_t = std::vector<ROOT::Internal::RAlignedStorage< 1>>;
using Cont2_t = std::vector<ROOT::Internal::RAlignedStorage< 2>>;
using Cont4_t = std::vector<ROOT::Internal::RAlignedStorage< 4>>;
using Cont8_t = std::vector<ROOT::Internal::RAlignedStorage< 8>>;
using Cont16_t = std::vector<ROOT::Internal::RAlignedStorage< 16>>;
using Cont32_t = std::vector<ROOT::Internal::RAlignedStorage< 32>>;
using Cont64_t = std::vector<ROOT::Internal::RAlignedStorage< 64>>;
using Cont128_t = std::vector<ROOT::Internal::RAlignedStorage< 128>>;
using Cont256_t = std::vector<ROOT::Internal::RAlignedStorage< 256>>;
using Cont512_t = std::vector<ROOT::Internal::RAlignedStorage< 512>>;
using Cont1024_t = std::vector<ROOT::Internal::RAlignedStorage<1024>>;
using Cont2048_t = std::vector<ROOT::Internal::RAlignedStorage<2048>>;
using Cont4096_t = std::vector<ROOT::Internal::RAlignedStorage<4096>>;
// clang-format on

// Canonical container type (used for sizeof/typeid; actual alignment is
// selected at runtime via the alignment switch in each method).
Expand Down
9 changes: 4 additions & 5 deletions tree/ntuple/inc/ROOT/RField.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,13 @@ private:
TClass *fClass;

public:
explicit RClassDeleter(TClass *cl) : fClass(cl) {}
explicit RClassDeleter(TClass *cl);
void operator()(void *objPtr, bool dtorOnly) final;
};

TClass *fClass;
/// Additional information kept for each entry in `fSubfields`
std::vector<RSubfieldInfo> fSubfieldsInfo;
std::size_t fMaxAlignment = 1;

/// The staging area stores inputs to I/O rules according to the offsets given by the streamer info of
/// "TypeName@@Version". The area is allocated depending on I/O rules resp. the source members of the I/O rules.
Expand Down Expand Up @@ -220,8 +219,8 @@ public:
~RClassField() override;

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final;
size_t GetAlignment() const final { return fMaxAlignment; }
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;
std::uint32_t GetTypeVersion() const final;
std::uint32_t GetTypeChecksum() const final;
/// For polymorphic classes (that declare or inherit at least one virtual method), return the expected dynamic type
Expand All @@ -240,7 +239,7 @@ private:
TClass *fClass;

public:
explicit RStreamerFieldDeleter(TClass *cl) : fClass(cl) {}
explicit RStreamerFieldDeleter(TClass *cl);
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand Down
12 changes: 4 additions & 8 deletions tree/ntuple/inc/ROOT/RField/RFieldProxiedCollection.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,9 @@ protected:
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite;

public:
explicit RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy) : fProxy(proxy) {}
explicit RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy);
RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy, std::unique_ptr<RDeleter> itemDeleter,
size_t itemSize)
: fProxy(proxy), fItemDeleter(std::move(itemDeleter)), fItemSize(itemSize)
{
fIFuncsWrite = RCollectionIterableOnce::GetIteratorFuncs(fProxy.get(), false /* readFromDisk */);
}
size_t itemSize);
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand Down Expand Up @@ -176,8 +172,8 @@ public:
~RProxiedCollectionField() override = default;

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final { return fProxy->Sizeof(); }
size_t GetAlignment() const final { return alignof(std::max_align_t); }
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

Expand Down
5 changes: 3 additions & 2 deletions tree/ntuple/inc/ROOT/RField/RFieldRecord.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ class RRecordField : public RFieldBase {
std::vector<std::size_t> fOffsets;

public:
RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets)
: fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets,
std::size_t alignment)
: RDeleter(alignment), fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
{
}
void operator()(void *objPtr, bool dtorOnly) final;
Expand Down
34 changes: 21 additions & 13 deletions tree/ntuple/inc/ROOT/RField/RFieldSTLMisc.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,10 @@ class ROptionalField : public RNullableField {
std::size_t fEngagementPtrOffset = 0;

public:
ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter, std::size_t engagementPtrOffset)
: fItemDeleter(std::move(itemDeleter)), fEngagementPtrOffset(engagementPtrOffset) {}
ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter, std::size_t engagementPtrOffset, std::size_t alignment)
: RDeleter(alignment), fItemDeleter(std::move(itemDeleter)), fEngagementPtrOffset(engagementPtrOffset)
{
}
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand Down Expand Up @@ -264,8 +266,8 @@ public:
~ROptionalField() override = default;

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final;
size_t GetAlignment() const final;
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;
};

template <typename ItemT>
Expand All @@ -284,7 +286,10 @@ class RUniquePtrField : public RNullableField {
std::unique_ptr<RDeleter> fItemDeleter;

public:
explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter)
: RDeleter(alignof(std::unique_ptr<char>)), fItemDeleter(std::move(itemDeleter))
{
}
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand Down Expand Up @@ -313,8 +318,8 @@ public:
~RUniquePtrField() override = default;

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
std::size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
std::size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
};

template <typename ItemT>
Expand Down Expand Up @@ -363,8 +368,8 @@ public:
RField &operator=(RField &&other) = default;
~RField() final = default;

size_t GetValueSize() const final { return sizeof(std::string); }
size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
std::size_t GetValueSize() const final { return sizeof(std::string); }
std::size_t GetAlignment() const final { return alignof(std::string); }
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

Expand All @@ -388,9 +393,12 @@ private:
std::vector<std::unique_ptr<RDeleter>> fItemDeleters;

public:
RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset,
RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset, std::size_t alignment,
std::vector<std::unique_ptr<RDeleter>> itemDeleters)
: fTagOffset(tagOffset), fVariantOffset(variantOffset), fItemDeleters(std::move(itemDeleters))
: RDeleter(alignment),
fTagOffset(tagOffset),
fVariantOffset(variantOffset),
fItemDeleters(std::move(itemDeleters))
{
}
void operator()(void *objPtr, bool dtorOnly) final;
Expand Down Expand Up @@ -436,8 +444,8 @@ public:
RVariantField &operator=(RVariantField &&other) = default;
~RVariantField() override = default;

size_t GetValueSize() const final;
size_t GetAlignment() const final;
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;
};

template <typename... ItemTs>
Expand Down
34 changes: 19 additions & 15 deletions tree/ntuple/inc/ROOT/RField/RFieldSequenceContainer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ private:
std::unique_ptr<RDeleter> fItemDeleter;

public:
RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr<RDeleter> itemDeleter)
: fItemSize(itemSize), fArrayLength(arrayLength), fItemDeleter(std::move(itemDeleter))
RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::size_t alignment,
std::unique_ptr<RDeleter> itemDeleter)
: RDeleter(alignment), fItemSize(itemSize), fArrayLength(arrayLength), fItemDeleter(std::move(itemDeleter))
{
}
void operator()(void *objPtr, bool dtorOnly) final;
Expand Down Expand Up @@ -126,9 +127,15 @@ class RRVecField : public RFieldBase {
std::unique_ptr<RDeleter> fItemDeleter;

public:
explicit RRVecDeleter(std::size_t itemAlignment) : fItemAlignment(itemAlignment) {}
explicit RRVecDeleter(std::size_t itemAlignment)
: RDeleter(ROOT::Internal::EvalRVecAlignment(itemAlignment)), fItemAlignment(itemAlignment)
{
}
RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
: fItemAlignment(itemAlignment), fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
: RDeleter(ROOT::Internal::EvalRVecAlignment(itemAlignment)),
fItemAlignment(itemAlignment),
fItemSize(itemSize),
fItemDeleter(std::move(itemDeleter))
{
}
void operator()(void *objPtr, bool dtorOnly) final;
Expand Down Expand Up @@ -211,11 +218,8 @@ class RVectorField : public RFieldBase {
std::unique_ptr<RDeleter> fItemDeleter;

public:
RVectorDeleter() = default;
RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
: fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
{
}
RVectorDeleter();
RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter);
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand Down Expand Up @@ -261,8 +265,8 @@ public:
CreateUntyped(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final { return sizeof(std::vector<char>); }
size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

Expand Down Expand Up @@ -315,8 +319,8 @@ public:

std::vector<RValue> SplitValue(const RValue &value) const final;

size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
std::size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
std::size_t GetAlignment() const final { return alignof(std::vector<bool>); }
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

Expand Down Expand Up @@ -410,8 +414,8 @@ public:
RArrayAsVectorField &operator=(RArrayAsVectorField &&other) = default;
~RArrayAsVectorField() final = default;

size_t GetValueSize() const final { return sizeof(std::vector<char>); }
size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
std::size_t GetValueSize() const final;
std::size_t GetAlignment() const final;

std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
Expand Down
5 changes: 2 additions & 3 deletions tree/ntuple/inc/ROOT/RField/RFieldSoA.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class RSoAField : public RFieldBase {
TClass *fSoAClass;

public:
explicit RSoADeleter(TClass *cl) : fSoAClass(cl) {}
explicit RSoADeleter(TClass *cl);
void operator()(void *objPtr, bool dtorOnly) final;
};

Expand All @@ -67,7 +67,6 @@ class RSoAField : public RFieldBase {
/// The offset of the RVec members in the SoA type in the order of subfields of the underlying record type.
/// In particular, the order is not necessarily the same then the order of RVec members in the SoA class.
std::vector<std::size_t> fSoAMemberOffsets;
std::size_t fMaxAlignment = 1;
ROOT::Internal::RColumnIndex fNWritten;

RSoAField(std::string_view fieldName, const RSoAField &source); ///< Used by CloneImpl
Expand Down Expand Up @@ -98,7 +97,7 @@ public:

std::vector<RValue> SplitValue(const RValue &value) const final;
size_t GetValueSize() const final;
size_t GetAlignment() const final { return fMaxAlignment; }
size_t GetAlignment() const final;
std::uint32_t GetTypeVersion() const final;
std::uint32_t GetTypeChecksum() const final;
/// For polymorphic classes (that declare or inherit at least one virtual method), return the expected dynamic type
Expand Down
Loading
Loading