Bug 1413096 - Remove SIZEOF_PTR and SIZEOF_PTR_2POW. r?njn draft
authorMike Hommey <mh+mozilla@glandium.org>
Mon, 30 Oct 2017 11:43:10 +0900
changeset 689165 2dd706608340e8825eeb71b356298cd16d43c828
parent 689164 0b717b3bdb043c5d68d67e0f5d35baf47d695b1c
child 738246 574a3699d87ecf304b1fc1fa285832b5bd8a4c80
push id86942
push userbmo:mh+mozilla@glandium.org
push dateTue, 31 Oct 2017 06:24:30 +0000
reviewersnjn
bugs1413096
milestone58.0a1
Bug 1413096 - Remove SIZEOF_PTR and SIZEOF_PTR_2POW. r?njn
memory/build/mozjemalloc.cpp
memory/build/rb.h
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -110,16 +110,17 @@
 #include "mozilla/Atomics.h"
 #include "mozilla/Alignment.h"
 #include "mozilla/CheckedInt.h"
 #include "mozilla/DoublyLinkedList.h"
 #include "mozilla/GuardObjects.h"
 #include "mozilla/Likely.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Sprintf.h"
+#include "mozilla/TemplateLib.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 
 // On Linux, we use madvise(MADV_DONTNEED) to release memory back to the
 // operating system.  If we release 1MB of live pages with MADV_DONTNEED, our
 // RSS will decrease by 1MB (almost) immediately.
 //
 // On Mac, we use madvise(MADV_FREE).  Unlike MADV_DONTNEED on Linux, MADV_FREE
@@ -149,16 +150,25 @@
 #include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
 #include <algorithm>
 
 using namespace mozilla;
 
+// Helper for log2 of powers of 2 at compile time.
+template<size_t N>
+struct Log2 : mozilla::tl::CeilingLog2<N>
+{
+  using mozilla::tl::CeilingLog2<N>::value;
+  static_assert(1ULL << value == N, "Number is not a power of 2");
+};
+#define LOG2(N) Log2<N>::value
+
 #ifdef XP_WIN
 
 // Some defines from the CRT internal headers that we need here.
 #define _CRT_SPINCOUNT 5000
 #include <io.h>
 #include <windows.h>
 #include <intrin.h>
 
@@ -281,23 +291,16 @@ static inline void*
 #endif
 #endif
 
 // Size of stack-allocated buffer passed to strerror_r().
 #define STRERROR_BUF 64
 
 // Minimum alignment of non-tiny allocations is 2^QUANTUM_2POW_MIN bytes.
 #define QUANTUM_2POW_MIN 4
-#if defined(_WIN64) || defined(__LP64__)
-#define SIZEOF_PTR_2POW 3
-#else
-#define SIZEOF_PTR_2POW 2
-#endif
-
-#define SIZEOF_PTR (1U << SIZEOF_PTR_2POW)
 
 #include "rb.h"
 
 // sizeof(int) == (1U << SIZEOF_INT_2POW).
 #ifndef SIZEOF_INT_2POW
 #define SIZEOF_INT_2POW 2
 #endif
 
@@ -628,22 +631,22 @@ struct ExtentTreeBoundsTrait : public Ex
 // With e.g. sizeof(void*)=4, Bits=16 and kBitsPerLevel=8, an address is split
 // like the following:
 // 0x12345678 -> mRoot[0x12][0x34]
 template<size_t Bits>
 class AddressRadixTree
 {
 // Size of each radix tree node (as a power of 2).
 // This impacts tree depth.
-#if (SIZEOF_PTR == 4)
-  static const size_t kNodeSize2Pow = 14;
+#ifdef HAVE_64BIT_BUILD
+  static const size_t kNodeSize2Pow = CACHELINE_2POW;
 #else
-  static const size_t kNodeSize2Pow = CACHELINE_2POW;
+  static const size_t kNodeSize2Pow = 14;
 #endif
-  static const size_t kBitsPerLevel = kNodeSize2Pow - SIZEOF_PTR_2POW;
+  static const size_t kBitsPerLevel = kNodeSize2Pow - LOG2(sizeof(void*));
   static const size_t kBitsAtLevel1 =
     (Bits % kBitsPerLevel) ? Bits % kBitsPerLevel : kBitsPerLevel;
   static const size_t kHeight = (Bits + kBitsPerLevel - 1) / kBitsPerLevel;
   static_assert(kBitsAtLevel1 + (kHeight - 1) * kBitsPerLevel == Bits,
                 "AddressRadixTree parameters don't work out");
 
   Mutex mLock;
   void** mRoot;
@@ -1129,17 +1132,17 @@ public:
 
   static Collection sCollection;
 };
 
 arena_t::Collection arena_t::sCollection;
 
 // ******
 // Chunks.
-static AddressRadixTree<(SIZEOF_PTR << 3) - CHUNK_2POW_DEFAULT> gChunkRTree;
+static AddressRadixTree<(sizeof(void*) << 3) - CHUNK_2POW_DEFAULT> gChunkRTree;
 
 // Protects chunk-related data structures.
 static Mutex chunks_mtx;
 
 // Trees of chunks that were previously allocated (trees differ only in node
 // ordering).  These are used when allocating chunks, in an attempt to re-use
 // address space.  Depending on function, different tree orderings are needed,
 // which is why there are two trees with the same contents.
@@ -1723,33 +1726,33 @@ AddressRadixTree<Bits>::GetSlot(void* aK
   uintptr_t subkey;
   unsigned i, lshift, height, bits;
   void** node;
   void** child;
 
   for (i = lshift = 0, height = kHeight, node = mRoot; i < height - 1;
        i++, lshift += bits, node = child) {
     bits = i ? kBitsPerLevel : kBitsAtLevel1;
-    subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
+    subkey = (key << lshift) >> ((sizeof(void*) << 3) - bits);
     child = (void**)node[subkey];
     if (!child && aCreate) {
       child = (void**)base_calloc(1 << kBitsPerLevel, sizeof(void*));
       if (child) {
         node[subkey] = child;
       }
     }
     if (!child) {
       return nullptr;
     }
   }
 
   // node is a leaf, so it contains values rather than node
   // pointers.
   bits = i ? kBitsPerLevel : kBitsAtLevel1;
-  subkey = (key << lshift) >> ((SIZEOF_PTR << 3) - bits);
+  subkey = (key << lshift) >> ((sizeof(void*) << 3) - bits);
   return &node[subkey];
 }
 
 template<size_t Bits>
 void*
 AddressRadixTree<Bits>::Get(void* aKey)
 {
   void* ret = nullptr;
--- a/memory/build/rb.h
+++ b/memory/build/rb.h
@@ -33,24 +33,16 @@
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  *
  * C++ template implementation of left-leaning red-black trees.
  *
- * Usage:
- *
- *   #define SIZEOF_PTR ...
- *   #define SIZEOF_PTR_2POW ...
- *
- *   #include <rb.h>
- *   ...
- *
  * All operations are done non-recursively.  Parent pointers are not used, and
  * color bits are stored in the least significant bit of right-child pointers,
  * thus making node linkage as compact as is possible for red-black trees.
  *
  * The RedBlackTree template expects two type arguments: the type of the nodes,
  * containing a RedBlackTreeNode, and a trait providing two methods:
  *  - a GetTreeNode method that returns a reference to the RedBlackTreeNode
  *    corresponding to a given node with the following signature:
@@ -71,16 +63,17 @@
  * that treat the first argument specially.
  *
  ******************************************************************************/
 
 #ifndef RB_H_
 #define RB_H_
 
 #include "mozilla/Alignment.h"
+#include "mozilla/TemplateLib.h"
 
 enum NodeColor
 {
   Black = 0,
   Red = 1,
 };
 
 /* Node structure. */
@@ -701,30 +694,31 @@ private:
    * iteration.
    */
 
   /*
    * Size the path arrays such that they are always large enough, even if a
    * tree consumes all of memory.  Since each node must contain a minimum of
    * two pointers, there can never be more nodes than:
    *
-   *   1 << ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))
+   *   1 << ((sizeof(void*)<<3) - (log2(sizeof(void*))+1))
    *
    * Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth
    * is:
    *
-   *   (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
+   *   (3 * ((sizeof(void*)<<3) - (log2(sizeof(void*))+1)))
    *
    * This works out to a maximum depth of 87 and 180 for 32- and 64-bit
    * systems, respectively (approximately 348 and 1440 bytes, respectively).
    */
 public:
   class Iterator
   {
-    TreeNode* mPath[3 * ((SIZEOF_PTR << 3) - (SIZEOF_PTR_2POW + 1))];
+    TreeNode* mPath[3 * ((sizeof(void*) << 3) -
+                         (mozilla::tl::CeilingLog2<sizeof(void*)>::value + 1))];
     unsigned mDepth;
 
   public:
     explicit Iterator(RedBlackTree<T, Trait>* aTree)
       : mDepth(0)
     {
       /* Initialize the path to contain the left spine. */
       if (aTree->mRoot) {