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