Merge third_party/base/memory/aligned_memory.h into fx_memory.h
Move the aligned alloc and free functions to core/fxcrt and rename them
to FX_AlignedAlloc() and FX_AlignedFree(). Then move the code in
third_party/base/bits.h into fx_memory.cpp, since that is the only
caller to IsPowerOfTwo().
Bug: pdfium:2127
Change-Id: I16e41b92b08ad30f029674d9342d282de2c75e4a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116730
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcrt/fx_memory.cpp b/core/fxcrt/fx_memory.cpp
index 9d84540..4ed7b51 100644
--- a/core/fxcrt/fx_memory.cpp
+++ b/core/fxcrt/fx_memory.cpp
@@ -10,14 +10,58 @@
#include <iterator>
#include <limits>
+#include <type_traits>
#include "build/build_config.h"
#include "core/fxcrt/debug/alias.h"
+#include "third_party/base/check_op.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif
+#if BUILDFLAG(IS_ANDROID)
+#include <malloc.h>
+#endif
+
+namespace {
+
+#if DCHECK_IS_ON()
+// TODO(thestig): When C++20 is required, replace with std::has_single_bit().
+// Returns true iff |value| is a power of 2.
+template <typename T, typename = std::enable_if<std::is_integral<T>::value>>
+constexpr inline bool IsPowerOfTwo(T value) {
+ // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
+ //
+ // Only positive integers with a single bit set are powers of two. If only one
+ // bit is set in x (e.g. 0b00000100000000) then |x-1| will have that bit set
+ // to zero and all bits to its right set to 1 (e.g. 0b00000011111111). Hence
+ // |x & (x-1)| is 0 iff x is a power of two.
+ return value > 0 && (value & (value - 1)) == 0;
+}
+
+#ifdef __has_builtin
+#define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
+#else
+#define SUPPORTS_BUILTIN_IS_ALIGNED 0
+#endif
+
+inline bool IsAligned(void* val, size_t alignment) {
+ // If the compiler supports builtin alignment checks prefer them.
+#if SUPPORTS_BUILTIN_IS_ALIGNED
+ return __builtin_is_aligned(reinterpret_cast<uintptr_t>(val), alignment);
+#else
+ DCHECK(IsPowerOfTwo(alignment));
+ return (reinterpret_cast<uintptr_t>(val) & (alignment - 1)) == 0;
+#endif
+}
+
+#undef SUPPORTS_BUILTIN_IS_ALIGNED
+
+#endif // DCHECK_IS_ON()
+
+} // namespace
+
void* FXMEM_DefaultAlloc(size_t byte_size) {
return pdfium::internal::Alloc(byte_size, 1);
}
@@ -52,6 +96,38 @@
abort();
}
+void* FX_AlignedAlloc(size_t size, size_t alignment) {
+ DCHECK_GT(size, 0u);
+ DCHECK(IsPowerOfTwo(alignment));
+ DCHECK_EQ(alignment % sizeof(void*), 0u);
+ void* ptr = nullptr;
+#if defined(COMPILER_MSVC)
+ ptr = _aligned_malloc(size, alignment);
+#elif BUILDFLAG(IS_ANDROID)
+ // Android technically supports posix_memalign(), but does not expose it in
+ // the current version of the library headers used by Chrome. Luckily,
+ // memalign() on Android returns pointers which can safely be used with
+ // free(), so we can use it instead. Issue filed to document this:
+ // http://code.google.com/p/android/issues/detail?id=35391
+ ptr = memalign(alignment, size);
+#else
+ int ret = posix_memalign(&ptr, alignment, size);
+ if (ret != 0) {
+ ptr = nullptr;
+ }
+#endif
+
+ // Since aligned allocations may fail for non-memory related reasons, force a
+ // crash if we encounter a failed allocation; maintaining consistent behavior
+ // with a normal allocation failure in Chrome.
+ if (!ptr) {
+ CHECK(false);
+ }
+ // Sanity check alignment just to be safe.
+ DCHECK(IsAligned(ptr, alignment));
+ return ptr;
+}
+
namespace pdfium::internal {
void* AllocOrDie(size_t num_members, size_t member_size) {
diff --git a/core/fxcrt/fx_memory.h b/core/fxcrt/fx_memory.h
index ac61146..477823c 100644
--- a/core/fxcrt/fx_memory.h
+++ b/core/fxcrt/fx_memory.h
@@ -24,6 +24,12 @@
#include "third_party/base/compiler_specific.h"
+#if defined(COMPILER_MSVC)
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+
void FX_InitializeMemoryAllocators();
NOINLINE void FX_OutOfMemoryTerminate(size_t size);
@@ -75,6 +81,21 @@
void FX_ArrayBufferFree(void* data);
#endif // V8_ENABLE_SANDBOX
+// Aligned allocators.
+
+// This can be replaced with std::aligned_alloc when we have C++17.
+// Caveat: std::aligned_alloc requires the size parameter be an integral
+// multiple of alignment.
+void* FX_AlignedAlloc(size_t size, size_t alignment);
+
+inline void FX_AlignedFree(void* ptr) {
+#if defined(COMPILER_MSVC)
+ _aligned_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
namespace pdfium {
namespace internal {
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index b6a4829..7ce0ee4 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -552,13 +552,10 @@
":pdfium_third_party_config",
]
sources = [
- "base/bits.h",
"base/check.h",
"base/check_op.h",
"base/component_export.h",
"base/immediate_crash.h",
- "base/memory/aligned_memory.cc",
- "base/memory/aligned_memory.h",
"base/memory/ptr_util.h",
"base/no_destructor.h",
"base/notreached.h",
diff --git a/third_party/base/bits.h b/third_party/base/bits.h
deleted file mode 100644
index b726f2f..0000000
--- a/third_party/base/bits.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file defines some bit utilities.
-
-#ifndef THIRD_PARTY_BASE_BITS_H_
-#define THIRD_PARTY_BASE_BITS_H_
-
-#include <type_traits>
-
-namespace pdfium {
-namespace base {
-namespace bits {
-
-// TODO(thestig): When C++20 is required, replace with std::has_single_bit().
-// Returns true iff |value| is a power of 2.
-template <typename T, typename = std::enable_if<std::is_integral<T>::value>>
-constexpr inline bool IsPowerOfTwo(T value) {
- // From "Hacker's Delight": Section 2.1 Manipulating Rightmost Bits.
- //
- // Only positive integers with a single bit set are powers of two. If only one
- // bit is set in x (e.g. 0b00000100000000) then |x-1| will have that bit set
- // to zero and all bits to its right set to 1 (e.g. 0b00000011111111). Hence
- // |x & (x-1)| is 0 iff x is a power of two.
- return value > 0 && (value & (value - 1)) == 0;
-}
-
-} // namespace bits
-} // namespace base
-} // namespace pdfium
-
-#endif // THIRD_PARTY_BASE_BITS_H_
diff --git a/third_party/base/memory/aligned_memory.cc b/third_party/base/memory/aligned_memory.cc
deleted file mode 100644
index 10884e8..0000000
--- a/third_party/base/memory/aligned_memory.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/base/memory/aligned_memory.h"
-
-#include "build/build_config.h"
-#include "third_party/base/check_op.h"
-
-#if BUILDFLAG(IS_ANDROID)
-#include <malloc.h>
-#endif
-
-namespace pdfium {
-namespace base {
-
-void* AlignedAlloc(size_t size, size_t alignment) {
- DCHECK(size > 0U);
- DCHECK(bits::IsPowerOfTwo(alignment));
- DCHECK_EQ(alignment % sizeof(void*), 0U);
- void* ptr = nullptr;
-#if defined(COMPILER_MSVC)
- ptr = _aligned_malloc(size, alignment);
-#elif BUILDFLAG(IS_ANDROID)
- // Android technically supports posix_memalign(), but does not expose it in
- // the current version of the library headers used by Chrome. Luckily,
- // memalign() on Android returns pointers which can safely be used with
- // free(), so we can use it instead. Issue filed to document this:
- // http://code.google.com/p/android/issues/detail?id=35391
- ptr = memalign(alignment, size);
-#else
- int ret = posix_memalign(&ptr, alignment, size);
- if (ret != 0) {
- ptr = nullptr;
- }
-#endif
-
- // Since aligned allocations may fail for non-memory related reasons, force a
- // crash if we encounter a failed allocation; maintaining consistent behavior
- // with a normal allocation failure in Chrome.
- if (!ptr) {
- CHECK(false);
- }
- // Sanity check alignment just to be safe.
- DCHECK(IsAligned(ptr, alignment));
- return ptr;
-}
-
-} // namespace base
-} // namespace pdfium
diff --git a/third_party/base/memory/aligned_memory.h b/third_party/base/memory/aligned_memory.h
deleted file mode 100644
index 2a95ebe..0000000
--- a/third_party/base/memory/aligned_memory.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
-#define THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <type_traits>
-
-#include "build/build_config.h"
-#include "third_party/base/bits.h"
-#include "third_party/base/check.h"
-
-#if defined(COMPILER_MSVC)
-#include <malloc.h>
-#else
-#include <stdlib.h>
-#endif
-
-// A runtime sized aligned allocation can be created:
-//
-// float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
-//
-// // ... 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)));
-
-namespace pdfium {
-namespace base {
-
-// This can be replaced with std::aligned_alloc when we have C++17.
-// Caveat: std::aligned_alloc requires the size parameter be an integral
-// multiple of alignment.
-void* AlignedAlloc(size_t size, size_t alignment);
-
-inline void AlignedFree(void* ptr) {
-#if defined(COMPILER_MSVC)
- _aligned_free(ptr);
-#else
- free(ptr);
-#endif
-}
-
-// Deleter for use with unique_ptr. E.g., use as
-// std::unique_ptr<Foo, base::AlignedFreeDeleter> foo;
-struct AlignedFreeDeleter {
- inline void operator()(void* ptr) const {
- AlignedFree(ptr);
- }
-};
-
-#ifdef __has_builtin
-#define SUPPORTS_BUILTIN_IS_ALIGNED (__has_builtin(__builtin_is_aligned))
-#else
-#define SUPPORTS_BUILTIN_IS_ALIGNED 0
-#endif
-
-inline bool IsAligned(uintptr_t val, size_t alignment) {
- // If the compiler supports builtin alignment checks prefer them.
-#if SUPPORTS_BUILTIN_IS_ALIGNED
- return __builtin_is_aligned(val, alignment);
-#else
- DCHECK(bits::IsPowerOfTwo(alignment));
- return (val & (alignment - 1)) == 0;
-#endif
-}
-
-#undef SUPPORTS_BUILTIN_IS_ALIGNED
-
-inline bool IsAligned(void* val, size_t alignment) {
- return IsAligned(reinterpret_cast<uintptr_t>(val), alignment);
-}
-
-} // namespace base
-} // namespace pdfium
-
-#endif // THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_
diff --git a/third_party/libopenjpeg/0034-opj_malloc.patch b/third_party/libopenjpeg/0034-opj_malloc.patch
index 3ad0d57..106d722 100644
--- a/third_party/libopenjpeg/0034-opj_malloc.patch
+++ b/third_party/libopenjpeg/0034-opj_malloc.patch
@@ -2,7 +2,7 @@
new file mode 100644
--- /dev/null
+++ b/third_party/libopenjpeg/opj_malloc.cc
-@@ -0,0 +1,42 @@
+@@ -0,0 +1,41 @@
+// Copyright 2020 The PDFium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
@@ -11,7 +11,6 @@
+// friends.
+
+#include "core/fxcrt/fx_memory.h"
-+#include "third_party/base/memory/aligned_memory.h"
+
+extern "C" {
+
@@ -24,15 +23,15 @@
+}
+
+void* opj_aligned_malloc(size_t size) {
-+ return size ? pdfium::base::AlignedAlloc(size, 16) : nullptr;
++ return size ? FX_AlignedAlloc(size, 16) : nullptr;
+}
+
+void opj_aligned_free(void* ptr) {
-+ pdfium::base::AlignedFree(ptr);
++ FX_AlignedFree(ptr);
+}
+
+void* opj_aligned_32_malloc(size_t size) {
-+ return size ? pdfium::base::AlignedAlloc(size, 32) : nullptr;
++ return size ? FX_AlignedAlloc(size, 32) : nullptr;
+}
+
+void* opj_realloc(void* m, size_t s) {
diff --git a/third_party/libopenjpeg/opj_malloc.cc b/third_party/libopenjpeg/opj_malloc.cc
index a8d8700..252af7c 100644
--- a/third_party/libopenjpeg/opj_malloc.cc
+++ b/third_party/libopenjpeg/opj_malloc.cc
@@ -6,7 +6,6 @@
// friends.
#include "core/fxcrt/fx_memory.h"
-#include "third_party/base/memory/aligned_memory.h"
extern "C" {
@@ -19,15 +18,15 @@
}
void* opj_aligned_malloc(size_t size) {
- return size ? pdfium::base::AlignedAlloc(size, 16) : nullptr;
+ return size ? FX_AlignedAlloc(size, 16) : nullptr;
}
void opj_aligned_free(void* ptr) {
- pdfium::base::AlignedFree(ptr);
+ FX_AlignedFree(ptr);
}
void* opj_aligned_32_malloc(size_t size) {
- return size ? pdfium::base::AlignedAlloc(size, 32) : nullptr;
+ return size ? FX_AlignedAlloc(size, 32) : nullptr;
}
void* opj_realloc(void* m, size_t s) {