Reland "Implement AlignedAlloc and AlignedFree"
This reverts commit 369001ee353fb6a8fa2414deaca56af289b89c87.
Reason for revert: Fix compilation error on Mac with Skia
Original change's description:
> Revert "Implement AlignedAlloc and AlignedFree"
>
> This reverts commit 0ac8c652c3568082ef6bcf6f3a1042a6ffad9bbb.
>
> Reason for revert: Breaking compilation in Skia
>
> Original change's description:
> > Implement AlignedAlloc and AlignedFree
> >
> > This patch implements `AlignedAlloc()` and `AlignedFree()` referenced
> > from `base::AlignedAlloc()` and `base::AlignedFree()` in Chromium.
> >
> > Bug: dawn:824
> > Change-Id: Ifcd794a14be29c006e9a39323252dd6b867a30dc
> > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/183983
> > Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> > Reviewed-by: Austin Eng <enga@chromium.org>
> > Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
>
> TBR=cwallez@chromium.org,jiawei.shao@intel.com,enga@chromium.org,dawn-scoped@luci-project-accounts.iam.gserviceaccount.com
>
> Change-Id: If4f76d409ae56aa4d35b2008c12860a005d9f285
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: dawn:824
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/184601
> Auto-Submit: Corentin Wallez <cwallez@chromium.org>
> Commit-Queue: Ben Clayton <bclayton@google.com>
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> Reviewed-by: Ben Clayton <bclayton@google.com>
Bug: dawn:824
Change-Id: I9a1892b0a6397194019a8251e287d063accb45b2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/184682
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/common/AlignedAlloc.cpp b/src/dawn/common/AlignedAlloc.cpp
new file mode 100644
index 0000000..d3eca92
--- /dev/null
+++ b/src/dawn/common/AlignedAlloc.cpp
@@ -0,0 +1,66 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/common/AlignedAlloc.h"
+
+#include "dawn/common/Assert.h"
+#include "dawn/common/Math.h"
+#include "dawn/common/Platform.h"
+
+namespace dawn {
+
+void* AlignedAlloc(size_t size, size_t alignment) {
+ DAWN_ASSERT(size > 0);
+ DAWN_ASSERT(IsPowerOfTwo(alignment));
+ DAWN_ASSERT(size % alignment == 0);
+
+#if DAWN_PLATFORM_IS(WINDOWS)
+ return _aligned_malloc(size, alignment);
+
+#elif DAWN_PLATFORM_IS(ANDROID)
+ // Currently std::aligned_alloc() is not supported on the Android build of Chromium. Luckily,
+ // memalign() on Android returns pointers which can safely be used with free(), so we can use it
+ // instead.
+ return memalign(alignment, size);
+
+#else
+ return aligned_alloc(alignment, size);
+
+#endif
+}
+
+void AlignedFree(void* alignedPtr) {
+#if DAWN_PLATFORM_IS(WINDOWS)
+ _aligned_free(alignedPtr);
+
+#else
+ free(alignedPtr);
+
+#endif
+}
+
+} // namespace dawn
diff --git a/src/dawn/common/AlignedAlloc.h b/src/dawn/common/AlignedAlloc.h
new file mode 100644
index 0000000..9dfe0ba
--- /dev/null
+++ b/src/dawn/common/AlignedAlloc.h
@@ -0,0 +1,70 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_COMMON_ALIGNED_ALLOC_H_
+#define SRC_DAWN_COMMON_ALIGNED_ALLOC_H_
+
+#include <cstdlib>
+
+namespace dawn {
+
+// The implementations of dawn::AlignedAlloc() and dawn::AlignedFree() are referenced from
+// base::AlignedAlloc() and base::AlignedFree() in Chromium (in `base/memory/aligned_memory.h`).
+//
+// In Dawn, a runtime sized aligned allocation can be created:
+//
+// float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
+// CHECK(reinterpret_cast<uintptr_t>(my_array) % alignment == 0);
+// memset(my_array, 0, size); // fills entire object.
+//
+// // ... later, to release the memory:
+// AlignedFree(my_array);
+//
+// Or using unique_ptr:
+//
+// std::unique_ptr<float, AlignedFreeDeleter> my_array(
+// static_cast<float*>(AlignedAlloc(size, alignment)));
+
+// Allocate memory of size `size` aligned to `alignment`.
+// The `alignment` parameter must be an integer power of 2.
+// The `size` parameter must be an integral multiple of `alignment`.
+// Note that the memory allocated by `dawn::AlignedAlloc()` can only be deallocated by
+// `dawn::AlignedFree()` otherwise on Windows the aligned memory may not be reclaimed correctly.
+void* AlignedAlloc(size_t size, size_t alignment);
+
+// Deallocate memory allocated by `AlignedAlloc`.
+void AlignedFree(void* alignedPtr);
+
+// Deleter for use with unique_ptr. E.g., use as
+// std::unique_ptr<Foo, dawn::AlignedFreeDeleter> foo;
+struct AlignedFreeDeleter {
+ inline void operator()(void* ptr) const { AlignedFree(ptr); }
+};
+
+} // namespace dawn
+
+#endif // SRC_DAWN_COMMON_ALIGNED_ALLOC_H_
diff --git a/src/dawn/common/BUILD.gn b/src/dawn/common/BUILD.gn
index aa6eecd..094e737 100644
--- a/src/dawn/common/BUILD.gn
+++ b/src/dawn/common/BUILD.gn
@@ -239,6 +239,8 @@
is_ios) {
static_library("common") {
sources = [
+ "AlignedAlloc.cpp",
+ "AlignedAlloc.h",
"Alloc.h",
"Assert.cpp",
"Assert.h",
diff --git a/src/dawn/common/CMakeLists.txt b/src/dawn/common/CMakeLists.txt
index 477ed12..37f7e66 100644
--- a/src/dawn/common/CMakeLists.txt
+++ b/src/dawn/common/CMakeLists.txt
@@ -46,6 +46,8 @@
target_sources(dawn_common PRIVATE
${DAWN_VERSION_AUTOGEN_SOURCES}
${DAWN_GPU_INFO_AUTOGEN_SOURCES}
+ "AlignedAlloc.cpp"
+ "AlignedAlloc.h"
"Alloc.h"
"Assert.cpp"
"Assert.h"
diff --git a/src/dawn/common/SlabAllocator.cpp b/src/dawn/common/SlabAllocator.cpp
index 3f095d6..f668f37 100644
--- a/src/dawn/common/SlabAllocator.cpp
+++ b/src/dawn/common/SlabAllocator.cpp
@@ -31,6 +31,7 @@
#include <cstdlib>
#include <limits>
#include <new>
+#include "dawn/common/AlignedAlloc.h"
#include "dawn/common/Assert.h"
#include "dawn/common/Math.h"
@@ -62,7 +63,7 @@
DAWN_ASSERT(slab->blocksInUse == 0);
char* allocation = slab->allocation;
slab->~Slab(); // Placement delete.
- delete[] allocation;
+ AlignedFree(allocation);
}
}
@@ -79,12 +80,7 @@
mIndexLinkNodeOffset(Align(objectSize, alignof(IndexLinkNode))),
mBlockStride(Align(mIndexLinkNodeOffset + u32_sizeof<IndexLinkNode>, objectAlignment)),
mBlocksPerSlab(blocksPerSlab),
- mTotalAllocationSize(
- // required allocation size
- static_cast<size_t>(mSlabBlocksOffset) + mBlocksPerSlab * mBlockStride +
- // Pad the allocation size by mAllocationAlignment so that the aligned allocation still
- // fulfills the required size.
- mAllocationAlignment) {
+ mTotalAllocationSize(static_cast<size_t>(mSlabBlocksOffset) + mBlocksPerSlab * mBlockStride) {
DAWN_ASSERT(IsPowerOfTwo(mAllocationAlignment));
}
@@ -232,10 +228,7 @@
return;
}
- // TODO(crbug.com/dawn/824): Use aligned_alloc when possible. It should be available with
- // C++17 but on macOS it also requires macOS 10.15 to work.
- char* allocation = new char[mTotalAllocationSize];
- char* alignedPtr = AlignPtr(allocation, mAllocationAlignment);
+ char* alignedPtr = static_cast<char*>(AlignedAlloc(mTotalAllocationSize, mAllocationAlignment));
char* dataStart = alignedPtr + mSlabBlocksOffset;
@@ -247,7 +240,7 @@
IndexLinkNode* lastNode = OffsetFrom(node, mBlocksPerSlab - 1);
lastNode->nextIndex = kInvalidIndex;
- mAvailableSlabs.Prepend(new (alignedPtr) Slab(allocation, node));
+ mAvailableSlabs.Prepend(new (alignedPtr) Slab(alignedPtr, node));
}
} // namespace dawn