bmalloc: stress_aligned test fails if you increase smallMax
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2016 20:59:51 +0000 (20:59 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Apr 2016 20:59:51 +0000 (20:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156414

Reviewed by Oliver Hunt.

When size exceeds alignment and is a multiple of alignment and is not
a power of two, such as 24kB with 8kB alignment, the small allocator
did not always guarantee alignment. Let's fix that.

* bmalloc/Algorithm.h:
(bmalloc::divideRoundingUp): Math is hard.

* bmalloc/Allocator.cpp:
(bmalloc::Allocator::allocate): Align to the page size unconditionally.
Even if the page size is not a power of two, it might be a multiple of
a power of two, and we want alignment to that smaller power of two to
be guaranteed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@199246 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/bmalloc/ChangeLog
Source/bmalloc/bmalloc/Algorithm.h
Source/bmalloc/bmalloc/VMHeap.cpp

index 0d5bcb3..fde19bd 100644 (file)
@@ -1,3 +1,23 @@
+2016-04-08  Geoffrey Garen  <ggaren@apple.com>
+
+        bmalloc: stress_aligned test fails if you increase smallMax
+        https://bugs.webkit.org/show_bug.cgi?id=156414
+
+        Reviewed by Oliver Hunt.
+
+        When size exceeds alignment and is a multiple of alignment and is not
+        a power of two, such as 24kB with 8kB alignment, the small allocator
+        did not always guarantee alignment. Let's fix that.
+
+        * bmalloc/Algorithm.h:
+        (bmalloc::divideRoundingUp): Math is hard.
+
+        * bmalloc/Allocator.cpp:
+        (bmalloc::Allocator::allocate): Align to the page size unconditionally.
+        Even if the page size is not a power of two, it might be a multiple of
+        a power of two, and we want alignment to that smaller power of two to
+        be guaranteed.
+
 2016-04-06  Geoffrey Garen  <ggaren@apple.com>
 
         bmalloc: handle aligned allocations on the fast path
index 277a1b0..c23b94a 100644 (file)
@@ -87,7 +87,7 @@ template<size_t divisor, typename T> inline constexpr T roundDownToMultipleOf(T
     return roundDownToMultipleOf(divisor, x);
 }
 
-template<typename T> void divideRoundingUp(T numerator, T denominator, T& quotient, T& remainder)
+template<typename T> inline void divideRoundingUp(T numerator, T denominator, T& quotient, T& remainder)
 {
     // We expect the compiler to emit a single divide instruction to extract both the quotient and the remainder.
     quotient = numerator / denominator;
@@ -96,6 +96,11 @@ template<typename T> void divideRoundingUp(T numerator, T denominator, T& quotie
         quotient += 1;
 }
 
+template<typename T> inline T divideRoundingUp(T numerator, T denominator)
+{
+    return (numerator + denominator - 1) / denominator;
+}
+
 // Version of sizeof that returns 0 for empty classes.
 
 template<typename T> inline constexpr size_t sizeOf()
index 8a3ca31..801e04f 100644 (file)
@@ -87,12 +87,9 @@ void VMHeap::allocateSmallChunk(std::lock_guard<StaticMutex>& lock, size_t pageC
     size_t pageSize = bmalloc::pageSize(pageClass);
     size_t smallPageCount = pageSize / smallPageSize;
 
-    // If our page size is a power of two, we align to it in order to guarantee
-    // that we can service aligned allocation requests at the same power of two.
-    size_t alignment = vmPageSizePhysical();
-    if (isPowerOfTwo(pageSize))
-        alignment = pageSize;
-    size_t metadataSize = roundUpToMultipleOf(alignment, sizeof(Chunk));
+    // We align to our page size in order to guarantee that we can service
+    // aligned allocation requests at equal and smaller powers of two.
+    size_t metadataSize = divideRoundingUp(sizeof(Chunk), pageSize) * pageSize;
 
     Object begin(chunk, metadataSize);
     Object end(chunk, chunkSize);