xref: /aosp_15_r20/external/pdfium/third_party/base/memory/aligned_memory.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
6 #define THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <type_traits>
12 
13 #include "build/build_config.h"
14 #include "third_party/base/base_export.h"
15 #include "third_party/base/bits.h"
16 #include "third_party/base/check.h"
17 
18 #if defined(COMPILER_MSVC)
19 #include <malloc.h>
20 #else
21 #include <stdlib.h>
22 #endif
23 
24 // A runtime sized aligned allocation can be created:
25 //
26 //   float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
27 //
28 //   // ... later, to release the memory:
29 //   AlignedFree(my_array);
30 //
31 // Or using unique_ptr:
32 //
33 //   std::unique_ptr<float, AlignedFreeDeleter> my_array(
34 //       static_cast<float*>(AlignedAlloc(size, alignment)));
35 
36 namespace pdfium {
37 namespace base {
38 
39 // This can be replaced with std::aligned_alloc when we have C++17.
40 // Caveat: std::aligned_alloc requires the size parameter be an integral
41 // multiple of alignment.
42 BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment);
43 
AlignedFree(void * ptr)44 inline void AlignedFree(void* ptr) {
45 #if defined(COMPILER_MSVC)
46   _aligned_free(ptr);
47 #else
48   free(ptr);
49 #endif
50 }
51 
52 // Deleter for use with unique_ptr. E.g., use as
53 //   std::unique_ptr<Foo, base::AlignedFreeDeleter> foo;
54 struct AlignedFreeDeleter {
operatorAlignedFreeDeleter55   inline void operator()(void* ptr) const {
56     AlignedFree(ptr);
57   }
58 };
59 
60 #ifdef __has_builtin
61 #define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
62 #else
63 #define SUPPORTS_BUILTIN_IS_ALIGNED 0
64 #endif
65 
IsAligned(uintptr_t val,size_t alignment)66 inline bool IsAligned(uintptr_t val, size_t alignment) {
67   // If the compiler supports builtin alignment checks prefer them.
68 #if SUPPORTS_BUILTIN_IS_ALIGNED
69   return __builtin_is_aligned(val, alignment);
70 #else
71   DCHECK(bits::IsPowerOfTwo(alignment));
72   return (val & (alignment - 1)) == 0;
73 #endif
74 }
75 
76 #undef SUPPORTS_BUILTIN_IS_ALIGNED
77 
IsAligned(void * val,size_t alignment)78 inline bool IsAligned(void* val, size_t alignment) {
79   return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
80 }
81 
82 }  // namespace base
83 }  // namespace pdfium
84 
85 #endif  // THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
86