Bug 1413096 - Remove SIZEOF_PTR and SIZEOF_PTR_2POW. r?njn
new file mode 100644
--- /dev/null
+++ b/memory/build/Utils.h
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef Utils_h
+#define Utils_h
+
+#include "mozilla/TemplateLib.h"
+
+// 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
+
+#endif
--- a/memory/build/mozjemalloc.cpp
+++ b/memory/build/mozjemalloc.cpp
@@ -111,16 +111,17 @@
#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/UniquePtr.h"
#include "mozilla/Unused.h"
+#include "Utils.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
// on Mac doesn't cause the OS to release the specified pages immediately; the
// OS keeps them in our process until the machine comes under memory pressure.
@@ -280,23 +281,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
@@ -624,22 +618,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;
@@ -1036,17 +1030,17 @@ struct ArenaTreeTrait
MOZ_ASSERT(aNode);
MOZ_ASSERT(aOther);
return (aNode->mId > aOther->mId) - (aNode->mId < aOther->mId);
}
};
// ******
// 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.
@@ -1643,33 +1637,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:
@@ -70,16 +62,18 @@
* comparison function, which makes it possible to write comparison functions
* that treat the first argument specially.
*
******************************************************************************/
#ifndef RB_H_
#define RB_H_
+#include "Utils.h"
+
enum NodeColor
{
Black = 0,
Red = 1,
};
/* Node structure. */
template <typename T>
@@ -699,30 +693,30 @@ 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) - (LOG2(sizeof(void*)) + 1))];
unsigned mDepth;
public:
explicit Iterator(RedBlackTree<T, Trait>* aTree)
: mDepth(0)
{
/* Initialize the path to contain the left spine. */
if (aTree->mRoot) {