diff --git a/tcmalloc/internal/BUILD b/tcmalloc/internal/BUILD index e8af1139e..26239d505 100644 --- a/tcmalloc/internal/BUILD +++ b/tcmalloc/internal/BUILD @@ -1326,6 +1326,7 @@ cc_test( deps = [ ":allocation_guard", ":config", + ":exponential_biased", ":logging", ":numa", ":proc_maps", @@ -1351,6 +1352,7 @@ cc_test( deps = [ ":allocation_guard", ":config", + ":exponential_biased", ":logging", ":numa", ":proc_maps", diff --git a/tcmalloc/internal/exponential_biased.h b/tcmalloc/internal/exponential_biased.h index 416193f05..9a334f78c 100644 --- a/tcmalloc/internal/exponential_biased.h +++ b/tcmalloc/internal/exponential_biased.h @@ -23,14 +23,14 @@ namespace tcmalloc_internal { class ExponentialBiased { public: - static uint64_t NextRandom(uint64_t rnd); - static uint32_t GetRandom(uint64_t rnd); + static constexpr uint64_t NextRandom(uint64_t rnd); + static constexpr uint32_t GetRandom(uint64_t rnd); }; // Returns the next prng value. // pRNG is: aX+b mod c with a = 0x5DEECE66D, b = 0xB, c = 1<<48 // This is the lrand64 generator. -inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { +inline constexpr uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { const uint64_t prng_mult = UINT64_C(0x5DEECE66D); const uint64_t prng_add = 0xB; const uint64_t prng_mod_power = 48; @@ -42,7 +42,9 @@ inline uint64_t ExponentialBiased::NextRandom(uint64_t rnd) { // Extracts higher-quality random bits. // The raw value returned from NextRandom has poor randomness low bits // and is not directly suitable for things like 'if (rnd % 2)'. -inline uint32_t ExponentialBiased::GetRandom(uint64_t rnd) { return rnd >> 16; } +inline constexpr uint32_t ExponentialBiased::GetRandom(uint64_t rnd) { + return rnd >> 16; +} // Convenience wrapper to initialize a seed and return a sequence of // pseudo-random values. Thread-safety: thread safe. diff --git a/tcmalloc/internal/system_allocator.cc b/tcmalloc/internal/system_allocator.cc index 8fa3f70be..3bfdab13a 100644 --- a/tcmalloc/internal/system_allocator.cc +++ b/tcmalloc/internal/system_allocator.cc @@ -42,10 +42,6 @@ #define MAP_ANONYMOUS MAP_ANON #endif -#ifndef MAP_FIXED_NOREPLACE -#define MAP_FIXED_NOREPLACE 0x100000 -#endif - GOOGLE_MALLOC_SECTION_BEGIN namespace tcmalloc::tcmalloc_internal::system_allocator_internal { @@ -81,7 +77,7 @@ int MapFixedNoReplaceFlagAvailable() { void* target = reinterpret_cast(uptr - page_size); void* ptr2 = mmap(target, 2 * page_size, PROT_NONE, - MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + kMapFixedNoReplace | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); const bool rejected = ptr2 == MAP_FAILED; if (!rejected) { if (ptr2 == target) { @@ -95,7 +91,7 @@ int MapFixedNoReplaceFlagAvailable() { } munmap(ptr, page_size); - noreplace_flag = rejected ? MAP_FIXED_NOREPLACE : 0; + noreplace_flag = rejected ? kMapFixedNoReplace : 0; }); return noreplace_flag; diff --git a/tcmalloc/internal/system_allocator.h b/tcmalloc/internal/system_allocator.h index ebd7104a7..0f8217a0d 100644 --- a/tcmalloc/internal/system_allocator.h +++ b/tcmalloc/internal/system_allocator.h @@ -77,6 +77,10 @@ #define PR_SET_VMA_ANON_NAME 0 #endif +#ifndef MAP_FIXED_NOREPLACE +#define MAP_FIXED_NOREPLACE 0x100000 +#endif + GOOGLE_MALLOC_SECTION_BEGIN namespace tcmalloc { namespace tcmalloc_internal { @@ -296,6 +300,8 @@ inline size_t RoundUp(const size_t size, const size_t alignment) { int MapFixedNoReplaceFlagAvailable(); +inline constexpr int kMapFixedNoReplace = MAP_FIXED_NOREPLACE; + } // namespace system_allocator_internal template @@ -804,9 +810,12 @@ uintptr_t SystemAllocator::RandomMmapHint( // tag. alignment = absl::bit_ceil(std::max(alignment, size)); - rnd_ = ExponentialBiased::NextRandom(rnd_); - uintptr_t addr = rnd_ & kAddrMask & ~(alignment - 1) & ~kTagMask; - addr |= static_cast(tag) << kTagShift; + uintptr_t addr; + do { + rnd_ = ExponentialBiased::NextRandom(rnd_); + addr = rnd_ & kAddrMask & ~(alignment - 1) & ~kTagMask; + addr |= static_cast(tag) << kTagShift; + } while (addr == 0); #if defined(ABSL_HAVE_THREAD_SANITIZER) #if defined(__x86_64__) diff --git a/tcmalloc/internal/system_allocator_test.cc b/tcmalloc/internal/system_allocator_test.cc index 00c87f03a..d8e315c1d 100644 --- a/tcmalloc/internal/system_allocator_test.cc +++ b/tcmalloc/internal/system_allocator_test.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include "absl/strings/string_view.h" #include "tcmalloc/internal/allocation_guard.h" #include "tcmalloc/internal/config.h" +#include "tcmalloc/internal/exponential_biased.h" #include "tcmalloc/internal/logging.h" #include "tcmalloc/internal/numa.h" #include "tcmalloc/internal/proc_maps.h"