Bug 1406303 - Simplify the calculation of AddressRadixTree's height. r?njn draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 06 Oct 2017 11:32:27 +0900
changeset 677069 d37d48915b9d4e8feca3c925c54f2f013f27f0e8
parent 677068 87ddfd91df91cc1ba09becd442b2ad7e8dbb603e
child 677070 34d180d496601d830ca54a9735671a08cd21ff4a
push id83679
push userbmo:mh+mozilla@glandium.org
push dateMon, 09 Oct 2017 23:14:34 +0000
reviewersnjn
bugs1406303
milestone58.0a1
Bug 1406303 - Simplify the calculation of AddressRadixTree's height. r?njn The tree height was defined as: height = aBits / bits_per_level; if (height * bits_per_level != aBits) { height++; } What's wanted here is a height that covers all the bits, where the first level might cover less than bits_per_level. So aBits / bits_per_level gets us the height covered by levels with exactly bits_per_level bits. The tree height is one more when there are remaining bits. Put differently, we can write aBits as: aBits = bits_per_level * x + y with y < bits_per_level. We have: aBits / bits_per_level = x. height = x when y = 0, and x + 1 when y > 0. We're looking for a number z such that height = (aBits + z) / bits_per_level. Or: height = (bits_per_level * x + y + z) / bits_per_level. = x + (y + z) / bits_per_level. So we're looking for a z such that (y + z) / bits_per_level = 0 when y = 0 = 1 when y > 0 The properties of the integer division are such that the above means: 0 <= y + z < bits_per_level when y = 0 bits_per_level <= y + z < 2 * bits_per_level when y > 0 Which gives us: 0 <= z < bits_per_level bits_per_level - y <= z < 2 * bits_per_level - y when y > 0 y being < bit_per_level per the constraint further above, 2 * bits_per_level - y > bits_per_level. So all in all, we want a z such that bits_per_level - y <= z < bits_per_level with 0 < y < bits_per_level The largest value where this is true is z = bits_per_level - 1. In summary, height = (aBits + bits_per_level - 1) / bits_per_level is the same as the height as originally defined. With that formula, it's self evident that height * bits_per_level is always >= aBits, so we remove the assertion.
memory/build/mozjemalloc.cpp
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -1735,21 +1735,17 @@ pages_copy(void *dest, const void *src, 
 
 AddressRadixTree*
 AddressRadixTree::Create(unsigned aBits)
 {
   AddressRadixTree* ret;
   unsigned bits_per_level, height, i;
 
   bits_per_level = AddressRadixTree::kNodeSize2Pow - SIZEOF_PTR_2POW;
-  height = aBits / bits_per_level;
-  if (height * bits_per_level != aBits) {
-    height++;
-  }
-  MOZ_DIAGNOSTIC_ASSERT(height * bits_per_level >= aBits);
+  height = (aBits + bits_per_level - 1) / bits_per_level;
 
   ret = (AddressRadixTree*)base_calloc(1, sizeof(AddressRadixTree) +
       (sizeof(unsigned) * (height - 1)));
   if (!ret) {
     return nullptr;
   }
 
   malloc_spin_init(&ret->mLock);