Bug 891177 - Remove Vector.h's js/TemplateLib.h dependency by introducing mfbt/TemplateLib.h with the necessary bits. r=terrence

--HG--
extra : rebase_source : e84231171d6bd6c1e2de8201b8c9563375723d01
This commit is contained in:
Jeff Walden 2013-07-08 12:42:13 -07:00
parent 4196fa2e0f
commit 5e2dbd029b
20 changed files with 142 additions and 146 deletions

View File

@ -15,10 +15,10 @@
#include "mozilla/Move.h"
#include "mozilla/PodOperations.h"
#include "mozilla/ReentrancyGuard.h"
#include "mozilla/TemplateLib.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Util.h"
#include "js/TemplateLib.h"
#include "js/Utility.h"
namespace js {
@ -540,7 +540,7 @@ struct DefaultHasher
// Specialize hashing policy for pointer types. It assumes that the type is
// at least word-aligned. For types with smaller size use PointerHasher.
template <class T>
struct DefaultHasher<T *> : PointerHasher<T *, tl::FloorLog2<sizeof(void *)>::result>
struct DefaultHasher<T *> : PointerHasher<T *, mozilla::tl::FloorLog2<sizeof(void *)>::value>
{};
// For doubles, we can xor the two uint32s.
@ -890,7 +890,7 @@ class HashTable : private AllocPolicy
static const unsigned sMinCapacity = 1 << sMinCapacityLog2;
static const unsigned sMaxInit = JS_BIT(23);
static const unsigned sMaxCapacity = JS_BIT(24);
static const unsigned sHashBits = tl::BitSize<HashNumber>::result;
static const unsigned sHashBits = mozilla::tl::BitSize<HashNumber>::value;
static const uint8_t sMinAlphaFrac = 64; // (0x100 * .25)
static const uint8_t sMaxAlphaFrac = 192; // (0x100 * .75)
static const uint8_t sInvMaxAlpha = 171; // (ceil(0x100 / .75) >> 1)

View File

@ -11,7 +11,6 @@
#include "mozilla/TypeTraits.h"
#include "js/Utility.h"
#include "js/TemplateLib.h"
#include "jspubtd.h"

View File

@ -1,112 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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 js_TemplateLib_h
#define js_TemplateLib_h
#include "jstypes.h"
/*
* Library of reusable template meta-functions (that is, functions on types and
* compile-time values). Meta-functions are placed inside the 'tl' namespace to
* avoid conflict with non-meta functions that logically have the same name
* (e.g., js::tl::Min vs. js::Min).
*/
namespace js {
namespace tl {
/* Compute min/max/clamp. */
template <size_t i, size_t j> struct Min {
static const size_t result = i < j ? i : j;
};
template <size_t i, size_t j> struct Max {
static const size_t result = i > j ? i : j;
};
template <size_t i, size_t min, size_t max> struct Clamp {
static const size_t result = i < min ? min : (i > max ? max : i);
};
/* Compute x^y. */
template <size_t x, size_t y> struct Pow {
static const size_t result = x * Pow<x, y - 1>::result;
};
template <size_t x> struct Pow<x,0> {
static const size_t result = 1;
};
/* Compute floor(log2(i)). */
template <size_t i> struct FloorLog2 {
static const size_t result = 1 + FloorLog2<i / 2>::result;
};
template <> struct FloorLog2<0> { /* Error */ };
template <> struct FloorLog2<1> { static const size_t result = 0; };
/* Compute ceiling(log2(i)). */
template <size_t i> struct CeilingLog2 {
static const size_t result = FloorLog2<2 * i - 1>::result;
};
/* Round up to the nearest power of 2. */
template <size_t i> struct RoundUpPow2 {
static const size_t result = size_t(1) << CeilingLog2<i>::result;
};
template <> struct RoundUpPow2<0> {
static const size_t result = 1;
};
/* Compute the number of bits in the given unsigned type. */
template <class T> struct BitSize {
static const size_t result = sizeof(T) * JS_BITS_PER_BYTE;
};
/*
* Produce an N-bit mask, where N <= BitSize<size_t>::result. Handle the
* language-undefined edge case when N = BitSize<size_t>::result.
*/
template <size_t N> struct NBitMask {
// Assert the precondition. On success this evaluates to 0. Otherwise it
// triggers divide-by-zero at compile time: a guaranteed compile error in
// C++11, and usually one in C++98. Add this value to |result| to assure
// its computation.
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::result);
static const size_t result = (size_t(1) << N) - 1 + checkPrecondition;
};
template <> struct NBitMask<BitSize<size_t>::result> {
static const size_t result = size_t(-1);
};
/*
* For the unsigned integral type size_t, compute a mask M for N such that
* for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
*/
template <size_t N> struct MulOverflowMask {
static const size_t result =
~NBitMask<BitSize<size_t>::result - CeilingLog2<N>::result>::result;
};
template <> struct MulOverflowMask<0> { /* Error */ };
template <> struct MulOverflowMask<1> { static const size_t result = 0; };
/*
* Generate a mask for T such that if (X & sUnsafeRangeSizeMask), an X-sized
* array of T's is big enough to cause a ptrdiff_t overflow when subtracting
* a pointer to the end of the array from the beginning.
*/
template <class T> struct UnsafeRangeSizeMask {
/*
* The '2' factor means the top bit is clear, sizeof(T) converts from
* units of elements to bytes.
*/
static const size_t result = MulOverflowMask<2 * sizeof(T)>::result;
};
template <bool cond, typename T, T v1, T v2> struct If { static const T result = v1; };
template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T result = v2; };
} /* namespace tl */
} /* namespace js */
#endif /* js_TemplateLib_h */

View File

@ -12,6 +12,7 @@
#include "mozilla/Compiler.h"
#include "mozilla/Move.h"
#include "mozilla/Scoped.h"
#include "mozilla/TemplateLib.h"
#include <stdlib.h>
#include <string.h>
@ -23,8 +24,6 @@
#include "jstypes.h"
#include "js/TemplateLib.h"
/* The public JS engine namespace. */
namespace JS {}
@ -354,7 +353,7 @@ template <class T>
static JS_ALWAYS_INLINE T *
js_pod_malloc(size_t numElems)
{
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return NULL;
return (T *)js_malloc(numElems * sizeof(T));
}
@ -363,7 +362,7 @@ template <class T>
static JS_ALWAYS_INLINE T *
js_pod_calloc(size_t numElems)
{
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result)
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
return NULL;
return (T *)js_calloc(numElems * sizeof(T));
}

View File

@ -13,9 +13,9 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/ReentrancyGuard.h"
#include "mozilla/TemplateLib.h"
#include "mozilla/TypeTraits.h"
#include "js/TemplateLib.h"
#include "mozilla/Util.h"
/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */
#ifdef _MSC_VER
@ -227,19 +227,19 @@ class Vector : private AllocPolicy
*/
template <int M, int Dummy>
struct ElemSize {
static const size_t result = sizeof(T);
static const size_t value = sizeof(T);
};
template <int Dummy>
struct ElemSize<0, Dummy> {
static const size_t result = 1;
static const size_t value = 1;
};
static const size_t sInlineCapacity =
tl::Min<N, sMaxInlineBytes / ElemSize<N, 0>::result>::result;
mozilla::tl::Min<N, sMaxInlineBytes / ElemSize<N, 0>::value>::value;
/* Calculate inline buffer size; avoid 0-sized array. */
static const size_t sInlineBytes =
tl::Max<1, sInlineCapacity * ElemSize<N, 0>::result>::result;
mozilla::tl::Max<1, sInlineCapacity * ElemSize<N, 0>::value>::value;
/* member data */
@ -648,7 +648,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
if (incr == 1) {
if (usingInlineStorage()) {
/* This case occurs in ~70--80% of the calls to this function. */
size_t newSize = tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::result;
size_t newSize = mozilla::tl::RoundUpPow2<(sInlineCapacity + 1) * sizeof(T)>::value;
newCap = newSize / sizeof(T);
goto convert;
}
@ -667,7 +667,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
* It also ensures that the ((char *)end() - (char *)begin()) does not
* overflow ptrdiff_t (see Bug 510319).
*/
if (mLength & tl::MulOverflowMask<4 * sizeof(T)>::result) {
if (mLength & mozilla::tl::MulOverflowMask<4 * sizeof(T)>::value) {
this->reportAllocOverflow();
return false;
}
@ -687,7 +687,7 @@ Vector<T,N,AP>::growStorageBy(size_t incr)
/* Did mLength+incr overflow? Will newCap*sizeof(T) overflow? */
if (newMinCap < mLength ||
newMinCap & tl::MulOverflowMask<2 * sizeof(T)>::result)
newMinCap & mozilla::tl::MulOverflowMask<2 * sizeof(T)>::value)
{
this->reportAllocOverflow();
return false;

View File

@ -7,9 +7,9 @@
#ifndef ds_BitArray_h
#define ds_BitArray_h
#include "jstypes.h"
#include "mozilla/TemplateLib.h"
#include "js/TemplateLib.h"
#include "jstypes.h"
namespace js {
@ -54,7 +54,7 @@ class BitArray {
private:
inline void getMarkWordAndMask(size_t offset,
uintptr_t *indexp, uintptr_t *maskp) const {
*indexp = offset >> tl::FloorLog2<JS_BITS_PER_WORD>::result;
*indexp = offset >> mozilla::tl::FloorLog2<JS_BITS_PER_WORD>::value;
*maskp = uintptr_t(1) << (offset & (JS_BITS_PER_WORD - 1));
}
};

View File

@ -11,6 +11,7 @@
using namespace js;
using mozilla::RoundUpPow2;
using mozilla::tl::BitSize;
namespace js {
namespace detail {
@ -91,7 +92,7 @@ LifoAlloc::getOrCreateChunk(size_t n)
// Guard for overflow.
if (allocSizeWithHeader < n ||
(allocSizeWithHeader & (size_t(1) << (tl::BitSize<size_t>::result - 1)))) {
(allocSizeWithHeader & (size_t(1) << (BitSize<size_t>::value - 1)))) {
return NULL;
}

View File

@ -12,6 +12,7 @@
#include "mozilla/MemoryChecking.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
#include "mozilla/TemplateLib.h"
#include "mozilla/TypeTraits.h"
// This data structure supports stacky LIFO allocation (mark/release and
@ -31,8 +32,8 @@ JS_ALWAYS_INLINE
char *
AlignPtr(void *orig)
{
MOZ_STATIC_ASSERT(tl::FloorLog2<LIFO_ALLOC_ALIGN>::result ==
tl::CeilingLog2<LIFO_ALLOC_ALIGN>::result,
MOZ_STATIC_ASSERT(mozilla::tl::FloorLog2<LIFO_ALLOC_ALIGN>::value ==
mozilla::tl::CeilingLog2<LIFO_ALLOC_ALIGN>::value,
"LIFO_ALLOC_ALIGN must be a power of two");
char *result = (char *) ((uintptr_t(orig) + (LIFO_ALLOC_ALIGN - 1)) & (~LIFO_ALLOC_ALIGN + 1));

View File

@ -12,7 +12,6 @@
#include "gc/Barrier.h"
#include "gc/Nursery.h"
#include "js/TemplateLib.h"
#include "ion/IonCode.h"
extern "C" {

View File

@ -26,7 +26,6 @@
#include "js/HeapAPI.h"
#include "js/MemoryMetrics.h"
#include "js/PropertyKey.h"
#include "js/TemplateLib.h"
#include "js/Utility.h"
#include "js/Value.h"
#include "js/Vector.h"

View File

@ -13,7 +13,6 @@
#include "jslock.h"
#include "js/RootingAPI.h"
#include "js/TemplateLib.h"
#include "vm/Shape.h"
#include "vm/ForkJoin.h"

View File

@ -13,6 +13,7 @@
#include "mozilla/MathAlgorithms.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TemplateLib.h"
#include "mozilla/Util.h"
#include "jstypes.h"
@ -2070,7 +2071,7 @@ JSObject::TradeGuts(JSContext *cx, JSObject *a, JSObject *b, TradeGutsReserved &
* whether they have dynamically allocated slots and instead just copy
* them over wholesale.
*/
char tmp[tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::result];
char tmp[mozilla::tl::Max<sizeof(JSFunction), sizeof(JSObject_Slots16)>::value];
JS_ASSERT(size <= sizeof(tmp));
js_memcpy(tmp, a, size);

View File

@ -73,7 +73,6 @@ EXPORTS.js += [
'../public/PropertyKey.h',
'../public/RequiredDefines.h',
'../public/RootingAPI.h',
'../public/TemplateLib.h',
'../public/Utility.h',
'../public/Value.h',
'../public/Vector.h',

View File

@ -15,7 +15,6 @@
#include "gc/Heap.h"
#include "gc/Marking.h"
#include "js/TemplateLib.h"
#include "vm/ObjectImpl.h"
#include "gc/Barrier-inl.h"

View File

@ -17,7 +17,6 @@
#include "gc/Barrier.h"
#include "gc/Marking.h"
#include "js/TemplateLib.h"
#include "vm/MatchPairs.h"
#include "vm/Runtime.h"
#include "yarr/MatchResult.h"

View File

@ -10,6 +10,7 @@
#include "mozilla/LinkedList.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/PodOperations.h"
#include "mozilla/TemplateLib.h"
#include <string.h>
#include <setjmp.h>
@ -612,7 +613,7 @@ struct MallocProvider
template <class T>
T *pod_malloc(size_t numElems) {
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result) {
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
Client *client = static_cast<Client *>(this);
client->reportAllocationOverflow();
return NULL;
@ -622,7 +623,7 @@ struct MallocProvider
template <class T>
T *pod_calloc(size_t numElems, JSCompartment *comp = NULL, JSContext *cx = NULL) {
if (numElems & js::tl::MulOverflowMask<sizeof(T)>::result) {
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
Client *client = static_cast<Client *>(this);
client->reportAllocationOverflow();
return NULL;

View File

@ -10,6 +10,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TemplateLib.h"
#include "jspropertytree.h"
#include "jstypes.h"
@ -108,7 +109,7 @@ static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2;
* minimize footprint.
*/
struct ShapeTable {
static const uint32_t HASH_BITS = tl::BitSize<HashNumber>::result;
static const uint32_t HASH_BITS = mozilla::tl::BitSize<HashNumber>::value;
static const uint32_t MIN_ENTRIES = 7;
static const uint32_t MIN_SIZE_LOG2 = 4;
static const uint32_t MIN_SIZE = JS_BIT(MIN_SIZE_LOG2);

View File

@ -20,7 +20,6 @@
#include "assembler/wtf/Platform.h"
#include "assembler/jit/ExecutableAllocator.h"
#include "yarr/CheckedArithmetic.h"
#include "js/TemplateLib.h"
namespace JSC { namespace Yarr {

111
mfbt/TemplateLib.h Normal file
View File

@ -0,0 +1,111 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* 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/. */
/*
* Reusable template meta-functions on types and compile-time values. Meta-
* functions are placed inside the 'tl' namespace to avoid conflict with non-
* meta functions of the same name (e.g., mozilla::tl::FloorLog2 vs.
* mozilla::FloorLog2).
*
* When constexpr support becomes universal, we should probably use that instead
* of some of these templates, for simplicity.
*/
#ifndef mozilla_TemplateLib_h
#define mozilla_TemplateLib_h
#include <limits.h>
#include <stddef.h>
namespace mozilla {
namespace tl {
/** Compute min/max. */
template<size_t I, size_t J>
struct Min
{
static const size_t value = I < J ? I : J;
};
template<size_t I, size_t J>
struct Max
{
static const size_t value = I > J ? I : J;
};
/** Compute floor(log2(i)). */
template<size_t I>
struct FloorLog2
{
static const size_t value = 1 + FloorLog2<I / 2>::value;
};
template<> struct FloorLog2<0> { /* Error */ };
template<> struct FloorLog2<1> { static const size_t value = 0; };
/** Compute ceiling(log2(i)). */
template<size_t I>
struct CeilingLog2
{
static const size_t value = FloorLog2<2 * I - 1>::value;
};
/** Round up to the nearest power of 2. */
template<size_t I>
struct RoundUpPow2
{
static const size_t value = size_t(1) << CeilingLog2<I>::value;
};
template<>
struct RoundUpPow2<0>
{
static const size_t value = 1;
};
/** Compute the number of bits in the given unsigned type. */
template<typename T>
struct BitSize
{
static const size_t value = sizeof(T) * CHAR_BIT;
};
/**
* Produce an N-bit mask, where N <= BitSize<size_t>::value. Handle the
* language-undefined edge case when N = BitSize<size_t>::value.
*/
template<size_t N>
struct NBitMask
{
// Assert the precondition. On success this evaluates to 0. Otherwise it
// triggers divide-by-zero at compile time: a guaranteed compile error in
// C++11, and usually one in C++98. Add this value to |value| to assure
// its computation.
static const size_t checkPrecondition = 0 / size_t(N < BitSize<size_t>::value);
static const size_t value = (size_t(1) << N) - 1 + checkPrecondition;
};
template<>
struct NBitMask<BitSize<size_t>::value>
{
static const size_t value = size_t(-1);
};
/**
* For the unsigned integral type size_t, compute a mask M for N such that
* for all X, !(X & M) implies X * N will not overflow (w.r.t size_t)
*/
template<size_t N>
struct MulOverflowMask
{
static const size_t value =
~NBitMask<BitSize<size_t>::value - CeilingLog2<N>::value>::value;
};
template<> struct MulOverflowMask<0> { /* Error */ };
template<> struct MulOverflowMask<1> { static const size_t value = 0; };
} // namespace tl
} // namespace mozilla
#endif /* mozilla_TemplateLib_h */

View File

@ -45,6 +45,7 @@ EXPORTS_mozilla += \
SHA1.h \
SplayTree.h \
StandardInteger.h \
TemplateLib.h \
ThreadLocal.h \
TypedEnum.h \
Types.h \