Add third_party/base/memory/aligned_memory.h.

Make AlignedAlloc() available for use in an upcoming CL to fix some
memory alignment issues.

Borrow Chromium's base/aligned_memory.h at crrev.com/773784, but without
crrev.com/756778, which drags in some unneeded bits that introduce more
Chromium dependencies. The other modifications are:

- Wrap in pdfium namespace.
- Update headers and header guards.
- Change logging/checks to work with PDFium's version of base/logging.h.

Bug: chromium:1086796
Change-Id: I1cfe69b2f3ea4621fd7d02ede3aa24d7a8431954
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70472
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index ae8881d..18ff15c 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -588,6 +588,8 @@
     "base/debug/alias.h",
     "base/immediate_crash.h",
     "base/logging.h",
+    "base/memory/aligned_memory.cc",
+    "base/memory/aligned_memory.h",
     "base/no_destructor.h",
     "base/numerics/checked_math.h",
     "base/numerics/checked_math_impl.h",
diff --git a/third_party/base/memory/aligned_memory.cc b/third_party/base/memory/aligned_memory.cc
new file mode 100644
index 0000000..b4cd54f
--- /dev/null
+++ b/third_party/base/memory/aligned_memory.cc
@@ -0,0 +1,48 @@
+// 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/logging.h"
+
+#if defined(OS_ANDROID)
+#include <malloc.h>
+#endif
+
+namespace pdfium {
+namespace base {
+
+void* AlignedAlloc(size_t size, size_t alignment) {
+  DCHECK(size > 0U);
+  DCHECK_EQ(alignment & (alignment - 1), 0U);
+  DCHECK_EQ(alignment % sizeof(void*), 0U);
+  void* ptr = nullptr;
+#if defined(COMPILER_MSVC)
+  ptr = _aligned_malloc(size, alignment);
+// 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
+#elif defined(OS_ANDROID)
+  ptr = memalign(alignment, size);
+#else
+  if (int ret = posix_memalign(&ptr, alignment, size)) {
+    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_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U);
+  return ptr;
+}
+
+}  // namespace base
+}  // namespace pdfium
diff --git a/third_party/base/memory/aligned_memory.h b/third_party/base/memory/aligned_memory.h
new file mode 100644
index 0000000..59510e7
--- /dev/null
+++ b/third_party/base/memory/aligned_memory.h
@@ -0,0 +1,62 @@
+// 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/base_export.h"
+#include "third_party/base/compiler_specific.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.
+BASE_EXPORT 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);
+  }
+};
+
+}  // namespace base
+}  // namespace pdfium
+
+#endif  // THIRD_PARTY_BASE_MEMORY_ALIGNED_MEMORY_H_