From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- js/src/util/TrailingArray.h | 88 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 js/src/util/TrailingArray.h (limited to 'js/src/util/TrailingArray.h') diff --git a/js/src/util/TrailingArray.h b/js/src/util/TrailingArray.h new file mode 100644 index 0000000000..574f9aa300 --- /dev/null +++ b/js/src/util/TrailingArray.h @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef util_TrailingArray_h +#define util_TrailingArray_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT + +#include // size_t +#include // uint32_t, uintptr_t + +namespace js { + +// This is a mixin class to use for types that have trailing arrays and use +// offsets to delimit them. It provides helper methods to do casting and +// initialization while avoiding C++ undefined behaviour. +class TrailingArray { + protected: + // Offsets are measured in bytes relative to 'this'. + using Offset = uint32_t; + + // Test if offset is correctly aligned for type. + template + static constexpr bool isAlignedOffset(Offset offset) { + return offset % alignof(T) == 0; + } + template + static constexpr bool isAlignedOffset(Offset offset) { + return offset % N == 0; + } + + // Translate an offset into a concrete pointer. + template + T* offsetToPointer(Offset offset) { + uintptr_t base = reinterpret_cast(this); + return reinterpret_cast(base + offset); + } + template + const T* offsetToPointer(Offset offset) const { + uintptr_t base = reinterpret_cast(this); + return reinterpret_cast(base + offset); + } + + // Placement-new the elements of an array. This optimizes away for types with + // trivial default initialization and plays nicely with compiler vectorization + // passes. + template + void initElements(Offset offset, size_t nelem) { + MOZ_ASSERT(isAlignedOffset(offset)); + + // Address of first array element. + uintptr_t elem = reinterpret_cast(this) + offset; + + for (size_t i = 0; i < nelem; ++i) { + void* raw = reinterpret_cast(elem); + new (raw) T; + elem += sizeof(T); + } + } + + // Compute the length of an array from its start and end offset. + template + size_t numElements(Offset start, Offset end) const { + constexpr size_t ElemSize = sizeof(T); + return numElements(start, end); + } + template + size_t numElements(Offset start, Offset end) const { + MOZ_ASSERT(start <= end); + MOZ_ASSERT((end - start) % ElemSize == 0); + return (end - start) / ElemSize; + } + + // Constructor is protected so a derived type is required. + TrailingArray() = default; + + public: + // Type has trailing data so isn't copyable or movable. + TrailingArray(const TrailingArray&) = delete; + TrailingArray& operator=(const TrailingArray&) = delete; +}; + +} // namespace js + +#endif // util_TrailingArray_h -- cgit v1.2.3