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) {