Make PartitionAlloc more like Chromium's.
- Add pdfium::base::bits::IsPowerOfTwo(), merge https://crrev.com/614040
- Add a cheap knockoff of CHECK_EQ(). Change some CHECK(x == y) calls
back to using CHECK_EQ().
Change-Id: I34918e5dd17175d1f9d660b0b57a7a736f30a37a
Reviewed-on: https://pdfium-review.googlesource.com/c/51170
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
diff --git a/third_party/base/allocator/partition_allocator/page_allocator.cc b/third_party/base/allocator/partition_allocator/page_allocator.cc
index 76f584b..683632d 100644
--- a/third_party/base/allocator/partition_allocator/page_allocator.cc
+++ b/third_party/base/allocator/partition_allocator/page_allocator.cc
@@ -12,6 +12,7 @@
#include "third_party/base/allocator/partition_allocator/address_space_randomization.h"
#include "third_party/base/allocator/partition_allocator/page_allocator_internal.h"
#include "third_party/base/allocator/partition_allocator/spin_lock.h"
+#include "third_party/base/bits.h"
#include "third_party/base/logging.h"
#include "third_party/base/numerics/safe_math.h"
@@ -109,7 +110,7 @@
DCHECK(!(length & kPageAllocationGranularityOffsetMask));
DCHECK(align >= kPageAllocationGranularity);
// Alignment must be power of 2 for masking math to work.
- DCHECK_EQ(align & (align - 1), 0UL);
+ DCHECK(pdfium::base::bits::IsPowerOfTwo(align));
DCHECK(!(reinterpret_cast<uintptr_t>(address) &
kPageAllocationGranularityOffsetMask));
uintptr_t align_offset_mask = align - 1;
@@ -120,7 +121,7 @@
// On 64 bit Linux, we may need to adjust the address space limit for
// guarded allocations.
if (length >= kMinimumGuardedMemorySize) {
- CHECK(PageInaccessible == accessibility);
+ CHECK_EQ(PageInaccessible, accessibility);
CHECK(!commit);
if (!AdjustAddressSpaceLimit(base::checked_cast<int64_t>(length))) {
// Fall through. Try the allocation, since we may have a reserve.
diff --git a/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h b/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h
index 4aba30c..026d10d 100644
--- a/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h
+++ b/third_party/base/allocator/partition_allocator/page_allocator_internals_posix.h
@@ -128,7 +128,7 @@
void* address,
size_t length,
PageAccessibilityConfiguration accessibility) {
- CHECK(0 == mprotect(address, length, GetAccessFlags(accessibility)));
+ CHECK_EQ(0, mprotect(address, length, GetAccessFlags(accessibility)));
}
void FreePagesInternal(void* address, size_t length) {
diff --git a/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h b/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
index 65e953a..2ba0a25 100644
--- a/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
+++ b/third_party/base/allocator/partition_allocator/page_allocator_internals_win.h
@@ -84,7 +84,7 @@
if (!VirtualFree(address, length, MEM_DECOMMIT)) {
// We check `GetLastError` for `ERROR_SUCCESS` here so that in a crash
// report we get the error number.
- CHECK(static_cast<uint32_t>(ERROR_SUCCESS) == GetLastError());
+ CHECK_EQ(static_cast<uint32_t>(ERROR_SUCCESS), GetLastError());
}
} else {
if (!VirtualAlloc(address, length, MEM_COMMIT,
@@ -94,7 +94,7 @@
OOM_CRASH();
// We check `GetLastError` for `ERROR_SUCCESS` here so that in a crash
// report we get the error number.
- CHECK(ERROR_SUCCESS == error);
+ CHECK_EQ(ERROR_SUCCESS, error);
}
}
}
diff --git a/third_party/base/bits.h b/third_party/base/bits.h
index 3a92b4c..1253683 100644
--- a/third_party/base/bits.h
+++ b/third_party/base/bits.h
@@ -23,9 +23,22 @@
namespace base {
namespace bits {
+// Returns true iff |value| is a power of 2.
+template <typename T,
+ typename = 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;
+}
+
// Round up |size| to a multiple of alignment, which must be a power of two.
inline size_t Align(size_t size, size_t alignment) {
- DCHECK_EQ(alignment & (alignment - 1), 0u);
+ DCHECK(IsPowerOfTwo(alignment));
return (size + alignment - 1) & ~(alignment - 1);
}
diff --git a/third_party/base/logging.h b/third_party/base/logging.h
index dc42016..0081a44 100644
--- a/third_party/base/logging.h
+++ b/third_party/base/logging.h
@@ -116,6 +116,7 @@
#define DCHECK assert
#endif
+#define CHECK_EQ(x, y) CHECK((x) == (y))
#define DCHECK_EQ(x, y) DCHECK((x) == (y))
#define NOTREACHED() DCHECK(false)